diff --git a/BakeGenuis-AI/.github/workflows/issue-create-automate-message.yml b/BakeGenuis-AI/.github/workflows/issue-create-automate-message.yml new file mode 100644 index 00000000..961e64da --- /dev/null +++ b/BakeGenuis-AI/.github/workflows/issue-create-automate-message.yml @@ -0,0 +1,28 @@ +name: Auto Comment on Issue + +on: + issues: + types: [opened] + +permissions: + issues: write + +jobs: + comment: + runs-on: ubuntu-latest + steps: + - name: Add Comment to Issue + uses: actions/github-script@v6 + with: + script: | + const issueNumber = context.issue.number; + const commentBody = `### Thank you for raising this issue!\n We'll review it as soon as possible. We truly appreciate your contributions! โœจ\n\n> Meanwhile make sure you've visited the README.md, CONTRIBUTING.md, and CODE_OF_CONDUCT.md before creating a PR for this. Also, please do NOT create a PR until this issue has been assigned to you. ๐Ÿ˜Š`; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + body: commentBody + }); + + console.log('Comment added successfully.'); \ No newline at end of file diff --git a/BakeGenuis-AI/.github/workflows/pr-create-automate-message.yml b/BakeGenuis-AI/.github/workflows/pr-create-automate-message.yml new file mode 100644 index 00000000..8c90343e --- /dev/null +++ b/BakeGenuis-AI/.github/workflows/pr-create-automate-message.yml @@ -0,0 +1,30 @@ +name: Auto Comment on PR + +on: + pull_request_target: + types: [opened] + +permissions: + issues: write + pull-requests: write + +jobs: + comment: + runs-on: ubuntu-latest + steps: + - name: Comment on PR + uses: actions/github-script@v6 + with: + script: | + const prNumber = context.issue.number; + + const commentBody = `### Thanks for creating a PR for your Issue! โ˜บ๏ธ\n\nWe'll review it as soon as possible.\nIn the meantime, please double-check the **file changes** and ensure that **all commits** are accurate.\n\nIf there are any **unresolved review comments**, feel free to resolve them. ๐Ÿ™Œ๐Ÿผ`; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: commentBody + }); + + console.log('Comment added successfully.'); \ No newline at end of file diff --git a/BakeGenuis-AI/.gitignore b/BakeGenuis-AI/.gitignore new file mode 100644 index 00000000..f1be1431 --- /dev/null +++ b/BakeGenuis-AI/.gitignore @@ -0,0 +1,49 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Firebase / API config (to avoid leaking keys) +firebase.js +js/google_config.js + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ + +# Build outputs +dist/ +build/ diff --git a/BakeGenuis-AI/CODE_CLEANUP_SUMMARY.md b/BakeGenuis-AI/CODE_CLEANUP_SUMMARY.md new file mode 100644 index 00000000..8731e95f --- /dev/null +++ b/BakeGenuis-AI/CODE_CLEANUP_SUMMARY.md @@ -0,0 +1,85 @@ +# BakeGenius.AI Code Cleanup Summary + +## ๐Ÿงน Code Quality Improvements Made + +### 1. **Fixed HTML Issues** +- โœ… Removed duplicate CSS link in `html/about.html` (toggle.css was included twice) +- โœ… Cleaned up HTML structure and removed redundant elements + +### 2. **Improved JavaScript Code Quality** +- โœ… Removed development `console.log()` statements from production code +- โœ… Improved error handling with graceful fallbacks +- โœ… Fixed duplicate function calls in `js/about.js` +- โœ… Added proper error handling without exposing internal errors +- โœ… Created centralized configuration in `js/config.js` + +### 3. **Security Improvements** +- โœ… Removed hardcoded API keys from client-side code +- โœ… Added security comments about server-side API implementation +- โœ… Replaced placeholder API keys with `null` values and proper comments + +### 4. **Performance Optimizations** +- โœ… Added cache headers for static assets in server.js +- โœ… Improved floating emoji performance with optimized transitions +- โœ… Reduced unnecessary console output in production + +### 5. **Error Handling Improvements** +- โœ… **js/about.js**: Graceful contributor loading failure handling +- โœ… **js/feedback.js**: Improved feedback submission error handling +- โœ… **js/feature.js**: Better Lenis library availability checking +- โœ… **js/floating_emoji_footer_fix.js**: Silent fallback when footer not found + +## ๐Ÿ“ Files Modified + +### HTML Files +- `html/about.html` - Removed duplicate CSS link +- `html/customize.html` - Added floating emoji fix +- `scale.html` - Added floating emoji fix, cleaned API references + +### JavaScript Files +- `js/floating_emoji_footer_fix.js` - Removed console logs, improved performance +- `js/about.js` - Fixed duplicate calls, improved error handling +- `js/feedback.js` - Cleaned console logs, better error messages +- `js/feature.js` - Improved Lenis availability checking +- `js/convert.js` - Removed hardcoded API keys +- `js/scale.js` - Removed hardcoded API keys +- `js/config.js` - **NEW**: Centralized configuration file + +### Server Files +- `server.js` - Added cache headers, environment port support + +## ๐Ÿ”’ Security Improvements + +1. **API Key Management**: + - Removed all hardcoded API keys from client-side code + - Added comments about proper server-side implementation + - Set API variables to `null` with explanatory comments + +2. **Error Information Disclosure**: + - Removed detailed error messages that could expose system information + - Implemented user-friendly error messages + +## ๐Ÿš€ Performance Improvements + +1. **Caching**: Added proper cache headers for static assets +2. **Error Handling**: Reduced unnecessary error logging in production +3. **Configuration**: Centralized settings for better maintainability + +## ๐ŸŽฏ Next Steps for Production + +1. **Server-Side API**: Implement API calls on the backend +2. **Environment Variables**: Use proper environment configuration +3. **Monitoring**: Add proper logging and monitoring for production +4. **Testing**: Add unit tests for critical functionality +5. **Build Process**: Implement minification and bundling + +## โœ… Verification + +All files have been: +- โœ… Linted with no errors +- โœ… Tested for functionality +- โœ… Checked for security issues +- โœ… Optimized for performance +- โœ… Documented with proper comments + +The code is now cleaner, more secure, and production-ready! ๐ŸŽ‰ diff --git a/BakeGenuis-AI/CODE_OF_CONDUCT.md b/BakeGenuis-AI/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..18f3f955 --- /dev/null +++ b/BakeGenuis-AI/CODE_OF_CONDUCT.md @@ -0,0 +1,92 @@ +# ๐ŸŒฑ Code of Conduct โ€” BakeGenius AI + +![Welcome Badge](https://img.shields.io/badge/Community-Welcoming-brightgreen?style=for-the-badge) +![Respect Badge](https://img.shields.io/badge/Respect-Everyone-blueviolet?style=for-the-badge) +![Contribution Badge](https://img.shields.io/badge/Contributions-Encouraged-orange?style=for-the-badge) +![Kindness Badge](https://img.shields.io/badge/Be-Kind-ff69b4?style=for-the-badge) + +--- + + +## ๐Ÿค Our Pledge + +We, as members, contributors, and leaders, pledge to make participation in our community a **harassment-free experience for everyone**. +We are committed to creating an **inclusive, friendly, and respectful environment** where collaboration thrives. ๐ŸŒ๐Ÿ’œ + +We pledge to: +- Treat every individual with **respect and empathy**. +- Build a culture where **differences are celebrated** and valued. +- Ensure our community is a place of **learning, creativity, and growth**. + +--- + +![Standards GIF](https://media.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3aXRiaTZ6ZGtoeTlsNjhkOHFjdmZremtoOHVsNG1qaXNxMWQ4NG5udSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/iYdrGlHbC0cAMwqfsL/giphy.gif) + +## ๐ŸŒŸ Our Standards + +### โœ… Positive behaviors we encourage: +- Showing **empathy, kindness, and respect** in all interactions ๐Ÿค— +- Being **open-minded** to different perspectives and ideas ๐ŸŒˆ +- Giving and **gracefully accepting constructive feedback** +- Prioritizing **community success over individual ego** ๐Ÿ’ช +- Helping others learn and grow ๐Ÿ“šโœจ + +### โŒ Behaviors that are unacceptable: +- Harassment, insults, or discriminatory comments ๐Ÿšซ +- Trolling, spreading negativity, or personal attacks +- Publishing others' **private information without consent** ๐Ÿ”’ +- Any kind of **exclusion or disrespectful behavior** +- Behavior inappropriate for professional and open communities + +--- + +![Enforcement GIF](https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExZXprMGp0YWJsaDNmZXZmdzduOHY4aHFjNTNtYW42eHN6b2dlazRicCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/L1R1tvI9svkIWwpVYr/giphy.gif) + +## ๐Ÿ› ๏ธ Enforcement Responsibilities + +- Community leaders are responsible for defining and enforcing standards of behavior. +- Leaders may take **appropriate and fair corrective actions** in response to violations. +- Leaders hold the right to **remove, edit, or reject contributions** that donโ€™t align with this Code of Conduct. โš–๏ธ +- Decisions will always be made in the best interest of the **communityโ€™s safety and inclusivity**. + +--- + +![Reporting GIF](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZzk0cm5zdjV5bHE2b3hlcDNqb2VxbG5naGU3bzIxcjRzejQzcWk0cyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/qgQUggAC3Pfv687qPC/giphy.gif) + +## ๐Ÿ“ข Reporting Issues + +If you see behavior that violates this Code of Conduct, please **report it immediately**. + +1. ๐Ÿ“จ Contact the maintainers through official communication channels. +2. ๐Ÿ”’ Reports will be treated with **confidentiality and respect**. +3. ๐Ÿš€ Community leaders will respond promptly and take fair action. + +We guarantee that **no retaliation will occur** against those who report in good faith. ๐Ÿ™Œ + +--- + +## ๐ŸŒ Scope + +This Code of Conduct applies to: +- All community spaces (online & offline). +- Public spaces where a person represents the community (e.g., GitHub repos, Discord, conferences, meetups). + +Whether you are **contributing code, writing documentation, attending discussions, or representing BakeGenius AI**, you are expected to follow this Code of Conduct. + +--- + +## ๐Ÿ† Acknowledgment + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1. + +We thank every contributor, maintainer, and member for **making BakeGenius AI a safe, inclusive, and inspiring space**. โœจ๐Ÿ’ก + +--- + +![Final Note GIF](https://media.giphy.com/media/v1.Y2lkPWVjZjA1ZTQ3ZzdpMHNzamV5bGl6cGs1NGZ6ajN5bDIxazlhdTJvdjByYjVnOHdrMyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/ll61xC3gYPh7C5SPCU/giphy.gif) + +## ๐ŸŽ‰ Final Note + +This is more than just rules โ€” itโ€™s about building a community where **creativity, collaboration, and kindness** thrive together. + +Letโ€™s make **BakeGenius AI** a place where everyone feels welcome to **learn, contribute, and innovate**. ๐Ÿฐ๐Ÿค–๐Ÿ’ก diff --git a/BakeGenuis-AI/CONTRIBUTING.md b/BakeGenuis-AI/CONTRIBUTING.md new file mode 100644 index 00000000..31f3ba5a --- /dev/null +++ b/BakeGenuis-AI/CONTRIBUTING.md @@ -0,0 +1,128 @@ +# ๐Ÿฐ Contributing to BakeGenius AI + +Thank you for considering contributing to **BakeGenius AI**! ๐ŸŽ‰ +Your contributions help make this project better, more innovative, and more welcoming for the community. Whether you are reporting a bug, suggesting a feature, improving documentation, or contributing code, your help is greatly appreciated. + +--- + +## ๐Ÿ“‹ Table of Contents +1. [Code of Conduct](#-code-of-conduct) +2. [Ways to Contribute](#-ways-to-contribute) +3. [Getting Started](#-getting-started) +4. [Contribution Workflow](#-contribution-workflow) +5. [Bug Reports & Feature Requests](#-bug-reports--feature-requests) +6. [Coding Guidelines](#-coding-guidelines) +7. [Commit Message Guidelines](#-commit-message-guidelines) +8. [Testing & Review Process](#-testing--review-process) +9. [Attribution](#-attribution) + +--- + +## ๐Ÿ“œ Code of Conduct +We expect all contributors to follow our **[Code of Conduct](CODE_OF_CONDUCT.md)**. +By participating in this project, you agree to maintain a **respectful and inclusive environment** for everyone. + +--- + +## ๐Ÿค Ways to Contribute +You can contribute in several ways: +- **๐Ÿž Report Bugs:** Submit issues for reproducible bugs. +- **๐Ÿ’ก Suggest Features:** Propose new ideas or improvements. +- **๐Ÿ“– Improve Documentation:** Enhance clarity, grammar, or structure. +- **โšก Add Code:** Fix bugs, build new features, or optimize existing ones. +- **๐Ÿงช Test:** Help us find issues by testing code in different environments. + +--- + +## ๐Ÿ›  Getting Started +Before contributing: +1. **Fork** the repository. +2. **Clone** your fork locally: + ```bash``` + git clone https://github.com/YOUR-USERNAME/BakeGenius-AI.git +3. **Install dependencies**: + ```bash``` + npm install +4. **Set up** your environment according to the **[README](README.md)**. + +--- + +๐Ÿ”„ **Contribution Workflow** +Follow these steps for a smooth process: +1. **Create a branch for your work**: + ```bash``` + git checkout -b feature/your-feature-name +2. **Make your changes and commit** +3. **Push** to your fork: + ```bash``` + git push origin feature/your-feature-name +4. **Open a Pull Request (PR)** against the main branch. +5. **Wait for review** and address any requested changes. + +--- + +๐Ÿž**Bug Reports & Feature Requests** +1. Use the **GitHub Issues** tab to report bugs or request features. +2. For bugs, include: + - Steps to reproduce ๐Ÿชœ + - Expected behavior โœ… + - Actual behavior โŒ + - Screenshots (if applicable) ๐Ÿ“ธ +3. For features, include: + - Problem statement + - Proposed solution + - Possible alternatives + +--- + +๐ŸŽฏ **Coding Guidelines** +To keep the codebase clean and consistent: +1. **JavaScript/React Code Style:** + - Use **camelCase** for variables and functions. + - Use **PascalCase** for components. + - Always lint before committing: + ```bash``` + npm run lint +2. Keep functions **small and focused**. +3. Write **meaningful** variable names. +4. Remove **unused code** and **comments**. + +--- + +๐Ÿ“ **Commit Message Guidelines** +**Follow this format**: + ```arduino``` + (scope): short description + +**Types:** +1. **feat** โ†’ New feature +2. **fix** โ†’ Bug fix +3. **docs** โ†’ Documentation change +4. **style** โ†’ Code formatting (no logic changes) +5. **refactor** โ†’ Code restructuring +6. **test** โ†’ Adding/Updating tests +7. **chore** โ†’ Maintenance tasks +**Example:** + ```pgsql``` + feat(auth): add **user login** API integration + +--- + +๐Ÿงช **Testing & Review Process** +**Before submitting a PR:** +1. Run all tests: + ```bash``` + npm test +2. Ensure **no ESLint errors** remain. +3. If adding new features, include unit tests. +4. All PRs require **at least one reviewerโ€™s approval** before merging. + +--- + +๐Ÿ… **Attribution** +This **CONTRIBUTING.md** was prepared with โค๏ธ by **Aditya Verma** for **BakeGenius AI** as part of the **GSSoC 2025 program.** +The structure and recommendations follow **GitHub Open Source Guides** and best practices used in leading open-source repositories. +Happy contributing! ๐ŸŽ‚๐Ÿช๐Ÿง +**BakeGenius AI โ€“ Where AI Meets Baking Magic** + +--- \ No newline at end of file diff --git a/BakeGenuis-AI/GOOGLE_SETUP.md b/BakeGenuis-AI/GOOGLE_SETUP.md new file mode 100644 index 00000000..45be054e --- /dev/null +++ b/BakeGenuis-AI/GOOGLE_SETUP.md @@ -0,0 +1,117 @@ +# ๐Ÿ” Google Sign-In Setup Guide + +This guide will help you set up Google Sign-In for local development and testing. + +## Prerequisites + +- A Google account +- Access to [Google Cloud Console](https://console.cloud.google.com/) + +## Step-by-Step Setup + +### 1. Create a Google Cloud Project + +1. Go to [Google Cloud Console](https://console.cloud.google.com/) +2. Click "Select a project" โ†’ "New Project" +3. Enter a project name (e.g., "BakeGenius-AI-Dev") +4. Click "Create" + +### 2. Enable Google+ API + +1. In your project, go to "APIs & Services" โ†’ "Library" +2. Search for "Google+ API" or "Google Identity Services" +3. Click on it and click "Enable" + +### 3. Create OAuth 2.0 Credentials + +1. Go to "APIs & Services" โ†’ "Credentials" +2. Click "Create Credentials" โ†’ "OAuth client ID" +3. If prompted, configure the OAuth consent screen: + - User Type: External + - App name: "BakeGenius AI Dev" + - User support email: Your email + - Developer contact information: Your email +4. Click "Save and Continue" through the remaining steps +5. Back to "Create OAuth client ID": + - Application type: Web application + - Name: "BakeGenius AI Web Client" + - Authorized JavaScript origins: Add your local development URLs: + - `http://localhost:5500` + - `http://localhost:5501` + - `http://127.0.0.1:5500` + - `http://127.0.0.1:5501` +6. Click "Create" +7. Copy the **Client ID** (looks like: `1234567890-abc123def456.apps.googleusercontent.com`) + +### 4. Configure Your Local Environment + +1. Copy the template file: + ```bash + cp js/google_config.example.js js/google_config.js + ``` + +2. Edit `js/google_config.js` and add your client ID: + ```javascript + window.GOOGLE_CLIENT_ID = "YOUR_ACTUAL_CLIENT_ID_HERE"; + ``` + +3. **Important**: Add `js/google_config.js` to `.gitignore` to keep your client ID private: + ```bash + echo "js/google_config.js" >> .gitignore + ``` + +### 5. Start Local Development Server + +```bash +cd /home/rht/Projects/BakeGenuis-AI +python3 -m http.server 5501 +``` + +### 6. Test Google Sign-In + +1. Open `http://localhost:5501/html/login.html` +2. You should see a Google Sign-In button below the login form +3. Click it and sign in with your Google account + +## Troubleshooting + +### Button Not Visible +- Check browser console for errors +- Verify `GOOGLE_CLIENT_ID` is set correctly +- Ensure you're serving over HTTP (not file://) + +### "Origin Mismatch" Error +- Add your exact localhost URL to Authorized JavaScript origins in Google Cloud Console +- Include the port number (e.g., `http://localhost:5501`) + +### "Invalid Client" Error +- Double-check your client ID is correct +- Ensure the Google+ API is enabled in your project + +### Ad-blocker Issues +- Some ad-blockers block Google scripts +- Temporarily disable ad-blockers for localhost testing + +## Security Notes + +- **Never commit your client ID** to version control +- The client ID is public and safe to use in frontend code +- Keep your OAuth consent screen configured appropriately +- Monitor your Google Cloud Console for unusual activity + +## Production Deployment + +When deploying to production: +1. Add your production domain to Authorized JavaScript origins +2. Update the OAuth consent screen with production details +3. Consider using environment variables for different environments + +## Need Help? + +- Check the [Google Identity Services documentation](https://developers.google.com/identity/gsi/web) +- Review the [OAuth 2.0 setup guide](https://developers.google.com/identity/protocols/oauth2) +- Open an issue in this repository for project-specific questions + +--- + +**Happy coding! ๐Ÿฐโœจ** diff --git a/BakeGenuis-AI/License b/BakeGenuis-AI/License new file mode 100644 index 00000000..97c88ffb --- /dev/null +++ b/BakeGenuis-AI/License @@ -0,0 +1,10 @@ + +The MIT License (MIT) +Copyright ยฉ 2025 supriya46788 + + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the โ€œSoftwareโ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED โ€œAS ISโ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/BakeGenuis-AI/README.md b/BakeGenuis-AI/README.md new file mode 100644 index 00000000..ad152d5b --- /dev/null +++ b/BakeGenuis-AI/README.md @@ -0,0 +1,306 @@ +
+ + **๐Ÿฐ BakeGenius AI - Precision Baking for Everyone** + +![GSSoC'25](https://img.shields.io/badge/GirlScript%20Summer%20of%20Code-2025-orange?style=for-the-badge) + +
+ +--- + +**BakeGenius AI** is an AI-powered tool that transforms vague recipe measurements like "1 cup of flour" or "2 tablespoons of butter" into precise gram-based values. It helps home cooks, professionals, and culinary enthusiasts bake with consistency and accuracy by removing the guesswork from measurements. + +> โšก *"BakeGenius AI bridges the gap between casual cooking and scientific precision."* + +--- +
+ Thanks Banner Typing SVG +
+ +--- + + + + + + + + + + + + + + + + + + + + + + + + +
๐ŸŒŸ Stars๐Ÿด Forks๐Ÿ› Issues๐Ÿ”” Open PRs๐Ÿ”• Closed PRs๐Ÿ› ๏ธ Languages๐Ÿ‘ฅ Contributors
StarsForksIssuesOpen PRsClosed PRsLanguages CountContributors Count
+ +--- + +## ๐Ÿง  Project Objective + +Many online recipes list ingredients using vague units like cups, teaspoons, and spoons, which can vary depending on the ingredient and person measuring. This inconsistency often leads to failed recipes. + +**BakeGenius AI solves this by:** +- Converting units like "cups", "tablespoons", etc., into exact grams. +- Using a built-in database of **ingredient densities**. +- Supporting **voice-based input**, **real-time AI assistance**, and **visualizations**. +- Empowering bakers with consistent, professional results every time. + +--- + +## ๐Ÿš€ Features + +โœ… Convert vague units to **precise gram measurements** +โœ… Smart ingredient detection using **Natural Language Processing (NLP)** +โœ… **Ingredient density database** for accurate conversions +โœ… **Real-time conversion engine** using Gemini API +โœ… **Voice input**: Speak your recipe and get precise outputs +โœ… Clean and **user-friendly interface** +โœ… Visualizations: Show side-by-side conversions and measurement charts +โœ… Open Source โ€“ Easy to contribute and extend + +--- + +

๐ŸŽฏ Open Source Programmes โญ

+

+ This project is now OFFICIALLY accepted for: +

+ +
+ +![GSSoC Logo](https://github.com/supriya46788/Research-Paper-Organizer/blob/main/images/gssoc-logo.png) +
+ +๐ŸŒŸ **Exciting News...** + +๐Ÿš€ This project is now an official part of GirlScript Summer of Code โ€“ GSSoC'25! ๐Ÿ’ƒ๐ŸŽ‰๐Ÿ’ป We're thrilled to welcome contributors from all over India and beyond to collaborate, build, and grow BakeGenuis-AI! Letโ€™s make learning and career development smarter โ€“ together! ๐ŸŒŸ๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป + +๐Ÿ‘ฉโ€๐Ÿ’ป GSSoC is one of Indiaโ€™s **largest 3-month-long open-source programs** that encourages developers of all levels to contribute to real-world projects ๐ŸŒ while learning, collaborating, and growing together. ๐ŸŒฑ + +๐ŸŒˆ With **mentorship, community support**, and **collaborative coding**, it's the perfect platform for developers to: + +- โœจ Improve their skills +- ๐Ÿค Contribute to impactful projects +- ๐Ÿ† Get recognized for their work +- ๐Ÿ“œ Receive certificates and swag! + +๐ŸŽ‰ **I canโ€™t wait to welcome new contributors** from GSSoC 2025 to this BakeGenuis-AI project family! Let's build, learn, and grow together โ€” one commit at a time. ๐Ÿ”ฅ๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป + +--- + +**๐Ÿ”ง Tech Stack** + +- **Frontend**: HTML, CSS, JavaScript +- **AI API**: Gemini API by Google (for language understanding and smart suggestions) + +--- + +**๐Ÿ“Š Example Conversion** + +| Input | Output (in grams) | +|------------------------|------------------| +| 1 cup of sugar | 200g | +| 2 tablespoons of butter| 28g | +| ยฝ cup of milk | 122g | +| 1 tsp of baking soda | 4.8g | + +(*values vary depending on the density of ingredients*) + +--- +**๐Ÿ› ๏ธ How to Run Locally** + +1. Clone the repository: +```bash +git clone https://github.com/supriya46788/BakeGenuis-AI.git +cd BakeGenuis-AI +``` + +## ๐Ÿ”‘ Firebase Configuration + +Update your Firebase SDK configuration in the file: + +```bash +js/firebase.js +``` + +To enable Google Sign-In and other Firebase services, update your Firebase SDK configuration inside the project: + +```bash +// Firebase Config +const firebaseConfig = { + apiKey: "YOUR_API_KEY", + authDomain: "YOUR_AUTH_DOMAIN", + projectId: "YOUR_PROJECT_ID", + storageBucket: "YOUR_STORAGE_BUCKET", + messagingSenderId: "YOUR_MESSAGING_SENDER_ID", + appId: "YOUR_APP_ID", + measurementId: "YOUR_MEASUREMENT_ID" +}; +``` +2. Open the `index.html` file in any browser to run the app. + +3. Ensure Gemini API keys are correctly added in your JS code. + +--- + +**๐Ÿ“ฅ Submitting a Pull Request** + +Follow these steps to contribute your changes to **BakeGenuis-AI**: + +1. **๐ŸŒŸ Star & Fork the Repository** + Click the **โ€œStarโ€** button to support the project, then **โ€œForkโ€** the repo to create your own copy: + ๐Ÿ‘‰ [https://github.com/supriya46788/BakeGenuis-AI](https://github.com/supriya46788/BakeGenuis-AI) + +2. **๐Ÿ“ฅ Clone Your Fork** + Use the following command to clone your forked repository to your local machine: + ```bash + git clone https://github.com/Your-Username/BakeGenuis-AI.git + ``` + 3. Create a Branch + Navigate to the project directory and create a new branch for your changes: + + ```bash + cd BakeGenuis-AI + git checkout -b my-feature-branch + ``` + + 4. Make Changes + Add your new ML projects, games, websites, or enhancements. Fix bugs or improve UI/UX as needed. + + 5. Commit Your Changes + Use a meaningful commit message: + + ```bash + git add . + git commit -m "๐Ÿ“ฆ [Feature Add] Add XYZ website project" + ``` + + 6. Push Your Changes + Push your branch to your GitHub fork: + + ```bash + git push origin my-feature-branch + ``` + 7. Submit a Pull Request + + Go to your fork on GitHub. + + Click "Compare & pull request". + + Add a descriptive title using one of the prefixes: [UI], [UX], [Feature Add]. + + Link the related issue (if any) and clearly describe your changes. + +--- + +**๐Ÿค Contributing** + +We welcome contributions from the community! +Hereโ€™s how you can help: + +- ๐Ÿ“Œ Raise issues or bug reports +- ๐ŸŒŸ Suggest new features +- ๐Ÿงช Improve AI prompt engineering or ingredient logic +- ๐ŸŽจ Enhance UI/UX + +--- + +**๐Ÿค๐Ÿ‘ค Contribution Guidelines** + +We love our contributors! If you'd like to help, please check out our [`CONTRIBUTE.md`](https://github.com/supriya46788/BakeGenuis-AI/blob/main/CONTRIBUTING.md) file for guidelines. + +>Thank you once again to all our contributors who has contributed to **BakeGenuis-AI!** Your efforts are truly appreciated. ๐Ÿ’–๐Ÿ‘ + + + +[![Contributors](https://img.shields.io/github/contributors/supriya46788/BakeGenuis-AI?style=for-the-badge)](https://github.com/supriya46788/BakeGenuis-AI/graphs/contributors) + + +

+ + Contributors + +

+ +See the full list of contributors and their contributions on the [`GitHub Contributors Graph`](https://github.com/supriya46788/BakeGenuis-AI/graphs/contributors). + +

+

Show some Red Heart by starring this awesome repository! +

+

+ +--- + +**๐Ÿ’ก Suggestions & Feedback** + +Feel free to open issues or discussions if you have any feedback, feature suggestions, or want to collaborate! + +--- + +**๐Ÿ™Œ Support & Star** + +***If you find this project helpful, please give it a star! โญ to support more such educational initiatives!*** + +--- + +**๐Ÿ“„ License** + +This project is licensed under the MIT License - see the [`License`](https://github.com/supriya46788/BakeGenuis-AI/blob/main/License) file for details. + +--- + +**โญ Stargazers** + +
+ + Stargazers + +
+ +--- + +**๐Ÿด Forkers** + +
+ + Forkers + + +--- + +

๐Ÿง‘โ€๐Ÿ’ปProject Admin:

+ + + + +
+Supriya
Supriya
+
+ +--- + + +**๐Ÿ‘จโ€๐Ÿ’ป Developed By** +**โค๏ธ Supriya and Contributors โค๏ธ** [open an issue](https://github.com/supriya46788/BakeGenuis-AI/issues) | [Watch Demo](https://supriya46788.github.io/BakeGenuis-AI/) + +--- + +
+ + Back to Top + +
+ +--- + +Ready to show off your coding achievements? Get started with BakeGenuis-AI today! ๐Ÿš€ diff --git a/BakeGenuis-AI/android-chrome-192x192.png b/BakeGenuis-AI/android-chrome-192x192.png new file mode 100644 index 00000000..bda9abb1 Binary files /dev/null and b/BakeGenuis-AI/android-chrome-192x192.png differ diff --git a/BakeGenuis-AI/android-chrome-512x512.png b/BakeGenuis-AI/android-chrome-512x512.png new file mode 100644 index 00000000..2d53324e Binary files /dev/null and b/BakeGenuis-AI/android-chrome-512x512.png differ diff --git a/BakeGenuis-AI/apple-touch-icon.png b/BakeGenuis-AI/apple-touch-icon.png new file mode 100644 index 00000000..2b3641cf Binary files /dev/null and b/BakeGenuis-AI/apple-touch-icon.png differ diff --git a/BakeGenuis-AI/css/about.css b/BakeGenuis-AI/css/about.css new file mode 100644 index 00000000..7f377f19 --- /dev/null +++ b/BakeGenuis-AI/css/about.css @@ -0,0 +1,1184 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --candy-red: #ff4757; + --sky-blue: #70a1ff; + --sunny-yellow: #ffa502; + --white: #ffffff; + --light-pink: #ffe0e6; + --light-blue: #e8f4ff; + --light-yellow: #fff5e0; + --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); +} +/* === Dark Theme Overrides for About Us === */ +[data-theme="dark"] body { + background: linear-gradient( + 135deg, + #121212 0%, + #1f1f1f 50%, + #2a2a2a 100% + ) !important; + color: #eee; + --navbar-gradient: linear-gradient(90deg, #222222, #111111, #333333); +} + +[data-theme="dark"] .hero-title, +[data-theme="dark"] .hero-subtitle, +[data-theme="dark"] .section-title, +[data-theme="dark"] .creator-name, +[data-theme="dark"] .creator-title, +[data-theme="dark"] .xyz { + color: #fff !important; +} + +[data-theme="dark"] .section-card, +[data-theme="dark"] .creator-section, +[data-theme="dark"] .contributors, +[data-theme="dark"] .step-card { + background: rgba(30, 30, 30, 0.85) !important; + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7); + color: #f0f0f0; +} + +[data-theme="dark"] .section-content, +[data-theme="dark"] .step-title, +[data-theme="dark"] .step-description, +[data-theme="dark"] .problem-item, +[data-theme="dark"] .creator-title { + color: #ccc; +} + +[data-theme="dark"] .cta-btn, +[data-theme="dark"] .social-link, +[data-theme="dark"] .scale-nav-btn { + background: linear-gradient(45deg, #bb86fc, #03dac6) !important; + color: #fff !important; + box-shadow: 0 8px 25px rgba(187, 134, 252, 0.3) !important; +} + +[data-theme="dark"] .social-link:hover, +[data-theme="dark"] .cta-btn:hover { + transform: scale(1.05); + box-shadow: 0 10px 30px rgba(187, 134, 252, 0.5); +} + +[data-theme="dark"] .navbar { + background: var(--navbar-gradient); + box-shadow: 0 4px 20px rgba(187, 134, 252, 0.4); + border-bottom: 1px solid rgba(187, 134, 252, 0.2); +} + +[data-theme="dark"] .nav-links li a { + color: var(--link-color) !important; + text-shadow: 0 0 8px rgba(187, 134, 252, 0.5); +} + +[data-theme="dark"] .nav-links li a:hover { + transform: translateY(-2px); + text-shadow: 0 0 12px rgba(187, 134, 252, 0.8); +} + +[data-theme="dark"] .footer { + background: var(--footer-bg) !important; + color: var(--footer-text) !important; + box-shadow: 0 0 30px rgba(255, 255, 255, 0.05); +} + +[data-theme="dark"] .footer-links ul li a, +[data-theme="dark"] .footer-text { + color: #e0e0e0 !important; +} +[data-theme="dark"] .footer-links ul li a:hover { + color: #ff7f50 !important; +} + +[data-theme="dark"] .contributor-card { + background: rgba(40, 40, 40, 0.85); + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.7); +} + +[data-theme="dark"] .creator-avatar { + background: linear-gradient(135deg, #bb86fc, #03dac6); +} + +[data-theme="dark"] .creator-avatar::before { + background: linear-gradient(135deg, #03dac6, #bb86fc, #3700b3); +} + +[data-theme="dark"] .problem-item { + background: rgba(187, 134, 252, 0.1); + border-left: 4px solid #bb86fc; +} + +[data-theme="dark"] .step-card { + background: rgba(30, 30, 30, 0.7); + border: 1px solid rgba(255, 255, 255, 0.1); +} +body { + font-family: "Comic Neue", cursive; + background: linear-gradient( + 135deg, + var(--light-pink) 0%, + var(--light-blue) 30%, + var(--light-yellow) 60%, + var(--light-pink) 100% + ); + min-height: 100vh; + position: relative; + overflow-x: hidden; + line-height: 1.6; +} +/* Dark-Light Toggle Slider */ +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(96, 165, 250, 0.7); border-radius: 34px; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + font-size: 12px; + color: #fff; +} + +.slider:before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +/* When checked (dark mode) */ +.theme-switch input:checked + .slider { + background: linear-gradient(45deg, #bf60fa, #fde68a); +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} +/* Advanced Animated Background */ +.page-content { + position: relative; + overflow: hidden; + z-index: 1; +} + +.page-content .animated-bg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 0; +} + +.floating-element { + position: absolute; + animation: floatAdvanced 8s ease-in-out infinite; + opacity: 0.7; +} + +.floating-element:nth-child(1) { + top: 10%; + left: 5%; + font-size: 3rem; + animation-delay: 0s; +} +.floating-element:nth-child(2) { + top: 20%; + right: 10%; + font-size: 2.5rem; + animation-delay: 2s; +} +.floating-element:nth-child(3) { + bottom: 30%; + left: 15%; + font-size: 2rem; + animation-delay: 4s; +} +.floating-element:nth-child(4) { + bottom: 20%; + right: 20%; + font-size: 2.8rem; + animation-delay: 1s; +} +.floating-element:nth-child(5) { + top: 50%; + left: 80%; + font-size: 2.2rem; + animation-delay: 3s; +} +.floating-element:nth-child(6) { + top: 70%; + left: 10%; + font-size: 1.8rem; + animation-delay: 5s; +} + +@keyframes floatAdvanced { + 0%, + 100% { + transform: translateY(0px) translateX(0px) rotate(0deg) scale(1); + opacity: 0.7; + } + 25% { + transform: translateY(-30px) translateX(20px) rotate(5deg) scale(1.1); + opacity: 0.9; + } + 50% { + transform: translateY(-60px) translateX(-10px) rotate(-3deg) scale(0.9); + opacity: 0.6; + } + 75% { + transform: translateY(-20px) translateX(15px) rotate(8deg) scale(1.05); + opacity: 0.8; + } +} + +/* Sparkle Effect */ +.sparkles { + position: absolute; + width: 100%; + height: 100%; +} + +.sparkle { + position: absolute; + width: 4px; + height: 4px; + background: var(--sunny-yellow); + border-radius: 50%; + animation: sparkle 3s linear infinite; +} + +@keyframes sparkle { + 0% { + opacity: 0; + transform: scale(0); + } + 50% { + opacity: 1; + transform: scale(1); + } + 100% { + opacity: 0; + transform: scale(0); + } +} + +/* Navigation Bar */ +/* Navbar Base */ +.navbar { + width: 100%; + background: linear-gradient( + 90deg, + #60a5fa, + #f9a8d4, + #fde68a + ); /* light blue โ†’ light pink โ†’ soft yellow */ + padding: 12px 20px; + position: sticky; + top: 0; + z-index: 1000; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; + gap: 1rem; +} + +/* Navigation Right Section */ +.nav-right { + display: flex; + align-items: center; + gap: 0.8rem; + flex-wrap: wrap; +} + +/* Logo */ +.logo { + font-size: 1.5rem; + font-weight: bold; + color: #ffffff; + letter-spacing: 1px; +} + +.logo a { + text-decoration: none; + color: #fff; +} + +/* Nav Links */ +.nav-links { + display: flex; + list-style: none; + gap: 1.2rem; + align-items: center; + margin: 0; + padding: 0; +} + +.nav-links li a { + color: #ffffff; + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 5px 0; +} + +/* Hover Gradient Underline */ +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after, +.nav-links li a.active::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} + +.fb-color { + padding: 8px 15px; + background: linear-gradient(45deg, #60a5fa, #fde68a); + border-radius: 20px; + border: none; +} +.fb-color:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} +.fb-color a { + color: white; + text-decoration: none; +} + +/* CTA Button */ +.cta-btn { + padding: 10px 20px; + background: linear-gradient(45deg, #60a5fa, #f9a8d4, #fde68a); + color: #ffffff; + font-weight: bold; + text-decoration: none; + border-radius: 30px; + transition: all 0.4s ease; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); +} + +.cta-btn:hover { + transform: scale(1.08); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); +} + +/* Scale Now Navigation Button */ +/* Scale Now Navigation Button - same as Feedback */ +.scale-nav-btn { + padding: 8px 15px; + background: linear-gradient(45deg, #60a5fa, #fde68a); + border-radius: 20px; + border: none; + color: #ffffff; + font-weight: 600; + text-decoration: none; + display: inline-block; + transition: all 0.3s ease; +} + +.scale-nav-btn:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} + +.scale-nav-btn::after { + display: none; +} + + +/* User Info Display */ +.user-info { + display: flex; + align-items: center; + gap: 1rem; + color: #ffffff; + font-weight: 600; +} + +.user-avatar { + width: 40px; + height: 40px; + background: linear-gradient(45deg, #c270f6, #747061); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + color: white; +} + +.logout-btn { + background: linear-gradient(90deg, #ff5f6d, #c31432); + color: #ffffff; + border: none !important; + padding: 0.5rem 1rem; + border-radius: 20px; + font-family: "Comic Neue", cursive; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + font-size: 0.9rem; + box-shadow: 0 2px 8px rgba(255, 71, 87, 0.3) !important; +} + +.logout-btn:hover { + background: linear-gradient(45deg, #ff3838, #ff2d2d) !important; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 71, 87, 0.4) !important; +} +/* Hero Section */ +.hero { + text-align: center; + padding: 2rem 2rem 4rem; + position: relative; + z-index: 10; +} + +.hero-title { + font-size: 4rem; + font-weight: 700; + background: linear-gradient( + 135deg, + var(--candy-red), + var(--sky-blue), + var(--sunny-yellow) + ); + -webkit-background-clip: text; + background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + margin-bottom: 1rem; + animation: heroAnimation 3s ease-out; +} + +@keyframes heroAnimation { + 0% { + opacity: 0; + transform: translateY(50px) scale(0.8); + } + 100% { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.hero-subtitle { + font-size: 1.5rem; + color: #666; + margin-bottom: 2rem; + animation: fadeInUp 1s ease-out 0.5s both; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Main Container */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 2rem; + position: relative; + z-index: 10; +} + +/* Section Cards */ +.section-card { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + border-radius: 30px; + padding: 3rem; + margin-bottom: 3rem; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + position: relative; + overflow: hidden; + transition: all 0.5s ease; +} + +.section-card::before { + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: conic-gradient( + from 0deg, + transparent, + rgba(255, 71, 87, 0.1), + transparent + ); + animation: rotate 20s linear infinite; + opacity: 0; + transition: opacity 0.5s ease; +} + +.section-card:hover::before { + opacity: 1; +} + +@keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.section-card:hover { + transform: translateY(-10px); + box-shadow: 0 30px 80px rgba(0, 0, 0, 0.15); +} + +.section-header { + display: flex; + align-items: center; + margin-bottom: 2rem; +} + +.section-icon { + font-size: 3rem; + margin-right: 1rem; + animation: iconBounce 2s ease-in-out infinite; +} + +@keyframes iconBounce { + 0%, + 20%, + 50%, + 80%, + 100% { + transform: translateY(0); + } + 40% { + transform: translateY(-10px); + } + 60% { + transform: translateY(-5px); + } +} + +.section-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--candy-red); + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.section-content { + font-size: 1.2rem; + color: #555; + line-height: 1.8; + position: relative; + z-index: 1; +} +/* Contributors Section */ +.contributors { + margin: 60px auto; + padding: 40px; + background: #fff; + border-radius: 20px; + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); + text-align: center; +} +.img { + font-size: xx-large; +} +.contributor-card h3 { + text-decoration: underline; +} + +.xyz { + font-size: 2rem; + margin-bottom: 30px; + font-weight: 700; + background: linear-gradient(90deg, #ff6ec4, #7873f5); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} + +.contributor-cards { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 20px; +} + +.contributor-card { + background: #fafafa; + border-radius: 15px; + padding: 20px; + width: 220px; + text-align: center; + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.contributor-card:hover { + transform: translateY(-8px); + box-shadow: 0 12px 25px rgba(0, 0, 0, 0.15); +} + +.contributor-card img { + width: 90px; + height: 90px; + border-radius: 50%; + margin-bottom: 15px; + border: 3px solid #ff6ec4; +} + +.contributor-card h3 a { + text-decoration: none; + color: #333; + font-weight: 600; +} + +.contributor-card p { + font-size: 14px; + color: #666; +} + +/* Problem List */ +.problem-list { + list-style: none; + padding: 0; +} + +.problem-item { + background: rgba(255, 71, 87, 0.1); + border-left: 4px solid var(--candy-red); + padding: 1rem 1.5rem; + margin-bottom: 1rem; + border-radius: 0 15px 15px 0; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.problem-item::before { + content: "โš ๏ธ"; + margin-right: 1rem; + font-size: 1.2rem; +} + +.problem-item:hover { + background: rgba(255, 71, 87, 0.2); + transform: translateX(10px); + box-shadow: 0 5px 15px rgba(255, 71, 87, 0.2); +} + +/* How It Works Steps */ +.steps-container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; + margin: 2rem 0; +} + +.step-card { + background: linear-gradient( + 135deg, + rgba(112, 161, 255, 0.1), + rgba(255, 165, 2, 0.1) + ); + border-radius: 20px; + padding: 2rem; + text-align: center; + border: 2px solid transparent; + transition: all 0.4s ease; + position: relative; + overflow: hidden; +} + +.step-card::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 20px; + padding: 2px; + background: linear-gradient( + 135deg, + var(--sky-blue), + var(--sunny-yellow), + var(--candy-red) + ); + mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + mask-composite: exclude; + opacity: 0; + transition: opacity 0.4s ease; +} + +.step-card:hover::before { + opacity: 1; +} + +.step-card:hover { + transform: translateY(-5px) scale(1.05); + box-shadow: 0 20px 40px rgba(112, 161, 255, 0.2); +} + +.step-number { + font-size: 3rem; + font-weight: 700; + color: var(--sky-blue); + margin-bottom: 1rem; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.step-title { + font-size: 1.3rem; + font-weight: 700; + color: #333; + margin-bottom: 1rem; +} + +.step-description { + color: #666; + font-size: 1rem; +} + +/* Creator Section */ +.creator-section { + background: linear-gradient( + 135deg, + rgba(255, 71, 87, 0.1), + rgba(112, 161, 255, 0.1) + ); + border-radius: 30px; + padding: 3rem; + text-align: center; + position: relative; + overflow: hidden; +} + +.creator-avatar { + width: 150px; + height: 150px; + border-radius: 50%; + background: linear-gradient(135deg, var(--candy-red), var(--sky-blue)); + display: flex; + align-items: center; + justify-content: center; + font-size: 4rem; + color: white; + margin: 0 auto 2rem; + animation: avatarFloat 3s ease-in-out infinite; + position: relative; +} + +.creator-avatar::before { + content: ""; + position: absolute; + top: -10px; + left: -10px; + right: -10px; + bottom: -10px; + border-radius: 50%; + background: linear-gradient( + 135deg, + var(--sunny-yellow), + var(--candy-red), + var(--sky-blue) + ); + z-index: -1; + animation: avatarGlow 4s ease-in-out infinite; +} + +@keyframes avatarFloat { + 0%, + 100% { + transform: translateY(0px); + } + 50% { + transform: translateY(-15px); + } +} + +@keyframes avatarGlow { + 0%, + 100% { + opacity: 0.3; + transform: scale(1); + } + 50% { + opacity: 0.8; + transform: scale(1.05); + } +} + +.creator-name { + font-size: 2.5rem; + font-weight: 700; + color: var(--candy-red); + margin-bottom: 1rem; +} + +.creator-title { + font-size: 1.3rem; + color: #666; + margin-bottom: 2rem; +} + +.social-link { + display: inline-flex; + align-items: center; + gap: 0.5rem; + background: var(--sky-blue); + color: white; + text-decoration: none; + padding: 1rem 2rem; + border-radius: 50px; + font-weight: 600; + transition: all 0.4s ease; + box-shadow: 0 8px 25px rgba(112, 161, 255, 0.3); + position: relative; + overflow: hidden; +} + +.social-link::before { + content: ""; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(255, 255, 255, 0.2); + border-radius: 50%; + transition: all 0.6s ease; + z-index: 0; +} + +.social-link:hover::before { + width: 300px; + height: 300px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.social-link:hover { + transform: translateY(-3px) scale(1.05); + box-shadow: 0 15px 35px rgba(112, 161, 255, 0.4); +} + +.social-link span { + position: relative; + z-index: 1; +} + +/* Mobile Responsive */ +@media (max-width: 968px) { + .navbar { + padding: 10px 15px; + } + + .navbar-container { + flex-direction: column; + gap: 1rem; + } + + .nav-links { + order: 2; + gap: 1rem; + flex-wrap: wrap; + justify-content: center; + } + + .nav-right { + order: 3; + justify-content: center; + gap: 0.5rem; + } + + .hero-title { + font-size: 2.5rem; + } + + .hero-subtitle { + font-size: 1.2rem; + } + + .section-card { + padding: 2rem; + } + + .section-title { + font-size: 2rem; + } + + .steps-container { + grid-template-columns: 1fr; + } + + .creator-avatar { + width: 120px; + height: 120px; + font-size: 3rem; + } + + .creator-name { + font-size: 2rem; + } + + .feedback-header { + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; + } +} + +/* Scroll Animations */ +.animate-on-scroll { + opacity: 0; + transform: translateY(50px); + transition: all 0.8s ease; +} + +.animate-on-scroll.animated { + opacity: 1; + transform: translateY(0); +} + +.footer { + background-color: #ffb6c1; + color: #fff; + padding: 40px 20px; + font-family: sans-serif; +} + +.footer-container { + max-width: 1200px; + margin: auto; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 30px; +} + +.footer h2 { + color: #ff7f50; +} + +.footer h3 { + margin-bottom: 10px; + color: #ff7f50; +} + +.footer p { + font-size: 16px; + line-height: 1.5; +} + +.footer-links ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-links ul li { + margin-bottom: 6px; +} + +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: color 0.3s; +} + +.footer-links ul li a:hover { + color: #ff7f50; +} + +.footer-newsletter input { + padding: 10px; + width: 100%; + margin-bottom: 10px; + border: none; + border-radius: 4px; +} + +.footer-newsletter button { + background-color: #ff7f50; + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background 0.3s; +} + +.footer-newsletter button:hover { + background-color: #ff956b; +} + +/* Social icons */ +.social-icons { + display: flex; + gap: 12px; + margin-top: 10px; +} + +.social-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + color: white; + font-size: 18px; + transition: transform 0.3s, opacity 0.3s; +} + +.social-icon:hover { + transform: scale(1.1); + opacity: 0.85; +} + +/* Specific brand colors */ +.social-icon.linkedin { + background: #0077b5; +} +.social-icon.github { + background: #6e5494; +} +.social-icon.email { + background: #ff8800; +} + +.footer-bottom { + text-align: center; + font-size: 14px; + margin-top: 30px; + border-top: 1px solid #333; + padding-top: 20px; +} + +/* Back to Top Button */ +#scrollTopBtn { + display: none; + position: fixed; + bottom: 30px; + right: 30px; + z-index: 99; + font-size: 30px; + border: none; + outline: none; + background: linear-gradient(45deg, #ff6ec7, #ffa07a, #87cefa); + color: black; + cursor: pointer; + padding: 7px 15px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + transition: all 0.3s ease; +} + +#scrollTopBtn:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(0,0,0,0.3); +} + +#contributors-container { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 10px; +} + +.contributor-card { + display: flex; + align-items: center; + background: #fff; + border-radius: 8px; + padding: 4px 8px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + transition: transform 0.2s; + max-width: 150px; + overflow: hidden; + cursor: pointer; +} + +.contributor-card img { + width: 35px; + height: 35px; + border-radius: 50%; + margin-right: 6px; + flex-shrink: 0; +} + +.contributor-card span { + font-size: 13px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.contributor-card:hover { + transform: translateY(-2px) scale(1.05); +} diff --git a/BakeGenuis-AI/css/auth.css b/BakeGenuis-AI/css/auth.css new file mode 100644 index 00000000..cffca29a --- /dev/null +++ b/BakeGenuis-AI/css/auth.css @@ -0,0 +1,968 @@ +/* =================================================================== */ +/* BakeGenius.ai - Authentication Stylesheet */ +/* Rewritten for Clarity, Maintainability, and Responsiveness */ +/* =================================================================== */ + + +/* ======================= + Theme Styles + ======================= */ +html[data-theme="dark"] { + background-color: #1e1e1e; + color: #ffffff; +} + +html[data-theme="light"] { + background-color: #ffffff; + color: #000000; +} + +/* ======================= + Auth Title Gradient + ======================= */ +.auth-title { + font-size: 24px; + font-weight: bold; + text-align: center; +} + +html[data-theme="dark"] .auth-title { + background: linear-gradient(45deg, #FF6B6B, #70A1FF, #FFD700); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +/* ======================= + General UI Elements + ======================= */ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; +} + +button { + background-color: #70A1FF; + color: #fff; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #4A90E2; +} + + + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --candy-red: #ff4757; + --sky-blue: #70a1ff; + --sunny-yellow: #ffa502; + --white: #ffffff; + --light-pink: #ffe0e6; + --light-blue: #e8f4ff; + --light-yellow: #fff5e0; + --dark-gray: #2c3e50; + --light-gray: #f8f9fa; + --success-green: #2ed573; + --error-red: #ff3838; +} + +body { + font-family: "Comic Neue", cursive; + background: linear-gradient( + 135deg, + var(--light-pink) 0%, + var(--light-blue) 50%, + var(--light-yellow) 100% + ); + min-height: 100vh; + position: relative; + overflow-x: hidden; +} + +/* -------------------------------------- */ +/* 2. Animated Background & Overlays */ +/* -------------------------------------- */ + +.floating-elements { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; +} + +.floating-cupcake { + position: absolute; + font-size: 2rem; + animation: float 6s ease-in-out infinite; + opacity: 0.7; +} + +.floating-cupcake:nth-child(1) { + top: 10%; + left: 10%; + animation-delay: 0s; +} +.floating-cupcake:nth-child(2) { + top: 20%; + right: 15%; + animation-delay: 2s; +} +.floating-cupcake:nth-child(3) { + bottom: 20%; + left: 20%; + animation-delay: 4s; +} +html[data-theme="dark"] .auth-title { + background: linear-gradient(45deg, #FF6B6B, #70A1FF, #FFD700); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +@keyframes float { + 0%, + 100% { + transform: translateY(0px) rotate(0deg); + } + 50% { + transform: translateY(-20px) rotate(5deg); + } +} + +/* -------------------------------------- */ +/* 3. Navigation Bar */ +/* -------------------------------------- */ + +.navbar { + width: 100%; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + padding: 12px 20px; + position: sticky; + top: 0; + z-index: 1000; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; + gap: 1rem; +} + +/* Navigation Right Section */ +.nav-right { + display: flex; + align-items: center; + gap: 0.8rem; + flex-wrap: wrap; +} + +.logo { + font-size: 1.5rem; + font-weight: bold; +} + +.logo a { + text-decoration: none; + color: #fff; +} + +.nav-links { + display: flex; + list-style: none; + gap: 1.2rem; + align-items: center; + margin: 0; + padding: 0; +} + +.nav-links li a { + color: #ffffff; + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 5px 0; +} + +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} + +.fb-color { + padding: 8px 15px; + background-color: rgba(238, 255, 0, 0.356); + border-radius: 20px; + border: none; + transition: background-color 0.3s ease; +} + +.fb-color:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} + +.fb-color a { + color: white; + text-decoration: none; +} + +.signup-btn { + padding: 8px 15px; + background-color: #ff6b6b; + color: white; + border: none; + border-radius: 20px; + cursor: pointer; + transition: all 0.3s; + text-decoration: none; + font-weight: 500; +} + +.signup-btn:hover { + background-color: #ff5252; +} + +/* -------------------------------------- */ +/* 4. Theme Toggle Switch */ +/* -------------------------------------- */ + +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(96, 165, 250, 0.7); + border-radius: 34px; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + font-size: 12px; + color: #fff; +} + +.slider:before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +.theme-switch input:checked + .slider { + background: linear-gradient(45deg, #bf60fa, #fde68a); + +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} +/* Divider line */ + .divider { + display: flex; + align-items: center; + text-align: center; + margin: 12px 0; + } + + .divider::before, + .divider::after { + content: ""; + flex: 1; + border-bottom: 1px solid #e0e0e0; + } + + .divider:not(:empty)::before { + margin-right: 15px; + } + + .divider:not(:empty)::after { + margin-left: 15px; + } + + .divider span { + color: #666; + font-size: 14px; + font-weight: 500; + white-space: nowrap; + padding: 0 5px; + } + /*-candy-red: #FF4757; + --sky-blue: #70A1FF; + --sunny-yellow: #FFA502; + --white: #FFFFFF; + --light-pink: #FFE0E6; + --light-blue: #E8F4FF; + --light-yellow: #FFF5E0; + --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + }*/ + + /* Google Button */ + .google-btn { + display: flex; + font-family: 'Comic Neue', cursive !important; + align-items: center; + justify-content: center; + gap: 8px; + width: 100%; + padding: 1.3rem; + background:rgba(255, 71, 87, 0.8) ; + color: white !important; + border: none; + border-radius: 20px; + font-size: 1.05rem; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; + margin-bottom: 1.2rem; + letter-spacing: 0.5px; + text-transform: uppercase; + box-shadow: + 0 8px 20px rgba(66, 133, 244, 0.3), + 0 4px 10px rgba(15, 157, 88, 0.2); + position: relative; + overflow: hidden; + font-family: 'Inter', sans-serif; + } + + /* Shine effect */ + .google-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient( + 90deg, + transparent, + rgba(255, 255, 255, 0.25), + transparent + ); + transition: left 0.5s; + } + + .google-btn:hover::before { + left: 100%; + } + + /* Active click */ + .google-btn:active { + transform: translateY(0); + } + + /* Google icon */ + .google-icon { + width: 20px; + height: 20px; + transition: transform 0.2s ease; + filter: drop-shadow(0 0 4px rgba(241, 255, 93, 0.8)); /* soft glow */ + } + + .google-btn:hover .google-icon { + transform: scale(1.1); + } + + @keyframes spin { + 0% { + transform: translateY(-50%) rotate(0deg); + } + + 100% { + transform: translateY(-50%) rotate(360deg); + } + } +/* Animated Background Elements */ +.floating-elements { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; +} + + + +/* -------------------------------------- */ +/* 5. Auth Card & Container */ +/* -------------------------------------- */ + +.auth-container { + display: flex; + justify-content: center; + align-items: center; + min-height: calc(100vh - 70px); + padding: 2rem 1rem; /* Added horizontal padding */ + position: relative; + z-index: 10; +} + +.auth-card { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + border-radius: 30px; + padding: 3rem; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + width: 100%; + max-width: 450px; + position: relative; + overflow: hidden; +} + +.auth-header { + text-align: center; + margin-bottom: 2rem; +} + +.auth-title { + font-size: 2.5rem; + font-weight: 700; + background: linear-gradient( + 45deg, + var(--candy-red), + var(--sky-blue), + var(--sunny-yellow) + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 0.5rem; +} + +.auth-subtitle { + color: #666; + font-size: 1.1rem; +} + +/* -------------------------------------- */ +/* 6. Form Styling */ +/* -------------------------------------- */ + +.form-group { + margin-bottom: 1.5rem; +} + +.form-label { + display: flex; + align-items: center; + gap: 0.5rem; + font-weight: 600; + color: var(--dark-gray); + margin-bottom: 0.5rem; +} + +.form-label i { + color: var(--sky-blue); + width: 16px; +} + +.form-input { + width: 100%; + padding: 1rem 1.2rem; + border: 2px solid #e0e0e0; + border-radius: 15px; + font-family: "Comic Neue", cursive; + font-size: 1rem; + background: rgba(255, 255, 255, 0.8); + transition: all 0.3s ease; + color: var(--dark-gray); +} + +.form-input:focus { + outline: none; + border-color: var(--sky-blue); + box-shadow: 0 0 0 3px rgba(112, 161, 255, 0.2); + background: #fff; +} + +.form-input::placeholder { + color: #999; +} + +.password-input-container { + position: relative; +} + +.password-toggle { + position: absolute; + right: 1rem; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + color: #666; + cursor: pointer; + padding: 0.5rem; + border-radius: 50%; + transition: all 0.3s ease; +} + +.password-toggle:hover { + background: rgba(112, 161, 255, 0.1); + color: var(--sky-blue); +} + +/* -------------------------------------- */ +/* 7. Buttons (Submit, Google, etc.) */ +/* -------------------------------------- */ + +.auth-button { + width: 100%; + padding: 1.2rem; + color: var(--white); + border: none; + border-radius: 20px; + font-family: "Comic Neue", cursive; + font-size: 1.2rem; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; +} + +#loginButton { + background: linear-gradient(45deg, var(--sky-blue), var(--candy-red)); + box-shadow: 0 8px 25px rgba(112, 161, 255, 0.4); +} + +#loginButton:hover { + transform: translateY(-2px); + box-shadow: 0 12px 35px rgba(112, 161, 255, 0.5); +} + +#signupButton { + background: linear-gradient(45deg, var(--candy-red), var(--sunny-yellow)); + box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4); +} + +#signupButton:hover { + transform: translateY(-2px); + box-shadow: 0 12px 35px rgba(255, 107, 107, 0.5); +} + +.auth-button:disabled { + opacity: 0.7; + cursor: not-allowed; + transform: none; +} + +.google-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + width: 100%; + padding: 1.1rem; /* Slightly reduced padding */ + background: #fff; + color: #444; + border: 2px solid #e0e0e0; + border-radius: 20px; + font-size: 1rem; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); +} + +.google-btn:hover { + transform: translateY(-2px); + border-color: #4285f4; + box-shadow: 0 8px 15px rgba(66, 133, 244, 0.2); +} + +.google-icon { + width: 20px; + height: 20px; +} + +/* -------------------------------------- */ +/* 8. Divider & Loading Spinner */ +/* -------------------------------------- */ + +.divider { + display: flex; + align-items: center; + text-align: center; + margin: 24px 0; +} + +.divider::before, +.divider::after { + content: ""; + flex: 1; + border-bottom: 1px solid #e0e0e0; +} + +.divider:not(:empty)::before { + margin-right: 15px; +} +.divider:not(:empty)::after { + margin-left: 15px; +} + +.divider span { + color: #666; + font-size: 14px; +} + +.loading-spinner { + display: none; + width: 20px; + height: 20px; + border: 2px solid transparent; + border-top: 2px solid var(--white); + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +/* -------------------------------------- */ +/* 9. Error & Success Messages */ +/* -------------------------------------- */ + +.error-message, +.success-message { + border: 2px solid; + border-radius: 12px; + padding: 1rem; + margin-bottom: 1rem; + font-weight: 600; + text-align: center; + display: none; +} + +.error-message { + background: rgba(255, 56, 56, 0.1); + border-color: var(--error-red); + color: var(--error-red); + animation: shake 0.5s ease-in-out; +} + +.success-message { + background: rgba(46, 213, 115, 0.1); + border-color: var(--success-green); + color: var(--success-green); +} + +.error-message.show, +.success-message.show { + display: block; +} + +@keyframes shake { + 0%, + 100% { + transform: translateX(0); + } + 25% { + transform: translateX(-5px); + } + 75% { + transform: translateX(5px); + } +} + +/* -------------------------------------- */ +/* 10. Auth Footer (FIX APPLIED) */ +/* -------------------------------------- */ + +.auth-footer { + text-align: center; + margin-top: 2rem; +} + +.auth-footer p { + color: #666; + font-size: 1rem; + + /* Flexbox for perfect alignment */ + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; /* Allows clean wrapping on small screens */ + gap: 10px; /* Provides space between text and button */ +} + +.auth-link { + color: var(--sky-blue); + text-decoration: none; + font-weight: 600; + transition: all 0.3s ease; +} + +.signup-link { + /* This styles the link as a proper button */ + background: linear-gradient(45deg, var(--candy-red), var(--sunny-yellow)); + color: white; + white-space: nowrap; /* Prevents text from splitting */ + + font-weight: 700; + padding: 0.5rem 1rem; + border-radius: 15px; + border: none; + transition: all 0.3s ease; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.auth-link:hover, +.signup-link:hover { + transform: translateY(-2px); + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + text-decoration: none; + color: var(--candy-red); /* General hover color */ +} + +/* Override hover color for the button */ +.signup-link:hover { + color: white; +} + +/* -------------------------------------- */ +/* 11. Other UI Elements */ +/* -------------------------------------- */ + +#scrollTopBtn { + display: none; + position: fixed; + bottom: 30px; + right: 30px; + z-index: 99; + font-size: 20px; + border: none; + outline: none; + background: linear-gradient(45deg, #ff6ec7, #ffa07a); + color: white; + cursor: pointer; + width: 50px; /* Set explicit dimensions */ + height: 50px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + transition: all 0.3s ease; +} + +#scrollTopBtn:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3); +} + +/* -------------------------------------- */ +/* 12. Dark Mode Styles */ +/* -------------------------------------- */ + +html[data-theme="dark"] { + background: linear-gradient(135deg, #1c1c1c 0%, #2c2c2c 50%, #0e0e0e 100%); + color: #f0f0f0; +} + +html[data-theme="dark"] body { + background: none; +} + +/* Navbar */ +[data-theme="dark"] .navbar { + background: linear-gradient(90deg, #222222, #111111, #333333); + box-shadow: 0 4px 20px rgba(187, 134, 252, 0.4); + border-bottom: 1px solid rgba(187, 134, 252, 0.2); +} + +[data-theme="dark"] .nav-links li a { + color: #ffffff !important; + text-shadow: 0 0 8px rgba(187, 134, 252, 0.5); +} + +/* Auth Card & Form */ +html[data-theme="dark"] .auth-card { + background: rgba(30, 30, 30, 0.95); + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.7); +} + +html[data-theme="dark"] .auth-subtitle, +html[data-theme="dark"] .auth-footer p, +html[data-theme="dark"] .divider span { + color: #ccc; +} + +html[data-theme="dark"] .form-label { + color: #ddd; +} + +html[data-theme="dark"] .form-input { + background: rgba(60, 60, 60, 0.9); + border-color: rgba(255, 255, 255, 0.2); + color: #fff; +} + +html[data-theme="dark"] .form-input::placeholder { + color: #aaa; +} + +html[data-theme="dark"] .form-input:focus { + background: rgba(70, 70, 70, 0.95); + border-color: #70a1ff; + box-shadow: 0 0 8px rgba(112, 161, 255, 0.5); +} + +html[data-theme="dark"] .password-toggle { + color: #ccc; +} + +html[data-theme="dark"] .divider::before, +html[data-theme="dark"] .divider::after { + border-color: #444; +} + +/* Buttons */ +html[data-theme="dark"] #loginButton, +html[data-theme="dark"] #signupButton { + background: linear-gradient(45deg, #70a1ff, #bb86fc); + box-shadow: 0 8px 25px rgba(187, 134, 252, 0.4); +} + +html[data-theme="dark"] #loginButton:hover, +html[data-theme="dark"] #signupButton:hover { + box-shadow: 0 12px 35px rgba(187, 134, 252, 0.5); +} + +html[data-theme="dark"] .google-btn { + background: #2c2c2c; + color: #f0f0f0; + border-color: #555; +} + +html[data-theme="dark"] .auth-link { + color: #70a1ff; +} + +/* -------------------------------------- */ +/* 13. Responsive Media Queries */ +/* -------------------------------------- */ + +/* Tablet Screens */ +@media (max-width: 768px) { + .nav-links { + display: none; /* Hiding full nav menu on mobile */ + } + + .auth-card { + padding: 2rem; + } + + .auth-title { + font-size: 2rem; + } +} + +/* Mobile Screens */ +@media (max-width: 480px) { + .navbar { + padding: 10px 15px; + } + + .navbar-container { + flex-direction: column; + gap: 1rem; + } + + .nav-links { + order: 2; + gap: 1rem; + flex-wrap: wrap; + justify-content: center; + } + + .nav-right { + order: 3; + justify-content: center; + gap: 0.5rem; + } + + .auth-card { + padding: 1.5rem; + border-radius: 20px; + } + + .form-input { + padding: 0.8rem 1rem; + } + + .auth-button { + padding: 1rem; + font-size: 1.1rem; + } + + .auth-footer p { + font-size: 0.9rem; /* Slightly smaller text on mobile */ + } +} diff --git a/BakeGenuis-AI/css/convert.css b/BakeGenuis-AI/css/convert.css new file mode 100644 index 00000000..fa17eda0 --- /dev/null +++ b/BakeGenuis-AI/css/convert.css @@ -0,0 +1,915 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + } + + :root { + --candy-red: #FF4757; + --sky-blue: #70A1FF; + --dark-gray: #3a3a3a; + --sunny-yellow: #FFA502; + --white: #FFFFFF; + --light-pink: #FFE0E6; + --light-blue: #E8F4FF; + --light-yellow: #FFF5E0; + --mint-green: #98ff98; + --sky-blue: #87ceeb; + --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + } +/* === Dark Theme Overrides for About Us === */ +[data-theme="dark"] body { + background: linear-gradient(135deg, #121212 0%, #1f1f1f 50%, #2a2a2a 100%) !important; + color: #eee; + --navbar-gradient: linear-gradient(90deg, #222222, #111111, #333333); +} + +[data-theme="dark"] .hero-title, +[data-theme="dark"] .hero-subtitle, +[data-theme="dark"] .section-title, +[data-theme="dark"] .creator-name, +[data-theme="dark"] .creator-title, +[data-theme="dark"] .xyz { + color: #fff !important; +} + +[data-theme="dark"] .section-card, +[data-theme="dark"] .creator-section, +[data-theme="dark"] .contributors, +[data-theme="dark"] .step-card { + background: rgba(30, 30, 30, 0.85) !important; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 10px 30px rgba(0,0,0,0.7); + color: #f0f0f0; +} + +[data-theme="dark"] .section-content, +[data-theme="dark"] .step-title, +[data-theme="dark"] .step-description, +[data-theme="dark"] .problem-item, +[data-theme="dark"] .creator-title { + color: #ccc; +} + +[data-theme="dark"] .cta-btn, +[data-theme="dark"] .social-link, +[data-theme="dark"] .scale-nav-btn { + background: linear-gradient(45deg, #bb86fc, #03dac6) !important; + color: #fff !important; + box-shadow: 0 8px 25px rgba(187,134,252,0.3) !important; +} + +[data-theme="dark"] .social-link:hover, +[data-theme="dark"] .cta-btn:hover { + transform: scale(1.05); + box-shadow: 0 10px 30px rgba(187,134,252,0.5); +} + +[data-theme="dark"] .navbar { + background: var(--navbar-gradient); + box-shadow: 0 4px 20px rgba(187,134,252,0.4); + border-bottom: 1px solid rgba(187,134,252,0.2); +} + +[data-theme="dark"] .nav-links li a { + color: var(--link-color) !important; + text-shadow: 0 0 8px rgba(187,134,252,0.5); +} + +[data-theme="dark"] .nav-links li a:hover { + transform: translateY(-2px); + text-shadow: 0 0 12px rgba(187,134,252,0.8); +} + +[data-theme="dark"] .footer { + background: var(--footer-bg) !important; + color: var(--footer-text) !important; + box-shadow: 0 0 30px rgba(255,255,255,0.05); +} + +[data-theme="dark"] .footer-links ul li a, +[data-theme="dark"] .footer-text { + color: #e0e0e0 !important; +} +[data-theme="dark"] .footer-links ul li a:hover { + color: #ff7f50 !important; +} + +[data-theme="dark"] .contributor-card { + background: rgba(40, 40, 40, 0.85); + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 8px 20px rgba(0,0,0,0.7); +} + +[data-theme="dark"] .creator-avatar { + background: linear-gradient(135deg, #bb86fc, #03dac6); +} + +[data-theme="dark"] .creator-avatar::before { + background: linear-gradient(135deg, #03dac6, #bb86fc, #3700b3); +} + +[data-theme="dark"] .problem-item { + background: rgba(187,134,252,0.1); + border-left: 4px solid #bb86fc; +} + + +[data-theme="dark"] .step-card { + background: rgba(30,30,30,0.7); + border: 1px solid rgba(255,255,255,0.1); +} + body { + font-family: 'Comic Neue', cursive; + background: linear-gradient(135deg, var(--light-pink) 0%, var(--light-blue) 30%, var(--light-yellow) 60%, var(--light-pink) 100%); + min-height: 100vh; + position: relative; + overflow-x: hidden; + line-height: 1.6; + } + /* Dark-Light Toggle Slider */ +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} +/*-candy-red: #FF4757; + --sky-blue: #70A1FF; + --dark-gray: #3a3a3a; + --sunny-yellow: #FFA502; + --white: #FFFFFF; + --light-pink: #FFE0E6; + --light-blue: #E8F4FF; + --light-yellow: #FFF5E0; + --mint-green: #98ff98; + --sky-blue: #87ceeb; + --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);*/ +.slider { + position: absolute; + cursor: pointer; + top: 0; left: 0; right: 0; bottom: 0; + background: white; + border-radius: 34px; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + font-size: 12px; + color: #fff; +} + +.slider:before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +/* When checked (dark mode) */ +.theme-switch input:checked + .slider { + background: linear-gradient(45deg, #bf60fa, #fde68a); +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} + /* Advanced Animated Background */ + .animated-bg { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + overflow: hidden; + } + + .floating-element { + position: absolute; + animation: floatAdvanced 8s ease-in-out infinite; + opacity: 0.7; + } + + .floating-element:nth-child(1) { top: 10%; left: 5%; font-size: 3rem; animation-delay: 0s; } + .floating-element:nth-child(2) { top: 20%; right: 10%; font-size: 2.5rem; animation-delay: 2s; } + .floating-element:nth-child(3) { bottom: 30%; left: 15%; font-size: 2rem; animation-delay: 4s; } + .floating-element:nth-child(4) { bottom: 20%; right: 20%; font-size: 2.8rem; animation-delay: 1s; } + .floating-element:nth-child(5) { top: 50%; left: 80%; font-size: 2.2rem; animation-delay: 3s; } + .floating-element:nth-child(6) { top: 70%; left: 10%; font-size: 1.8rem; animation-delay: 5s; } + + @keyframes floatAdvanced { + 0%, 100% { + transform: translateY(0px) translateX(0px) rotate(0deg) scale(1); + opacity: 0.7; + } + 25% { + transform: translateY(-30px) translateX(20px) rotate(5deg) scale(1.1); + opacity: 0.9; + } + 50% { + transform: translateY(-60px) translateX(-10px) rotate(-3deg) scale(0.9); + opacity: 0.6; + } + 75% { + transform: translateY(-20px) translateX(15px) rotate(8deg) scale(1.05); + opacity: 0.8; + } + } + + /* Sparkle Effect */ + .sparkles { + position: absolute; + width: 100%; + height: 100%; + } + + .sparkle { + position: absolute; + width: 4px; + height: 4px; + background: var(--sunny-yellow); + border-radius: 50%; + animation: sparkle 3s linear infinite; + } + + @keyframes sparkle { + 0% { opacity: 0; transform: scale(0); } + 50% { opacity: 1; transform: scale(1); } + 100% { opacity: 0; transform: scale(0); } + } + + /* Navigation Bar */ + /* Navbar Base */ +.navbar { + width: 100%; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); /* light blue โ†’ light pink โ†’ soft yellow */ + padding: 0.75rem 1.25rem; + position: sticky; + top: 0; + z-index: 1000; + box-shadow: 0 4px 15px rgba(0,0,0,0.08); +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; +} + +/* Logo */ +.logo { + font-size: 1.5rem; + font-weight: bold; + color: #ffffff; + letter-spacing: 1px; +} + +.logo a{ + text-decoration: none; + color: #fff; +} + +/* Nav Links */ +.nav-links { + display: flex; + list-style: none; + gap: 1.5rem; +} + +.nav-links li a { + color: #ffffff; + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 0.3rem 0; +} + +/* Hover Gradient Underline */ +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after, +.nav-links li a.active::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} +.fb-color { + padding: 0.5rem 0.9rem; + background: linear-gradient(45deg, #60a5fa, #fde68a); + border-radius: 1.25rem; + border: none; + } + .fb-color:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} + .fb-color a { + color: white; + text-decoration: none; + } +/* CTA Button */ +.cta-btn { + padding: 0.625rem 1.25rem; + background: linear-gradient(45deg, #60a5fa, #f9a8d4, #fde68a); + color: #ffffff; + font-weight: bold; + text-decoration: none; + border-radius: 1.875rem; + transition: all 0.4s ease; + box-shadow: 0 4px 12px rgba(0,0,0,0.12); +} + +.cta-btn:hover { + transform: scale(1.08); + box-shadow: 0 6px 20px rgba(0,0,0,0.2); +} + +/* Scale Now Navigation Button */ +.scale-nav-btn { + background: linear-gradient(45deg, #60a5fa, #fde68a) !important; + color: #ffffff !important; + padding: 8px 16px !important; + border-radius: 20px !important; + font-weight: 600 !important; + text-decoration: none !important; + transition: all 0.3s ease !important; + box-shadow: 0 2px 8px rgba(96, 165, 250, 0.3) !important; + display: inline-block !important; +} + +.scale-nav-btn:hover { + transform: translateY(-2px) scale(1.05) !important; + box-shadow: 0 4px 12px rgba(96, 165, 250, 0.4) !important; +} + +.scale-nav-btn::after { + display: none !important; +} + +/* User Info Display */ +.user-info { + display: flex; + align-items: center; + gap: 1rem; + color: #ffffff; + font-weight: 600; +} + +.user-avatar { + width: 40px; + height: 40px; + background: linear-gradient(45deg, #c270f6, #747061); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + color: white; +} + +.logout-btn { + background: linear-gradient(90deg, #ff5f6d, #c31432); + color: #ffffff; + border: none !important; + padding: 0.5rem 1rem; + border-radius: 20px; + font-family: 'Comic Neue', cursive; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + font-size: 0.9rem; + box-shadow: 0 2px 8px rgba(255, 71, 87, 0.3) !important; +} + +.logout-btn:hover { + background: linear-gradient(45deg, #ff3838, #ff2d2d) !important; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 71, 87, 0.4) !important; +} + + /* Main Content */ + main { + padding: 2rem 2rem; + max-width: 1200px; + margin: 0 auto; + } + + .page-header { + text-align: center; + margin-bottom: 3rem; + } + + .page-title { + display: inline-block; + font-size: clamp(2rem, 6vw, 3rem); + font-weight: 700; + margin-bottom: 1rem; + background: linear-gradient(0deg, var(--dark-gray), var(--sunny-yellow)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + } + + .page-subtitle { + font-size: 1.2rem; + opacity: 0.9; + margin-bottom: 2rem; + } + + .converter-container { + display: grid; + grid-template-columns: 1fr; + gap: 2rem; + max-width: 800px; + margin: 0 auto; + } + + .input-section { + background: rgba(151, 146, 146, 0.1); + backdrop-filter: blur(20px); + border-radius: 20px; + padding: 2rem; + border: 1px solid rgba(255, 255, 255, 0.2); + } + + .input-group { + margin-bottom: 1.5rem; + } + + .input-label { + display: block; + font-size: 1.1rem; + font-weight: 600; + margin-bottom: 0.5rem; + } + + .recipe-input { + width: 100%; + min-height: 200px; + padding: 1rem; + border: none; + border-radius: 15px; + background: rgba(197, 197, 197, 0.1); + backdrop-filter: blur(10px); + font-family: 'Comic Neue', cursive; + font-size: 1rem; + resize: vertical; + border: 2px solid transparent; + transition: all 0.3s ease; + } + + .recipe-input:focus { + outline: none; + border-color: var(--light-yellow); + box-shadow: 0 0 20px rgba(255, 231, 195, 0.3); + } + + .recipe-input::placeholder { + color:var(--light-gray); + } + + .file-upload { + display: none; + } + + .file-upload-label { + display: inline-block; + padding: 1rem 2rem; + background: linear-gradient(45deg, var(--mint-green), var(--sky-blue)); + color: var(--white); + border-radius: 25px; + cursor: pointer; + transition: all 0.3s ease; + font-weight: 600; + margin-right: 1rem; + } + + .file-upload-label:hover { + transform: translateY(-2px); + box-shadow: var(--shadow); + } + + .convert-button { + width: 100%; + padding: 1.5rem; + background: linear-gradient(45deg, var(--candy-red), var(--sunny-yellow)); + color: var(--white); + border: none; + border-radius: 25px; + font-size: 1.3rem; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + margin-top: 1rem; + } + + .convert-button:hover { + transform: translateY(-3px); + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2); + } + + .convert-button:disabled { + opacity: 0.6; + cursor: not-allowed; + transform: none; + } + + .loading-spinner { + display: none; + width: 20px; + height: 20px; + border: 2px solid transparent; + border-top: 2px solid var(--white); + border-radius: 50%; + animation: spin 1s linear infinite; + margin-right: 10px; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .results-section { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(20px); + border-radius: 20px; + padding: 2rem; + border: 1px solid rgba(255, 255, 255, 0.2); + display: none; + } + + .results-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 2rem; + } + + .results-title { + font-size: 1.5rem; + font-weight: 700; + } + + .unit-toggle { + display: flex; + background: rgba(255, 255, 255, 0.1); + border-radius: 25px; + padding: 0.2rem; + } + + .unit-toggle button { + padding: 0.5rem 1rem; + border: none; + background: transparent; + color: var(--white); + border-radius: 20px; + cursor: pointer; + transition: all 0.3s ease; + font-family: 'Comic Neue', cursive; + font-weight: 600; + } + + .unit-toggle button.active { + background: var(--sunny-yellow); + color: var(--dark-gray); + } + + .results-table { + width: 100%; + border-collapse: collapse; + margin-top: 1rem; + } + + .results-table th, + .results-table td { + padding: 1rem; + text-align: left; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + } + + .results-table th { + background: rgba(255, 255, 255, 0.1); + font-weight: 700; + color: var(--sunny-yellow); + } + + .ingredient-row { + transition: all 0.3s ease; + } + + .ingredient-row:hover { + background: rgba(255, 255, 255, 0.05); + } + + .ingredient-icon { + font-size: 1.5rem; + margin-right: 0.5rem; + } + + .tooltip { + position: relative; + cursor: help; + } + + .tooltip::after { + content: attr(data-tooltip); + position: absolute; + bottom: 125%; + left: 50%; + transform: translateX(-50%); + background: var(--dark-gray); + color: var(--white); + padding: 0.5rem; + border-radius: 8px; + font-size: 0.8rem; + white-space: nowrap; + opacity: 0; + pointer-events: none; + transition: opacity 0.3s; + z-index: 1001; + } + + .tooltip:hover::after { + opacity: 1; + } + + .warning-popup { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(255, 71, 87, 0.95); + backdrop-filter: blur(20px); + padding: 2rem; + border-radius: 20px; + border: 2px solid var(--candy-red); + z-index: 1002; + display: none; + max-width: 400px; + text-align: center; + } + + .warning-popup h3 { + margin-bottom: 1rem; + font-size: 1.3rem; + } + + .warning-popup button { + padding: 0.8rem 1.5rem; + background: var(--white); + color: var(--candy-red); + border: none; + border-radius: 15px; + font-weight: 600; + cursor: pointer; + margin: 0.5rem; + transition: all 0.3s ease; + } + + .warning-popup button:hover { + transform: translateY(-2px); + } + + .overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(5px); + z-index: 1001; + display: none; + } + + /* Responsive Design */ + @media (max-width: 768px) { + .navbar { + padding: 10px 15px; + } + + .nav-links { + display: none; + position: absolute; + top: 100%; + left: 0; + right: 0; + background: rgba(0, 0, 0, 0.9); + flex-direction: column; + padding: 2rem; + gap: 1rem; + z-index: 999; + } + + .nav-links.active { + display: flex; + } + + .mobile-menu { + display: flex; + } + + main { + padding: 5rem 1rem 2rem; + } + + .results-table { + font-size: 0.9rem; + } + + .results-table th, + .results-table td { + padding: 0.5rem; + } + + .file-upload-label { + display: block; + text-align: center; + margin-bottom: 1rem; + margin-right: 0; + } + } + + @media (max-width: 480px) { + nav { + padding: 1rem; + } + + .input-section, + .results-section { + padding: 1.5rem; + } + + .warning-popup { + margin: 1rem; + max-width: calc(100% - 2rem); + } + } + + +.footer { + background-color: #FFB6C1; + color: #fff; + padding: 40px 20px; + font-family: sans-serif; +} + +.footer-container { + max-width: 1200px; + margin: auto; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 30px; +} + +.footer h2 { + color: #ff7f50; +} + +.footer h3 { + margin-bottom: 10px; + color: #ff7f50; +} + +.footer p { + font-size: 14px; + line-height: 1.5; +} + +.footer-links ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-links ul li { + margin-bottom: 6px; +} + +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: color 0.3s; +} + +.footer-links ul li a:hover { + color: #ff7f50; +} + +.footer-newsletter input { + padding: 10px; + width: 100%; + margin-bottom: 10px; + border: none; + border-radius: 4px; +} + +.footer-newsletter button { + background-color: #ff7f50; + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background 0.3s; +} + +.footer-newsletter button:hover { + background-color: #ff956b; +} + +/* Social icons */ +.social-icons { + display: flex; + gap: 12px; + margin-top: 10px; +} + +.social-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + color: white; + font-size: 18px; + transition: transform 0.3s, opacity 0.3s; +} + +.social-icon:hover { + transform: scale(1.1); + opacity: 0.85; +} + +/* Specific brand colors */ +.social-icon.linkedin { background: #0077b5; } +.social-icon.github { background: #6e5494; } +.social-icon.email { background: #ff8800; } + +.footer-bottom { + text-align: center; + font-size: 14px; + margin-top: 30px; + border-top: 1px solid #333; + padding-top: 20px; +} + +/* Back to Top Button */ +#scrollTopBtn { + display: none; + position: fixed; + bottom: 30px; + right: 30px; + z-index: 99; + font-size: 30px; + border: none; + outline: none; + background: linear-gradient(45deg, #ff6ec7, #ffa07a, #87cefa); + color: black; + cursor: pointer; + padding: 7px 15px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + transition: all 0.3s ease; +} + +#scrollTopBtn:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(0,0,0,0.3); +} diff --git a/BakeGenuis-AI/css/customize.css b/BakeGenuis-AI/css/customize.css new file mode 100644 index 00000000..eb8232ab --- /dev/null +++ b/BakeGenuis-AI/css/customize.css @@ -0,0 +1,998 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + } + + :root { + --candy-red: #FF4757; + --sky-blue: #70A1FF; + --sunny-yellow: #FFA502; + --white: #FFFFFF; + --light-pink: #FFE0E6; + --light-blue: #E8F4FF; + --light-yellow: #FFF5E0; + } + + body { + font-family: 'Comic Neue', cursive; + background: linear-gradient(135deg, var(--light-pink) 0%, var(--light-blue) 50%, var(--light-yellow) 100%); + min-height: 100vh; + position: relative; + overflow-x: hidden; + } + +/* ===================== Dark Theme ===================== */ +[data-theme="dark"] { + --bg-color: #121212; + --text-color: #ffffff; + --card-bg: rgba(30, 30, 30, 0.85); + --card-glow: rgba(187,134,252,0.2); + --cta-gradient: linear-gradient(45deg, #bb86fc, #03dac6); + --navbar-bg: #1e1e1e; + --footer-bg: #1e1e1e; + --footer-heading: #ff7f50; +} + +/* ===================== Body ===================== */ +[data-theme="dark"] body { + background: var(--bg-color); + color: var(--text-color); + transition: all 0.3s ease; +} + +/* ===================== Navbar ===================== */ +[data-theme="dark"] .navbar { + background: var(--navbar-bg); + box-shadow: 0 4px 15px rgba(0,0,0,0.5); +} + +[data-theme="dark"] .nav-links li a { + color: #ffffff; +} + +[data-theme="dark"] .nav-links li a::after { + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); /* same as light mode */ +} + +/* ===================== Cards ===================== */ +[data-theme="dark"] .ingredient-card, +[data-theme="dark"] .brand-selector, +[data-theme="dark"] .density-editor, +[data-theme="dark"] .container { + background: var(--card-bg); + color: #fff; + box-shadow: 0 15px 40px var(--card-glow), 0 0 15px rgba(187,134,252,0.1); + border-radius: 20px; + transition: all 0.3s ease; +} + +[data-theme="dark"] .ingredient-card:hover, +[data-theme="dark"] .brand-selector:hover { + background: rgba(40, 40, 40, 0.95); + box-shadow: 0 25px 60px var(--card-glow); +} + +[data-theme="dark"] .ingredient-card .ingredient-name, +[data-theme="dark"] .ingredient-card .ingredient-header, +[data-theme="dark"] .user-info { + color: #fff; +} +/* Page subtitle whitish gray */ +[data-theme="dark"] .page-subtitle { + color: #cccccc; +} + +/* Brand options text black */ +[data-theme="dark"] .brand-option { + color: #000000; +} +/* ===================== Forms ===================== */ +[data-theme="dark"] .custom-input, +[data-theme="dark"] .custom-select { + color: #ccc; + background: #2b2b2b; + border: 2px solid #444; +} + +/* ===================== Buttons ===================== */ +[data-theme="dark"] .btn-primary { background: #FF6B6B; } +[data-theme="dark"] .btn-secondary { background: #4ECDC4; } +[data-theme="dark"] .btn-success { background: #2ED573; } + +[data-theme="dark"] .cta-btn { + background: var(--cta-gradient); + color: #ffffff; + box-shadow: 0 10px 25px rgba(187,134,252,0.2); +} + +[data-theme="dark"] .cta-btn:hover { + transform: scale(1.05); + box-shadow: 0 15px 35px rgba(187,134,252,0.25); +} + +/* ===================== Footer ===================== */ +[data-theme="dark"] .footer { + background-color: var(--footer-bg); + color: #f5f5f5; +} + +[data-theme="dark"] .footer h2, +[data-theme="dark"] .footer h3 { + color: var(--footer-heading); +} + +[data-theme="dark"] .footer-links ul li a { + color: #f5f5f5; +} + +/* Social icons */ +[data-theme="dark"] .social-icon.linkedin { background: #0077b5; } +[data-theme="dark"] .social-icon.github { background: #6e5494; } +[data-theme="dark"] .social-icon.email { background: #ff8800; } + +/* ===================== Misc ===================== */ +[data-theme="dark"] .user-info { + color: #ffffff; +} + +[data-theme="dark"] .density-input { + border: 2px solid #c7e9c0; + background: #f0fff4; +} + +[data-theme="dark"] .density-input:focus { + border-color: #2ecc71; + background: #e9fdf0; +} + +/* Tooltips */ +[data-theme="dark"] .tooltip::after { + background: #333; + color: white; +} + +/* Theme switch slider */ +[data-theme="dark"] .theme-switch input:checked + .slider { + background: linear-gradient(45deg, #bf60fa, #fde68a); +} + +[data-theme="dark"] .theme-switch input:checked + .slider:before { + transform: translateX(24px); +} + /* Dark-Light Toggle Slider */ +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; left: 0; right: 0; bottom: 0; + background: linear-gradient(45deg, #6b7043, #fde68a); + border-radius: 34px; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + font-size: 12px; + color: #fff; +} + +.slider:before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +/* When checked (dark mode) */ +.theme-switch input:checked + .slider { +background: linear-gradient(45deg, #bf60fa, #fde68a); +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} + /* Animated Background Elements */ + .floating-elements { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + } + + .floating-cupcake { + position: absolute; + font-size: 2rem; + animation: float 6s ease-in-out infinite; + } + + .floating-cupcake:nth-child(1) { top: 10%; left: 10%; animation-delay: 0s; } + .floating-cupcake:nth-child(2) { top: 20%; right: 15%; animation-delay: 2s; } + .floating-cupcake:nth-child(3) { bottom: 20%; left: 20%; animation-delay: 4s; } + .floating-cupcake:nth-child(4) { bottom: 30%; right: 10%; animation-delay: 1s; } + + @keyframes float { + 0%, 100% { transform: translateY(0px) rotate(0deg); } + 50% { transform: translateY(-20px) rotate(5deg); } + } + + /* Navigation Bar */ + /* Navbar Base */ +.navbar { + width: 100%; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); /* light blue โ†’ light pink โ†’ soft yellow */ + padding: 0.75rem 1.25rem; + position: sticky; + top: 0; + z-index: 1000; + box-shadow: 0 4px 15px rgba(0,0,0,0.08); +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; +} + +/* Logo */ +.logo { + font-size: 1.5rem; + font-weight: bold; + color: #ffffff; + letter-spacing: 1px; +} + +.logo a{ + text-decoration: none; + color: #fff; +} + +/* Nav Links */ +.nav-links { + display: flex; + list-style: none; + gap: 1.5rem; +} + +.nav-links li a { + color: #ffffff; + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 0.3rem 0; +} + +/* Hover Gradient Underline */ +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after, +.nav-links li a.active::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} + +.fb-color { + padding: 0.5rem 0.9rem; + background: linear-gradient(45deg, #60a5fa, #fde68a); + border-radius: 1.25rem; + border: none; +} +.fb-color:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} +.fb-color a { + color: white; + text-decoration: none; +} + +/* CTA Button */ +.cta-btn { + padding: 0.625rem 1.25rem; + background: linear-gradient(45deg, #60a5fa, #f9a8d4, #fde68a); + color: #ffffff; + font-weight: bold; + text-decoration: none; + border-radius: 1.875rem; + transition: all 0.4s ease; + box-shadow: 0 4px 12px rgba(0,0,0,0.12); +} + +.cta-btn:hover { + transform: scale(1.08); + box-shadow: 0 6px 20px rgba(0,0,0,0.2); +} + +/* Scale Now Navigation Button */ +.scale-nav-btn { + background: linear-gradient(45deg, #60a5fa, #fde68a) !important; + color: #ffffff !important; + padding: 0.5rem 1rem !important; + border-radius: 1.25rem !important; + font-weight: 600 !important; + text-decoration: none !important; + transition: all 0.3s ease !important; + box-shadow: 0 2px 8px rgba(96, 165, 250, 0.3) !important; + display: inline-block !important; +} + +.scale-nav-btn:hover { + transform: translateY(-2px) scale(1.05) !important; + box-shadow: 0 4px 12px rgba(96, 165, 250, 0.4) !important; +} + +.scale-nav-btn::after { + display: none !important; +} + +/* User Info Display */ +.user-info { + display: flex; + align-items: center; + gap: 1rem; + color: #ffffff; + font-weight: 600; +} + +.user-avatar { + width: 2.5rem; + height: 2.5rem; + background: linear-gradient(45deg, #c270f6, #747061); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + color: white; +} + +.logout-btn { + background: linear-gradient(90deg, #ff5f6d, #c31432); + color: #ffffff; + border: none !important; + padding: 0.5rem 1rem; + border-radius: 20px; + font-family: 'Comic Neue', cursive; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + font-size: 0.9rem; + box-shadow: 0 2px 8px rgba(255, 71, 87, 0.3) !important; +} + +.logout-btn:hover { + background: linear-gradient(45deg, #ff3838, #ff2d2d) !important; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 71, 87, 0.4) !important; +} + + /* Main Container */ + .container { + max-width: 1000px; + margin: 1rem auto 2rem; + padding: 0 1rem; + position: relative; + z-index: 10; + } + + .page-header { + text-align: center; + margin-bottom: 3rem; + } + + .page-title { + font-size: 3rem; + color: var(--candy-red); + margin-bottom: 1rem; + text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.1); + animation: bounce 2s ease-in-out infinite; + } + + .page-subtitle { + font-size: 1.2rem; + color: #666; + max-width: 600px; + margin: 0 auto; + } + + @keyframes bounce { + 0%, 20%, 50%, 80%, 100% { transform: translateY(0); } + 40% { transform: translateY(-10px); } + 60% { transform: translateY(-5px); } + } + + /* Ingredient Cards */ + .ingredients-container { + display: grid; + gap: 1.5rem; + margin-bottom: 2rem; + } + + .ingredient-card { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 1.5rem; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + border: 2px solid transparent; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + } + + .ingredient-card::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent); + transition: left 0.5s ease; + } + + .ingredient-card:hover { + transform: translateY(-5px); + border-color: var(--sky-blue); + box-shadow: 0 12px 40px rgba(112, 161, 255, 0.2); + } + + .ingredient-card:hover::before { + left: 100%; + } + + .ingredient-header { + display: flex; + align-items: center; + margin-bottom: 1rem; + } + + .ingredient-icon { + font-size: 2rem; + margin-right: 1rem; + } + + .ingredient-name { + font-size: 1.3rem; + font-weight: 700; + color: #333; + flex: 1; + } + + .ingredient-controls { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + align-items: end; + } + + .control-group { + display: flex; + flex-direction: column; + } + + .control-label { + font-size: 0.9rem; + font-weight: 600; + color: #666; + margin-bottom: 0.5rem; + } + + .custom-select, .custom-input { + padding: 0.75rem; + border: 2px solid #e0e0e0; + border-radius: 12px; + font-family: 'Comic Neue', cursive; + font-size: 1rem; + background: white; + transition: all 0.3s ease; + } + + .custom-select:focus, .custom-input:focus { + outline: none; + border-color: var(--sky-blue); + box-shadow: 0 0 0 3px rgba(112, 161, 255, 0.2); + } + + .custom-input[type="number"] { + text-align: center; + font-weight: 600; + } + + /* Brand Selector */ + .brand-selector { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 1.5rem; + margin-bottom: 2rem; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + } + + .brand-title { + font-size: 1.5rem; + font-weight: 700; + color: var(--candy-red); + margin-bottom: 1rem; + text-align: center; + } + + .brand-options { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1rem; + } + + .brand-option { + background: white; + border: 2px solid #e0e0e0; + border-radius: 12px; + padding: 1rem; + text-align: center; + cursor: pointer; + transition: all 0.3s ease; + font-weight: 600; + } + + .brand-option:hover { + border-color: var(--sunny-yellow); + background: var(--light-yellow); + transform: scale(1.05); + } + + .brand-option.selected { + border-color: var(--sky-blue); + background: var(--light-blue); + } + + /* Action Buttons */ + .action-buttons { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; + } + + .btn { + padding: 1rem 2rem; + border: none; + border-radius: 25px; + font-family: 'Comic Neue', cursive; + font-size: 1.1rem; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 0.5rem; + position: relative; + overflow: hidden; + } + + .btn-primary { + background: var(--candy-red); + color: white; + box-shadow: 0 4px 15px rgba(255, 71, 87, 0.4); + } + + .btn-secondary { + background: var(--sky-blue); + color: white; + box-shadow: 0 4px 15px rgba(112, 161, 255, 0.4); + } + + .btn-success { + background: #2ED573; + color: white; + box-shadow: 0 4px 15px rgba(46, 213, 115, 0.4); + } + + .btn:hover { + transform: translateY(-3px); + animation: wobble 0.5s ease-in-out; + } + + @keyframes wobble { + 0% { transform: translateY(-3px) rotate(0deg); } + 25% { transform: translateY(-3px) rotate(1deg); } + 75% { transform: translateY(-3px) rotate(-1deg); } + 100% { transform: translateY(-3px) rotate(0deg); } + } + + /* Mobile Responsive */ + @media (max-width: 768px) { + .navbar { + padding: 10px 15px; + } + + .nav-links { + display: none; + } + + .page-title { + font-size: 2rem; + } + + .ingredient-controls { + grid-template-columns: 1fr; + gap: 1rem; + } + + .brand-options { + grid-template-columns: 1fr; + } + + .action-buttons { + flex-direction: column; + align-items: center; + } + + .btn { + width: 100%; + max-width: 300px; + justify-content: center; + } + } + /* NEW: Density Input Styles */ + .density-input { + border: 2px solid #c7e9c0; + background: #f0fff4; + } + .density-input:focus { + border-color: #2ecc71; + background: #e9fdf0; + } + + + /* Success Message */ +.success-message { + background: #e9fdf0; + border: 2px solid #2ED573; + border-radius: 10px; + padding: 0.6rem 1rem; + margin: 1rem auto; + max-width: 400px; + text-align: center; + color: #2ED573; + font-weight: 600; + font-size: 0.95rem; + display: none; + box-shadow: 0 4px 12px rgba(46, 213, 115, 0.2); + animation: fadeInUp 0.5s ease-out; +} + +/* Animation for showing success */ +@keyframes fadeInUp { + 0% { + opacity: 0; + transform: translateY(15px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} +/* Density Editor Hover Effect */ +.density-editor { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 1.5rem; + margin-bottom: 2rem; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + border: 2px solid transparent; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.density-editor::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent); + transition: left 0.5s ease; +} + +.density-editor:hover { + transform: translateY(-5px); + border-color: var(--sky-blue); + box-shadow: 0 12px 40px rgba(112, 161, 255, 0.2); +} + +.density-editor:hover::before { + left: 100%; +} + +/* Density List (added densities) */ +#densityList { + margin-top: 1rem; + list-style: none; + padding: 0; + display: flex; + flex-wrap: wrap; + gap: 0.6rem; + justify-content: center; +} + +#densityList li { + background: #f8faff; + border: 1px solid #d6e4ff; + border-radius: 20px; + padding: 0.4rem 0.8rem; + font-size: 0.9rem; + font-weight: 600; + color: #3a6ff7; + box-shadow: 0 2px 6px rgba(58, 111, 247, 0.15); + transition: transform 0.2s ease; +} + +#densityList li:hover { + transform: scale(1.05); +} +/* Density Editor */ +.density-editor { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 1.5rem; + margin-bottom: 2rem; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); +} + +.density-editor h2 { + text-align: center; + color: var(--candy-red); + margin-bottom: 1rem; +} + +/* Form styling */ +#densityForm { + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: center; + margin-bottom: 1.5rem; +} + +#densityForm input { + flex: 1; + min-width: 200px; + padding: 0.75rem; + border: 2px solid #e0e0e0; + border-radius: 12px; + font-family: 'Comic Neue', cursive; + font-size: 1rem; + transition: all 0.3s ease; +} + +#densityForm input:focus { + border-color: var(--sky-blue); + box-shadow: 0 0 0 3px rgba(112, 161, 255, 0.2); +} + +#densityForm button { + padding: 0.75rem 1.5rem; + border-radius: 12px; + font-family: 'Comic Neue', cursive; + font-size: 1rem; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; +} + +/* Make it mobile friendly */ +@media (max-width: 768px) { + #densityForm { + flex-direction: column; + align-items: center; + } + + #densityForm input, + #densityForm button { + width: 100%; + max-width: 300px; + } +} + @keyframes slideDown { + from { transform: translateY(-20px); opacity: 0; } + to { transform: translateY(0); opacity: 1; } + } + + /* Tooltip */ + .tooltip { + position: relative; + cursor: help; + } + + .tooltip::after { + content: attr(data-tooltip); + position: absolute; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + background: #333; + color: white; + padding: 0.5rem; + border-radius: 8px; + font-size: 0.8rem; + white-space: nowrap; + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + z-index: 1000; + } + + .tooltip:hover::after { + opacity: 1; + visibility: visible; + } + + +.footer { + background-color:#FFB6C1; + color: #fff; + padding: 40px 20px; + font-family: sans-serif; +} + +.footer-container { + max-width: 1200px; + margin: auto; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 30px; +} + +.footer h2 { + color: #ff7f50; +} + +.footer h3 { + margin-bottom: 10px; + color: #ff7f50; +} + +.footer p { + font-size: 14px; + line-height: 1.5; +} + +.footer-links ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-links ul li { + margin-bottom: 6px; +} + +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: color 0.3s; +} + +.footer-links ul li a:hover { + color: #ff7f50; +} + +.footer-newsletter input { + padding: 10px; + width: 100%; + margin-bottom: 10px; + border: none; + border-radius: 4px; +} + +.footer-newsletter button { + background-color: #ff7f50; + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background 0.3s; +} + +.footer-newsletter button:hover { + background-color: #ff956b; +} + +/* Social icons */ +.social-icons { + display: flex; + gap: 12px; + margin-top: 10px; +} + +.social-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + color: white; + font-size: 18px; + transition: transform 0.3s, opacity 0.3s; +} + +.social-icon:hover { + transform: scale(1.1); + opacity: 0.85; +} + +/* Specific brand colors */ +.social-icon.linkedin { background: #0077b5; } +.social-icon.github { background: #6e5494; } +.social-icon.email { background: #ff8800; } + +.footer-bottom { + text-align: center; + font-size: 14px; + margin-top: 30px; + border-top: 1px solid #333; + padding-top: 20px; +} + +/* Back to Top Button */ +#scrollTopBtn { + display: none; + position: fixed; + bottom: 30px; + right: 30px; + z-index: 99; + font-size: 30px; + border: none; + outline: none; + background: linear-gradient(45deg, #ff6ec7, #ffa07a, #87cefa); + color: black; + cursor: pointer; + padding: 7px 15px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + transition: all 0.3s ease; +} + +#scrollTopBtn:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(0,0,0,0.3); +} diff --git a/BakeGenuis-AI/css/feature.css b/BakeGenuis-AI/css/feature.css new file mode 100644 index 00000000..1169a1aa --- /dev/null +++ b/BakeGenuis-AI/css/feature.css @@ -0,0 +1,48 @@ +/* Custom Scrollbar */ +::-webkit-scrollbar { + width: 12px; +} + +::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.1); +} + +::-webkit-scrollbar-thumb { + background: linear-gradient(135deg, var(--candy-red), var(--sky-blue)); + border-radius: 6px; +} + +::-webkit-scrollbar-thumb:hover { + background: linear-gradient(135deg, var(--sky-blue), var(--sunny-yellow)); +} + +/* footer logo */ +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: all 0.3s ease; + display: inline-block; + font-weight: 500; +} + +.footer-links ul li a:hover { + color: #ff7f50; + transform: translateX(5px); +} +.footer-icon { + font-size: 1rem; + color: #ff7f50; + margin-right: 6px; + transition: transform 0.3s ease, color 0.3s ease; + vertical-align: middle; /* Align nicely with text */ +} +/* Hover effect */ +.footer-links ul li a:hover i { + color: #ff6b6b; /* Cyan on hover */ + transform: scale(1.2); /* Grow icon slightly */ +} + +/* Optional glowing effect on hover */ +.footer-icon:hover { + text-shadow: 0 0 8px rgba(0, 255, 255, 0.6); +} diff --git a/BakeGenuis-AI/css/feedback.css b/BakeGenuis-AI/css/feedback.css new file mode 100644 index 00000000..0e4b0d0c --- /dev/null +++ b/BakeGenuis-AI/css/feedback.css @@ -0,0 +1,1146 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --candy-red: #ff4757; + --sky-blue: #70a1ff; + --sunny-yellow: #ffa502; + --white: #ffffff; + --light-pink: #ffe0e6; + --light-blue: #e8f4ff; + --light-yellow: #fff5e0; + --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + --success-green: #2ed573; +} +/* Dark Mode Overrides */ +[data-theme="dark"] { + --bg-color: #121212; + --text-color: #ffffff; + --card-bg: rgba(30, 30, 30, 0.9); + --card-border: rgba(255, 255, 255, 0.1); + --input-bg: rgba(50, 50, 50, 0.8); + --input-border: rgba(255, 255, 255, 0.2); + --input-placeholder: rgba(200, 200, 200, 0.6); + --section-title: #bb86fc; + --section-text: #e0e0e0; + --btn-gradient: linear-gradient(45deg, #bb86fc, #03dac6); + --btn-text: #000; + --navbar-gradient: linear-gradient(90deg, #222, #111, #333); + --footer-bg: #1a1a1a; + --footer-text: #e0e0e0; +} + +/* Body background gradient */ +[data-theme="dark"] body { + background: linear-gradient(135deg, #121212 0%, #1f1f1f 50%, #2a2a2a 100%); + color: var(--text-color); +} + +/* Navbar Glow & Gradient Magic */ +[data-theme="dark"] .navbar { + background: var(--navbar-gradient); + box-shadow: 0 4px 20px rgba(187, 134, 252, 0.4); + border-bottom: 1px solid rgba(187, 134, 252, 0.2); +} + +[data-theme="dark"] .nav-links li a { + color: var(--link-color) !important; + text-shadow: 0 0 8px rgba(187, 134, 252, 0.5); +} + +[data-theme="dark"] .nav-links li a:hover { + transform: translateY(-2px); + text-shadow: 0 0 12px rgba(187, 134, 252, 0.8); +} + +/* Hero Section */ +[data-theme="dark"] .hero-title, +[data-theme="dark"] .hero-subtitle { + color: #ffffff !important; +} + +[data-theme="dark"] #feedbackFormSection { + box-shadow: 0 15px 40px rgba(187, 134, 252, 0.4), + 0 0 15px rgba(187, 134, 252, 0.2); + border: 1px solid rgba(187, 134, 252, 0.3); +} +/* Section Cards */ +[data-theme="dark"] .section-card { + background: var(--card-bg) !important; + border: 1px solid var(--card-border); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); +} + +[data-theme="dark"] .section-title { + color: var(--section-title) !important; +} + +[data-theme="dark"] .section-content, +[data-theme="dark"] .feedback-message { + color: var(--section-text) !important; +} + +/* Feedback Form */ +[data-theme="dark"] .form-label { + color: #e0e0e0; +} +/* Dark Mode Inputs */ +[data-theme="dark"] .form-input, +[data-theme="dark"] .form-textarea [data-theme="dark"] #feedbackRating { + background: rgba(40, 40, 40, 0.9); /* toned down dark bg */ + color: #ffffff; /* text visible */ + border: 1px solid rgba(255, 255, 255, 0.2); /* subtle border */ +} + +[data-theme="dark"] .form-input:focus, +[data-theme="dark"] .form-textarea:focus { + background: rgba(50, 50, 50, 0.95); + border-color: #bb86fc; /* accent on focus */ + box-shadow: 0 0 8px rgba(187, 134, 252, 0.3); + outline: none; +} +/* Dark Mode Feedback Rating Dropdown */ +[data-theme="dark"] #feedbackRating { + background: rgba(50, 50, 50, 0.9); /* darker, not blinding */ + color: #ffffff; /* text visible */ + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: none; +} + +[data-theme="dark"] #feedbackRating:hover { + border-color: #bb86fc; + box-shadow: 0 0 6px rgba(187, 134, 252, 0.2); +} + +[data-theme="dark"] #feedbackRating:focus { + outline: none; + border-color: #bb86fc; + box-shadow: 0 0 8px rgba(187, 134, 252, 0.3); + background: rgba(60, 60, 60, 0.95); /* darker on focus, not too bright */ +} +[data-theme="dark"] .form-input::placeholder, +[data-theme="dark"] .form-textarea::placeholder { + color: #cccccc; /* softer placeholder */ +} +/* Dark Mode Feedback Textarea */ +[data-theme="dark"] .form-textarea { + background: rgba(50, 50, 50, 0.9); /* dark but not pitch black */ + color: #ffffff; /* readable text */ + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: none; +} + +[data-theme="dark"] .form-textarea:focus { + outline: none; + border-color: #bb86fc; + box-shadow: 0 0 8px rgba(187, 134, 252, 0.3); + background: rgba(60, 60, 60, 0.95); +} +/* Buttons */ +[data-theme="dark"] .submit-btn, +[data-theme="dark"] .home-btn { + background: var(--btn-gradient); + color: var(--btn-text); +} + +/* Feedback List Items */ +[data-theme="dark"] .feedback-item { + background: rgba(40, 40, 40, 0.85); + border-left: 4px solid #bb86fc; + color: #e0e0e0; +} + +[data-theme="dark"] .feedback-name { + color: #bb86fc; +} + +[data-theme="dark"] .feedback-email, +[data-theme="dark"] .feedback-date { + color: #ccc; +} + +/* Footer */ +[data-theme="dark"] .footer { + background: #1a1a1a !important; + color: #ffffff !important; + box-shadow: 0 0 30px rgba(255, 255, 255, 0.05); +} + +[data-theme="dark"] .footer h2, +[data-theme="dark"] .footer h3 { + color: #ff7f50 !important; /* Orange accent like index page */ +} + +[data-theme="dark"] .footer p, +[data-theme="dark"] .footer-links ul li a, +[data-theme="dark"] .footer-text { + color: #e0e0e0 !important; +} + +[data-theme="dark"] .footer-links ul li a:hover { + color: #ffa502 !important; /* Brighter orange hover */ +} + +[data-theme="dark"] .footer-newsletter input { + background: rgba(255, 255, 255, 0.1); + color: #ffffff; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +[data-theme="dark"] .footer-newsletter button { + background: linear-gradient(45deg, #ff7f50, #ffa502); + color: #000000; +} +body { + font-family: "Comic Neue", cursive; + background: linear-gradient( + 135deg, + var(--light-pink) 0%, + var(--light-blue) 30%, + var(--light-yellow) 60%, + var(--light-pink) 100% + ); + min-height: 100vh; + position: relative; + overflow-x: hidden; + line-height: 1.6; +} +/* Dark-Light Toggle Slider */ +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, #6b7043, #fde68a); + border-radius: 34px; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + font-size: 12px; + color: #fff; +} + +.slider:before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +/* When checked (dark mode) */ +.theme-switch input:checked + .slider { + background: linear-gradient(45deg, #bf60fa, #fde68a); +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} +/* Advanced Animated Background */ + +.page-content { + position: relative; + overflow: hidden; + z-index: 1; +} + +.page-content .animated-bg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 0; +} + +.floating-element { + position: absolute; + animation: floatAdvanced 8s ease-in-out infinite; + opacity: 0.7; +} + +.floating-element:nth-child(1) { + top: 10%; + left: 5%; + font-size: 3rem; + animation-delay: 0s; +} +.floating-element:nth-child(2) { + top: 20%; + right: 10%; + font-size: 2.5rem; + animation-delay: 2s; +} +.floating-element:nth-child(3) { + bottom: 30%; + left: 15%; + font-size: 2rem; + animation-delay: 4s; +} +.floating-element:nth-child(4) { + bottom: 20%; + right: 20%; + font-size: 2.8rem; + animation-delay: 1s; +} +.floating-element:nth-child(5) { + top: 50%; + left: 80%; + font-size: 2.2rem; + animation-delay: 3s; +} +.floating-element:nth-child(6) { + top: 70%; + left: 10%; + font-size: 1.8rem; + animation-delay: 5s; +} + +@keyframes floatAdvanced { + 0%, + 100% { + transform: translateY(0px) translateX(0px) rotate(0deg) scale(1); + opacity: 0.7; + } + 25% { + transform: translateY(-30px) translateX(20px) rotate(5deg) scale(1.1); + opacity: 0.9; + } + 50% { + transform: translateY(-60px) translateX(-10px) rotate(-3deg) scale(0.9); + opacity: 0.6; + } + 75% { + transform: translateY(-20px) translateX(15px) rotate(8deg) scale(1.05); + opacity: 0.8; + } +} + +/* Sparkle Effect */ +.sparkles { + position: absolute; + width: 100%; + height: 100%; +} + +.sparkle { + position: absolute; + width: 4px; + height: 4px; + background: var(--sunny-yellow); + border-radius: 50%; + animation: sparkle 3s linear infinite; +} + +@keyframes sparkle { + 0% { + opacity: 0; + transform: scale(0); + } + 50% { + opacity: 1; + transform: scale(1); + } + 100% { + opacity: 0; + transform: scale(0); + } +} + +/* Navigation Bar */ +.navbar { + width: 100%; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + padding: 12px 20px; + position: sticky; + top: 0; + z-index: 100; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; +} + +.logo { + font-size: 1.5rem; + font-weight: bold; + color: #ffffff; + letter-spacing: 1px; +} + +.logo a { + text-decoration: none; + color: #fff; +} + +.nav-links { + display: flex; + list-style: none; + gap: 25px; +} + +.nav-links li a { + color: #ffffff; + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 5px 0; +} + +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after, +.nav-links li a.active::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} + +.fb-color { + padding: 8px 15px; + background: linear-gradient(45deg, #60a5fa, #fde68a); + border-radius: 20px; + border: none; +} +.fb-color:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} +.fb-color a { + color: white; + text-decoration: none; +} + +.cta-btn { + padding: 10px 20px; + background: linear-gradient(45deg, #60a5fa, #f9a8d4, #fde68a); + color: #ffffff; + font-weight: bold; + text-decoration: none; + border-radius: 30px; + transition: all 0.4s ease; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); +} + +.cta-btn:hover { + transform: scale(1.08); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); +} +/* Scale Now Navigation Button */ +.scale-nav-btn { + background: linear-gradient(45deg, #60a5fa, #fde68a) !important; + color: #ffffff !important; + padding: 8px 16px !important; + border-radius: 20px !important; + font-weight: 600 !important; + text-decoration: none !important; + transition: all 0.3s ease !important; + box-shadow: 0 2px 8px rgba(96, 165, 250, 0.3) !important; + display: inline-block !important; +} + +.scale-nav-btn:hover { + transform: translateY(-2px) scale(1.05) !important; + box-shadow: 0 4px 12px rgba(96, 165, 250, 0.4) !important; +} + +.scale-nav-btn::after { + display: none !important; +} +/* User Info Display */ +.user-info { + display: flex; + align-items: center; + gap: 1rem; + color: #ffffff; + font-weight: 600; +} + +.user-avatar { + width: 40px; + height: 40px; + background: linear-gradient(45deg, #c270f6, #747061); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + color: white; +} + +.logout-btn { + background: linear-gradient(90deg, #ff5f6d, #c31432); + color: #ffffff; + border: none !important; + padding: 0.5rem 1rem; + border-radius: 20px; + font-family: "Comic Neue", cursive; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + font-size: 0.9rem; + box-shadow: 0 2px 8px rgba(255, 71, 87, 0.3) !important; +} + +.logout-btn:hover { + background: linear-gradient(45deg, #ff3838, #ff2d2d) !important; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 71, 87, 0.4) !important; +} + +/* Hero Section */ +.hero { + text-align: center; + padding: 2rem 2rem 4rem; + position: relative; + z-index: 10; +} + +.hero-title { + font-size: 4rem; + font-weight: 700; + background: linear-gradient( + 135deg, + var(--candy-red), + var(--sky-blue), + var(--sunny-yellow) + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 1rem; + animation: heroAnimation 3s ease-out; +} + +@keyframes heroAnimation { + 0% { + opacity: 0; + transform: translateY(50px) scale(0.8); + } + 100% { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.hero-subtitle { + font-size: 1.5rem; + color: #666; + margin-bottom: 2rem; + animation: fadeInUp 1s ease-out 0.5s both; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Main Container */ +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 2rem; + position: relative; + z-index: 10; +} + +/* Section Cards */ +.section-card { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + border-radius: 30px; + padding: 3rem; + margin-bottom: 3rem; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + position: relative; + overflow: hidden; + transition: all 0.5s ease; +} + +.section-card::before { + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: conic-gradient( + from 0deg, + transparent, + rgba(255, 71, 87, 0.1), + transparent + ); + animation: rotate 20s linear infinite; + opacity: 0; + transition: opacity 0.5s ease; +} + +.section-card:hover::before { + opacity: 1; +} + +@keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.section-card:hover { + transform: translateY(-10px); + box-shadow: 0 30px 80px rgba(0, 0, 0, 0.15); +} + +.section-header { + display: flex; + align-items: center; + margin-bottom: 2rem; +} + +.section-icon { + font-size: 3rem; + margin-right: 1rem; + animation: iconBounce 2s ease-in-out infinite; +} + +@keyframes iconBounce { + 0%, + 20%, + 50%, + 80%, + 100% { + transform: translateY(0); + } + 40% { + transform: translateY(-10px); + } + 60% { + transform: translateY(-5px); + } +} + +.section-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--candy-red); + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.section-content { + font-size: 1.2rem; + color: #555; + line-height: 1.8; + position: relative; + z-index: 1; +} + +/* Feedback Form */ +.feedback-form { + max-width: 600px; + margin: 0 auto; +} + +.form-group { + margin-bottom: 2rem; +} + +.form-label { + display: flex; + align-items: center; + gap: 0.5rem; + font-weight: 600; + color: #333; + margin-bottom: 0.5rem; + font-size: 1.1rem; +} + +.form-label i { + color: var(--sky-blue); + width: 16px; +} + +.form-input, +.form-textarea { + width: 100%; + padding: 1rem 1.2rem; + border: 2px solid #e0e0e0; + border-radius: 15px; + font-family: "Comic Neue", cursive; + font-size: 1rem; + background: rgba(255, 255, 255, 0.8); + transition: all 0.3s ease; + color: #333; +} + +.form-input:focus, +.form-textarea:focus { + outline: none; + border-color: var(--sky-blue); + box-shadow: 0 0 0 3px rgba(112, 161, 255, 0.2); + background: rgba(255, 255, 255, 1); +} + +.form-input::placeholder, +.form-textarea::placeholder { + color: #999; +} + +.form-textarea { + resize: vertical; + min-height: 120px; +} + +.form-actions { + text-align: center; + margin-top: 2rem; +} + +.submit-btn { + background: linear-gradient(45deg, var(--candy-red), var(--sunny-yellow)); + color: var(--white); + border: none; + padding: 1.2rem 2.5rem; + border-radius: 25px; + font-family: "Comic Neue", cursive; + font-size: 1.2rem; + font-weight: 700; + cursor: pointer; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + display: inline-flex; + align-items: center; + gap: 0.5rem; + box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4); +} + +.submit-btn:hover { + transform: translateY(-3px); + box-shadow: 0 12px 35px rgba(255, 107, 107, 0.5); +} + +.submit-btn:disabled { + opacity: 0.7; + cursor: not-allowed; + transform: none; +} + +.loading-spinner { + display: none; + width: 20px; + height: 20px; + border: 2px solid transparent; + border-top: 2px solid var(--white); + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +/* Success Message */ +.success-message { + display: none; + background: rgba(46, 213, 115, 0.1); + border: 2px solid var(--success-green); + border-radius: 20px; + padding: 3rem; + text-align: center; + margin: 2rem 0; + animation: slideIn 0.5s ease-out; +} + +.success-message.show { + display: block; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.success-content i { + font-size: 4rem; + color: var(--success-green); + margin-bottom: 1rem; +} + +.success-content h3 { + font-size: 2rem; + color: var(--success-green); + margin-bottom: 1rem; +} + +.success-content p { + font-size: 1.2rem; + color: #666; + margin-bottom: 2rem; +} + +.home-btn { + background: linear-gradient(45deg, var(--sky-blue), var(--candy-red)); + color: var(--white); + border: none; + padding: 1rem 2rem; + border-radius: 25px; + font-family: "Comic Neue", cursive; + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: inline-flex; + align-items: center; + gap: 0.5rem; + text-decoration: none; + box-shadow: 0 4px 15px rgba(112, 161, 255, 0.4); +} + +.home-btn:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(112, 161, 255, 0.5); +} + +/* Feedback List */ +.feedback-list { + max-height: 500px; + overflow-y: auto; + margin-bottom: 2rem; +} + +.feedback-item { + background: rgba(255, 255, 255, 0.8); + border-radius: 15px; + padding: 1.5rem; + margin-bottom: 1rem; + border-left: 4px solid var(--sky-blue); + transition: all 0.3s ease; +} + +.feedback-item:hover { + transform: translateX(5px); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); +} + +.feedback-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.5rem; +} + +.feedback-name { + font-weight: 700; + color: var(--candy-red); + font-size: 1.1rem; +} + +.feedback-date { + font-size: 0.9rem; + color: #666; +} + +.feedback-email { + font-size: 0.9rem; + color: var(--sky-blue); + margin-bottom: 1rem; +} + +.feedback-message { + color: #555; + line-height: 1.6; +} + +.list-actions { + text-align: center; + margin-top: 2rem; +} + +/* Scroll Animations */ +.animate-on-scroll { + opacity: 0; + transform: translateY(50px); + transition: all 0.8s ease; +} + +.animate-on-scroll.animated { + opacity: 1; + transform: translateY(0); +} + +/* Mobile Responsive */ +@media (max-width: 968px) { + .navbar { + padding: 10px 15px; + } + + .nav-links { + display: none; + } + + .hero-title { + font-size: 2.5rem; + } + + .hero-subtitle { + font-size: 1.2rem; + } + + .section-card { + padding: 2rem; + } + + .section-title { + font-size: 2rem; + } + + .feedback-header { + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; + } +} + +/* Footer */ +.footer { + background-color: #ffb6c1; + color: #fff; + padding: 40px 20px; + font-family: sans-serif; +} + +.footer-container { + max-width: 1200px; + margin: auto; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 30px; +} + +.footer h2 { + color: #ff7f50; +} + +.footer h3 { + margin-bottom: 10px; + color: #ff7f50; +} + +.footer p { + font-size: 16px; + line-height: 1.5; +} + +.footer-links ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-links ul li { + margin-bottom: 6px; +} + +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: color 0.3s; +} + +.footer-links ul li a:hover { + color: #ff7f50; +} + +.footer-newsletter input { + padding: 10px; + width: 100%; + margin-bottom: 10px; + border: none; + border-radius: 4px; +} + +.footer-newsletter button { + background-color: #ff7f50; + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background 0.3s; +} + +.footer-newsletter button:hover { + background-color: #ff956b; +} + +.social-icons { + display: flex; + gap: 12px; + margin-top: 10px; +} + +.social-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + color: white; + font-size: 18px; + transition: transform 0.3s, opacity 0.3s; +} + +.social-icon:hover { + transform: scale(1.1); + opacity: 0.85; +} + +.social-icon.linkedin { + background: #0077b5; +} +.social-icon.github { + background: #6e5494; +} +.social-icon.email { + background: #ff8800; +} + +.footer-bottom { + text-align: center; + font-size: 14px; + margin-top: 30px; + border-top: 1px solid #333; + padding-top: 20px; +} + +/* Back to Top Button */ +#scrollTopBtn { + display: none; + position: fixed; + bottom: 30px; + right: 30px; + z-index: 99; + font-size: 30px; + border: none; + outline: none; + background: linear-gradient(45deg, #ff6ec7, #ffa07a, #87cefa); + color: black; + cursor: pointer; + padding: 7px 15px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + transition: all 0.3s ease; +} + +#scrollTopBtn:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(0,0,0,0.3); +} + +/* Rating Dropdown Styling */ +#feedbackRating { + width: 100%; + padding: 10px 15px; + border-radius: 12px; + border: 2px solid #ffb347; + background: linear-gradient(145deg, #fffaf0, #fff5e1); + color: #444; + font-family: "Comic Neue", cursive; + font-size: 1rem; + font-weight: 600; + transition: all 0.3s ease; + appearance: none; + cursor: pointer; + box-shadow: inset 0 2px 5px rgba(255, 178, 56, 0.15), + 0 2px 6px rgba(0, 0, 0, 0.05); +} + +/* Add arrow icon */ +#feedbackRating:after { + content: "\f107"; /* FontAwesome down arrow */ + font-family: "Font Awesome 6 Free"; + font-weight: 900; + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); + pointer-events: none; + color: #ff914d; +} + +#feedbackRating:hover { + border-color: #ff914d; + box-shadow: 0 4px 12px rgba(255, 145, 77, 0.2); +} + +#feedbackRating:focus { + outline: none; + border-color: #ff6b6b; + box-shadow: 0 4px 14px rgba(255, 107, 107, 0.25); + background: #fffaf0; +} diff --git a/BakeGenuis-AI/css/floating_emoji_fix.css b/BakeGenuis-AI/css/floating_emoji_fix.css new file mode 100644 index 00000000..1df2a965 --- /dev/null +++ b/BakeGenuis-AI/css/floating_emoji_fix.css @@ -0,0 +1,102 @@ +/** + * Floating Emoji Footer Fix - CSS Component + * Ensures proper z-index stacking and provides fallback styling + * for floating emoji elements when they overlap with footer + */ + +/* Ensure footer has higher z-index than floating elements */ +.footer, +footer { + position: relative; + z-index: 100 !important; +} + +/* Lower z-index for all floating emoji elements */ +.floating-elements, +.floating-element, +.floating-cupcake, +.animated-bg .floating-element { + z-index: 1 !important; + transition: opacity 0.3s ease; +} + +/* Specific adjustments for different page layouts */ + +/* Customize page floating elements */ +.floating-elements .floating-cupcake { + z-index: 1 !important; +} + +/* About page animated background elements */ +.animated-bg { + z-index: 0; +} + +.animated-bg .floating-element { + z-index: 1 !important; +} + +/* Scale page floating elements */ +body .floating-elements { + z-index: 1 !important; +} + +body .floating-cupcake { + z-index: 1 !important; +} + +/* Backup hiding class for JavaScript control */ +.floating-elements.hidden-for-footer, +.floating-element.hidden-for-footer, +.floating-cupcake.hidden-for-footer { + opacity: 0; + pointer-events: none; + transition: opacity 0.3s ease-out; +} + +/* Smooth transitions for emoji visibility changes */ +.floating-elements, +.floating-element, +.floating-cupcake { + transition: opacity 0.3s ease, z-index 0.3s ease; +} + +/* Media query adjustments for mobile devices */ +@media (max-width: 768px) { + .floating-elements, + .floating-element, + .floating-cupcake { + /* Reduce emoji prominence on mobile where footer overlap is more problematic */ + opacity: 0.6; + } + + .footer, + footer { + z-index: 200 !important; + } +} + +/* Specific fix for back-to-top button positioning */ +#scrollTopBtn, +#backToTop { + z-index: 150 !important; +} + +/* Dark mode considerations */ +[data-theme="dark"] .floating-elements, +[data-theme="dark"] .floating-element, +[data-theme="dark"] .floating-cupcake { + /* Slightly reduce opacity in dark mode for better footer visibility */ + opacity: 0.5; +} + +/* Additional safety net: hide emojis when they might be at the bottom of viewport */ +@media (max-height: 600px) { + .floating-element:nth-child(3), + .floating-element:nth-child(4), + .floating-cupcake:nth-child(3), + .floating-cupcake:nth-child(4) { + /* Hide bottom positioned emojis on short screens */ + opacity: 0.3; + } +} diff --git a/BakeGenuis-AI/css/index.css b/BakeGenuis-AI/css/index.css new file mode 100644 index 00000000..dd1be500 --- /dev/null +++ b/BakeGenuis-AI/css/index.css @@ -0,0 +1,1680 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --bg-color: #ffffff; + --text-color: #000000; + --candy-red: #ff6b6b; + --sky-blue: #4ecdc4; + --sunny-yellow: #ffd93d; + --soft-pink: #ffb6c1; + --mint-green: #98fb98; + --lavender: #e6e6fa; + /* Light mode */ + --bg-color: #ffffff; + --text-color: #000000; + + --body-gradient: linear-gradient( + 135deg, + #4ecdc4 0%, + #ffb6c1 50%, + #ffd93d 100% + ); + --navbar-gradient: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + --link-color: #ffffff; + --link-hover-gradient: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + --cta-gradient: linear-gradient(45deg, #60a5fa, #f9a8d4, #fde68a); + --cta-text: #ffffff; + --card-bg: rgba(255, 255, 255, 0.8); + --card-hover-bg: rgba(255, 255, 255, 0.95); + --card-shadow: rgba(0, 0, 0, 0.15); +} + +[data-theme="dark"] { + --bg-color: #121212; + --text-color: #ffffff; + + --body-gradient: linear-gradient( + 135deg, + #121212 0%, + #1f1f1f 50%, + #2a2a2a 100% + ); + --navbar-gradient: linear-gradient(90deg, #333333, #222222, #111111); + --link-color: #ffffff; + --link-hover-gradient: linear-gradient(90deg, #bb86fc, #03dac6); + --cta-gradient: linear-gradient(45deg, #bb86fc, #03dac6); + --cta-text: #000000; + --card-bg: rgba(30, 30, 30, 0.8); + --card-hover-bg: rgba(50, 50, 50, 0.95); + --card-shadow: rgba(0, 0, 0, 0.6); +} +/* Dark Mode Overrides Only */ +[data-theme="dark"] { + /* Base variables */ + --bg-color: #121212; + --text-color: #ffffff; + + --body-gradient: linear-gradient( + 135deg, + #121212 0%, + #1f1f1f 50%, + #2a2a2a 100% + ); + --navbar-gradient: linear-gradient(90deg, #222222, #111111, #333333); + --link-color: #ffffff; + --link-hover-gradient: linear-gradient(90deg, #bb86fc, #03dac6); + --cta-gradient: linear-gradient(45deg, #bb86fc, #03dac6); + --cta-text: #ffffff; + + --card-bg: rgba(30, 30, 30, 0.85); + --card-hover-bg: rgba(50, 50, 50, 0.95); + --card-shadow: rgba(0, 0, 0, 0.6); + --hero-bg: rgba(30, 30, 30, 0.85); + --footer-bg: #1a1a1a; + --footer-text: #ffffff; +} + +/* Hero Section */ +[data-theme="dark"] .hero-section { + background: var(--hero-bg) !important; + color: #ffffff !important; + box-shadow: 0 20px 60px rgba(255, 255, 255, 0.05), + 0 0 20px rgba(187, 134, 252, 0.2); + backdrop-filter: blur(15px); +} + +[data-theme="dark"] .hero-title, +[data-theme="dark"] .hero-subtitle { + color: #ffffff !important; +} +/* Dark Mode User Info (hi, username) */ +[data-theme="dark"] .user-info { + color: #ffffff !important; /* always white in dark mode */ +} + +/* Dark Theme for Newsletter Section */ +html[data-theme="dark"] .newsletter-section { + background: linear-gradient(135deg, #2c2c2c 0%, #3d3d3d 100%); + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5); +} + +html[data-theme="dark"] .newsletter-section h2 { + color: #ffa07a; /* lighter accent for dark mode */ +} + +html[data-theme="dark"] .newsletter-section p { + color: #ddd; +} + +html[data-theme="dark"] .newsletter-form input { + background-color: #444; + color: #eee; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5); +} + +html[data-theme="dark"] .newsletter-form input:focus { + box-shadow: 0 4px 15px rgba(255, 127, 80, 0.5); +} + +html[data-theme="dark"] .newsletter-form button { + background-color: #ff7f50; + color: #fff; + box-shadow: 0 4px 10px rgba(255, 127, 80, 0.5); +} + +html[data-theme="dark"] .newsletter-form button:hover { + background-color: #ff956b; + box-shadow: 0 6px 15px rgba(255, 127, 80, 0.7); +} +/* Feature Cards */ +[data-theme="dark"] .feature-card { + background: var(--card-bg) !important; + box-shadow: 0 20px 60px var(--card-shadow), 0 0 15px rgba(187, 134, 252, 0.2); +} + +[data-theme="dark"] .feature-card:hover { + background: var(--card-hover-bg) !important; + box-shadow: 0 25px 80px rgba(187, 134, 252, 0.25); +} + +[data-theme="dark"] .feature-title, +[data-theme="dark"] .feature-desc { + color: #f0f0f0 !important; +} + +/* Section Cards */ +[data-theme="dark"] .section-card { + background: var(--card-bg) !important; + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 20px 60px rgba(255, 255, 255, 0.05), + 0 0 15px rgba(187, 134, 252, 0.2); +} + +[data-theme="dark"] .section-title, +[data-theme="dark"] .section-content { + color: #f0f0f0 !important; +} + +/* Navbar */ +[data-theme="dark"] .navbar { + background: var(--navbar-gradient) !important; + box-shadow: 0 2px 20px rgba(255, 255, 255, 0.05); +} + +[data-theme="dark"] .nav-links li a { + color: #ffffff !important; +} + +/* CTA Buttons */ +[data-theme="dark"] .cta-button { + color: #ffffff !important; + background: var(--cta-gradient); + box-shadow: 0 10px 30px rgba(187, 134, 252, 0.3); +} + +/* Footer */ +[data-theme="dark"] .footer { + background: var(--footer-bg) !important; + color: var(--footer-text) !important; + box-shadow: 0 0 30px rgba(255, 255, 255, 0.05); +} + +[data-theme="dark"] .footer-links ul li a, +[data-theme="dark"] .footer-text { + color: #e0e0e0 !important; +} +[data-theme="dark"] .footer-links ul li a:hover { + color: #ff7f50 !important; +} +/* Hero & Section Glow Animation */ +[data-theme="dark"] .hero-section::before, +[data-theme="dark"] .section-card::before { + background: linear-gradient( + 45deg, + transparent, + rgba(187, 134, 252, 0.1), + transparent + ); + opacity: 0.3; +} + +/* Optional subtle accent for steps/cards */ +[data-theme="dark"] .step-card { + background: rgba(40, 40, 40, 0.8); + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 10px 30px rgba(187, 134, 252, 0.15); +} + +[data-theme="dark"] .step-number { + color: #bb86fc !important; +} + +[data-theme="dark"] .step-title, +[data-theme="dark"] .step-description { + color: #f0f0f0 !important; +} +/* Navbar Glow & Gradient Magic */ +[data-theme="dark"] .navbar { + background: linear-gradient(90deg, #222222, #111111, #333333); + box-shadow: 0 4px 20px rgba(187, 134, 252, 0.4); + border-bottom: 1px solid rgba(187, 134, 252, 0.2); +} + +[data-theme="dark"] .nav-links li a { + color: #ffffff !important; + text-shadow: 0 0 8px rgba(187, 134, 252, 0.5); +} + +[data-theme="dark"] .nav-links li a:hover { + transform: translateY(-2px); + text-shadow: 0 0 12px rgba(187, 134, 252, 0.8); +} + +/* Apply Variables */ +body { + background: var(--bg-color); + color: var(--text-color); + transition: background 0.3s, color 0.3s; +} + +.navbar { + background: var(--navbar-gradient); + transition: background 0.3s; +} + +.nav-links li a { + color: var(--link-color); +} + +.nav-links li a::after { + background: var(--link-hover-gradient); +} + +.hero-section { + background: var(--hero-bg); + backdrop-filter: blur(15px); + transition: background 0.3s, color 0.3s; +} + +.feature-card { + background: var(--card-bg); + box-shadow: 0 20px 60px var(--card-shadow); + transition: background 0.3s, box-shadow 0.3s, color 0.3s; +} + +.feature-card:hover { + background: var(--card-hover-bg); + box-shadow: 0 20px 60px var(--card-shadow); +} + +.cta-button { + background: var(--cta-gradient); + color: var(--cta-text); + transition: background 0.3s, color 0.3s; +} + +.footer { + background: var(--footer-bg); + color: var(--footer-text); + transition: background 0.3s, color 0.3s; +} +body { + background: var(--bg-color) !important; + color: var(--text-color) !important; +} + +body { + font-family: "Comic Neue", cursive; + overflow-x: hidden; + background: var(--bg-color); + color: var(--text-color); + min-height: 100vh; + position: relative; + transition: background 0.3s, color 0.3s; +} + +@keyframes wobble { + 0% { + transform: translateX(0%); + } + 15% { + transform: translateX(-25px) rotate(-5deg); + } + 30% { + transform: translateX(20px) rotate(3deg); + } + 45% { + transform: translateX(-15px) rotate(-3deg); + } + 60% { + transform: translateX(10px) rotate(2deg); + } + 75% { + transform: translateX(-5px) rotate(-1deg); + } + 100% { + transform: translateX(0%); + } +} + +@keyframes shimmer { + 0% { + background-position: -1000px 0; + } + 100% { + background-position: 1000px 0; + } +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.05); + } + 100% { + transform: scale(1); + } +} + +/* Navigation */ +/* Navbar Base */ +.navbar { + width: 100%; + background: var(--navbar-gradient); /* light or dark depending on theme */ + padding: 0.75rem 1.25rem; + position: sticky; + top: 0; + z-index: 1000; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); + transition: background 0.3s; +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; +} + +/* Logo */ +.logo { + font-size: 1.5rem; + font-weight: bold; + color: var(--link-color); + letter-spacing: 1px; +} + +.logo a { + text-decoration: none; + color: #fff; +} + +/* Nav Links */ +.nav-links { + display: flex; + list-style: none; + gap: 1.5rem; +} + +.nav-links li a { + color: var(--link-color); + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 0.3rem 0; +} + +/* Hover Gradient Underline */ +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: var(--link-hover-gradient); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after, +.nav-links li a.active::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} +/*dark-light toggle*/ +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} + +.slider { + position: absolute; + cursor: pointer; + background: linear-gradient(45deg, #6b7043, #fde68a); + border-radius: 34px; + top: 0; + left: 0; + right: 0; + bottom: 0; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + color: #fff; + font-size: 12px; +} + +.slider:before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +/* When checked (dark mode) */ +.theme-switch input:checked + .slider { + background: linear-gradient(45deg, #bf60fa, #fde68a); +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} + +/* CTA Button */ +.cta-btn { + padding: 0.625rem 1.25rem; + background: var(--cta-gradient); + color: var(--cta-text); + font-weight: bold; + text-decoration: none; + border-radius: 30px; + transition: all 0.4s ease; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); +} + +.cta-btn:hover { + transform: scale(1.08); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); +} + +.fb-color { + padding: 0.5rem 0.9rem; + background: linear-gradient(45deg, #60a5fa, #fde68a); + border-radius: 20px; + border: none; +} +.fb-color:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} +.fb-color a { + color: bwhitelack; + text-decoration: none; +} + +/* Scale Now Navigation Button */ +.scale-nav-btn { + background: linear-gradient(45deg, #60a5fa, #fde68a) !important; + color: #ffffff !important; + padding: 8px 16px !important; + border-radius: 20px !important; + font-weight: 600 !important; + text-decoration: none !important; + transition: all 0.3s ease !important; + box-shadow: 0 2px 8px rgba(96, 165, 250, 0.3) !important; + display: inline-block !important; +} + +.scale-nav-btn:hover { + transform: translateY(-2px) scale(1.05) !important; + box-shadow: 0 4px 12px rgba(96, 165, 250, 0.4) !important; +} + +.scale-nav-btn::after { + display: none !important; +} + +/* User Info Display */ +.user-info { + display: flex; + align-items: center; + gap: 1rem; + color: #ffffff; + font-weight: 600; +} + +.user-avatar { + width: 40px; + height: 40px; + background: linear-gradient(45deg, #c270f6, #747061); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + color: white; +} + +.logout-btn { + background: linear-gradient(90deg, #ff5f6d, #c31432); + color: #ffffff; + border: none !important; + padding: 0.5rem 1rem; + border-radius: 20px; + font-family: "Comic Neue", cursive; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + font-size: 0.9rem; + box-shadow: 0 2px 8px rgba(255, 71, 87, 0.3) !important; +} + +.logout-btn:hover { + background: linear-gradient(45deg, #ff3838, #ff2d2d) !important; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 71, 87, 0.4) !important; +} +/* Main Content */ +.main-content { + margin-top: 0; + padding: 2rem; + position: relative; + z-index: 2; + min-height: calc(100vh - 200px); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} + +.hero-section { + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(15px); + padding: 3rem; + border-radius: 30px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1); + max-width: 800px; + margin: 0 auto; + position: relative; + overflow: hidden; +} + +.hero-section::before { + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient( + 45deg, + transparent, + rgba(255, 255, 255, 0.1), + transparent + ); + animation: shimmer 3s linear infinite; +} + +.hero-title { + font-size: 3.5rem; + font-weight: 700; + background: linear-gradient( + 45deg, + var(--candy-red), + var(--sky-blue), + var(--sunny-yellow) + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 1rem; + /* adding text animation */ + display: inline-block; + white-space: nowrap; + overflow: hidden; + border-right: 2px solid #ab57cf; + width: 0; /* start hidden */ +} +.typing-active { + animation: typing 3s steps(22, end) forwards, blink 0.6s step-end 3s, + /* blink for 5 times after typing */ hideCursor 0s forwards 2.7s; /* remove cursor after blinking */ +} + +@keyframes typing { + from { + width: 0; + } + to { + width: 22ch; + } +} +@keyframes blink { + 50% { + border-color: transparent; + } +} +@keyframes hideCursor { + to { + border-right: none; + } +} + +.hero-subtitle { + font-size: 1.3rem; + color: #666; + margin-bottom: 2rem; + font-weight: 400; + line-height: 1.6; +} + +.cta-button { + background: linear-gradient(45deg, var(--candy-red), var(--sunny-yellow)); + color: white; + font-size: 1.2rem; + font-weight: 700; + padding: 1rem 2.5rem; + border: none; + border-radius: 50px; + cursor: pointer; + text-decoration: none; + display: inline-block; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + box-shadow: 0 10px 30px rgba(255, 107, 107, 0.4); + animation: pulse 2s ease-in-out infinite; +} + +.cta-button:hover { + transform: translateY(-5px) scale(1.05); + box-shadow: 0 15px 40px rgba(255, 107, 107, 0.6); +} + +.cta-button::before { + content: ""; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient( + 90deg, + transparent, + rgba(255, 255, 255, 0.3), + transparent + ); + transition: left 0.5s; +} + +.cta-button:hover::before { + left: 100%; +} + +/* Section Cards */ +.section-card { + margin-top: 3rem; + background: rgba(255, 255, 255, 0.9); + backdrop-filter: blur(20px); + border-radius: 30px; + padding: 3rem; + margin-bottom: 3rem; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + position: relative; + overflow: hidden; + transition: all 0.5s ease; +} + +.section-card::before { + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: conic-gradient( + from 0deg, + transparent, + rgba(255, 71, 87, 0.1), + transparent + ); + animation: rotate 20s linear infinite; + opacity: 0; + transition: opacity 0.5s ease; +} + +.section-card:hover::before { + opacity: 1; +} + +@keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.section-card:hover { + transform: translateY(-10px); + box-shadow: 0 30px 80px rgba(0, 0, 0, 0.15); +} + +.section-header { + display: flex; + align-items: center; + margin-bottom: 2rem; +} + +.section-icon { + font-size: 3rem; + margin-right: 1rem; + animation: iconBounce 2s ease-in-out infinite; +} + +@keyframes iconBounce { + 0%, + 20%, + 50%, + 80%, + 100% { + transform: translateY(0); + } + 40% { + transform: translateY(-10px); + } + 60% { + transform: translateY(-5px); + } +} + +.section-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--candy-red); + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.section-content { + font-size: 1.2rem; + color: #555; + line-height: 1.8; + position: relative; + z-index: 1; +} + +/* How It Works Steps */ +.steps-container { + display: flex; + flex-wrap: wrap; + gap: 2rem; + margin: 2rem 0; +} +.steps-container > * { + flex: 1 1 250px; +} + +.auth-buttons { + display: flex; + align-items: center; + gap: 10px; +} + +.login-btn { + padding: 0.5rem 0.9rem; + background: transparent; + border: 1px solid #ff6b6b; + color: #ff6b6b; + border-radius: 20px; + cursor: pointer; + transition: all 0.3s; + text-decoration: none; + font-weight: 500; +} + +.login-btn:hover { + background-color: #ff6b6b; + color: white; +} + +.signup-btn { + padding: 0.5rem 0.9rem; + background-color: #ff6b6b; + color: white; + border: none; + border-radius: 20px; + cursor: pointer; + transition: all 0.3s; + text-decoration: none; + font-weight: 500; +} + +.signup-btn:hover { + background-color: #ff5252; +} + +.step-card { + background: linear-gradient( + 135deg, + rgba(112, 161, 255, 0.1), + rgba(255, 165, 2, 0.1) + ); + border-radius: 20px; + padding: 2rem; + text-align: center; + border: 2px solid transparent; + transition: all 0.4s ease; + position: relative; + overflow: hidden; +} + +.step-card::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 20px; + padding: 2px; + background: linear-gradient( + 135deg, + var(--sky-blue), + var(--sunny-yellow), + var(--candy-red) + ); + mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + mask-composite: exclude; + opacity: 0; + transition: opacity 0.4s ease; +} + +.step-card:hover::before { + opacity: 1; +} + +.step-card:hover { + transform: translateY(-5px) scale(1.05); + box-shadow: 0 20px 40px rgba(112, 161, 255, 0.2); +} + +.step-number { + font-size: 3rem; + font-weight: 700; + color: var(--sky-blue); + margin-bottom: 1rem; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.step-title { + font-size: 1.3rem; + font-weight: 700; + color: #333; + margin-bottom: 1rem; +} + +.step-description { + color: #666; + font-size: 1rem; +} + +.section-card { + padding: 2rem; +} + +.section-title { + font-size: 2rem; +} + +.steps-container { + grid-template-columns: 1fr; +} + +/* Decorative Elements */ +.baking-icons { + position: absolute; + width: 100%; + height: 100%; + pointer-events: none; +} + +.baking-icon { + position: absolute; + font-size: 3rem; + color: var(--candy-red); + opacity: 0.3; + animation: wobble 4s ease-in-out infinite; +} + +.icon-1 { + top: 10%; + left: 10%; + animation-delay: 0s; +} +.icon-2 { + top: 20%; + right: 15%; + animation-delay: 1s; +} +.icon-3 { + bottom: 30%; + left: 20%; + animation-delay: 2s; +} +.icon-4 { + bottom: 20%; + right: 10%; + animation-delay: 3s; +} + +/* Features Preview */ +.features-preview { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; + margin-top: 4rem; + max-width: 1000px; +} + +.feature-card { + background: var(--card-bg); + backdrop-filter: blur(10px); + padding: 2rem; + border-radius: 20px; + text-align: center; + transition: all 0.3s ease; + border: 2px solid transparent; +} + +.feature-card:hover { + transform: translateY(-10px); + border-color: var(--sky-blue); + background: var(--card-hover-bg); + box-shadow: 0 20px 60px var(--card-shadow); +} + +.feature-icon { + font-size: 3rem; + margin-bottom: 1.2rem; + display: inline-block; + will-change: transform; +} + +.feature-card:nth-child(1) .feature-icon { + color: var(--candy-red); +} +.feature-card:nth-child(2) .feature-icon { + color: var(--sky-blue); +} +.feature-card:nth-child(3) .feature-icon { + color: var(--sunny-yellow); +} +/* Animations on icons */ +@keyframes sparkle { + 0% { + transform: rotate(0deg) scale(1); + color: var(--candy-red); + } + 25% { + transform: rotate(-10deg) scale(1.1); + color: var(--soft-pink); + } + 50% { + transform: rotate(10deg) scale(1.2); + color: var(--sunny-yellow); + } + 75% { + transform: rotate(-6deg) scale(1.1); + color: var(--sky-blue); + } + 100% { + transform: rotate(0deg) scale(1); + color: var(--mint-green); + } +} + +@keyframes tilt { + 0%, + 100% { + transform: rotate(0); + } + 50% { + transform: rotate(-6deg); + } +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.magic { + animation: sparkle 2s ease-in-out infinite; +} +.scale { + color: var(--sky-blue); + animation: tilt 2s ease-in-out infinite; + transform-origin: 50% 10%; +} +.gears { + color: var(--sunny-yellow); + animation: spin 3s linear infinite; +} +@media (prefers-reduced-motion: reduce) { + .icon { + animation: none !important; + } +} +/* animation styles end here */ + +.feature-title { + font-size: 1.3rem; + font-weight: 700; + margin-bottom: 0.5rem; + color: #333; +} + +.feature-desc { + color: #666; + line-height: 1.5; +} + +/* Footer */ +.footer { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + padding: 2rem; + position: relative; + z-index: 2; + border-top: 1px solid rgba(255, 255, 255, 0.2); +} + +.footer-content { + max-width: 1200px; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 1rem; +} + +.footer-text { + color: #666; + font-weight: 600; +} + +.social-links { + display: flex; + gap: 1rem; +} + +.social-link { + display: inline-flex; + align-items: center; + justify-content: center; + width: 45px; + height: 45px; + background: linear-gradient(45deg, var(--candy-red), var(--sky-blue)); + color: white; + text-decoration: none; + border-radius: 50%; + font-size: 1.2rem; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); +} + +.social-link:hover { + transform: translateY(-3px) scale(1.1); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3); + animation: wobble 0.5s ease-in-out; +} + +.social-link.linkedin { + background: linear-gradient(45deg, #0077b5, #00a0dc); +} + +.social-link.portfolio { + background: linear-gradient(45deg, var(--sunny-yellow), var(--candy-red)); +} + +/* Responsive Design */ +@media (max-width: 768px) { + /* .navbar { + padding: 10px 15px; + } + + .navbar-container { + flex-wrap: wrap; + gap: 10px; + } + + .nav-links { + position: fixed; + top: 70px; + left: -100%; + width: 100%; + height: calc(100vh - 70px); + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + flex-direction: column; + justify-content: start; + padding-top: 2rem; + gap: 1rem; + transition: left 0.3s ease; + display: flex; + z-index: 999; + } + + .nav-links.active { + left: 0; + } */ + + .hero-title { + font-size: 2.5rem; + } + + .hero-section { + padding: 2rem; + margin: 1rem; + } + + .features-preview { + grid-template-columns: 1fr; + margin-top: 2rem; + } + + .footer-content { + flex-direction: column; + text-align: center; + } +} + +@media (max-width: 480px) { + .hero-title { + font-size: 2rem; + } + + .hero-subtitle { + font-size: 1.1rem; + } + + .cta-button { + font-size: 1rem; + padding: 0.8rem 2rem; + } +} + +.footer { + background-color: #ffb6c1; + color: #fff; + padding: 40px 20px; + font-family: sans-serif; +} +.footer-logo { + font-size: 1.4rem; +} +.footer-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 40px; +} + +.footer h2 { + color: #ff7f50; +} + +.footer h3 { + margin-bottom: 10px; + color: #ff7f50; +} + +.footer p { + font-size: 14px; + line-height: 1.5; +} + +.footer-links ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-links ul li { + margin-bottom: 6px; +} + +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: color 0.3s; +} + +.footer-links ul li a:hover { + color: #ff7f50; +} +.footer-icon { + font-size: 1rem; + color: #ff7f50; + margin-right: 6px; + transition: transform 0.3s ease, color 0.3s ease; + vertical-align: middle; /* Align nicely with text */ +} +/* Hover effect */ +.footer-links ul li a:hover i { + color: var(--soft-pink); /* Cyan on hover */ + transform: scale(1.2); /* Grow icon slightly */ +} + +/* Optional glowing effect on hover */ +.footer-icon:hover { + text-shadow: 0 0 8px rgba(0, 255, 255, 0.6); +} + +.footer-newsletter input { + padding: 10px; + width: 100%; + margin-bottom: 10px; + border: none; + border-radius: 4px; +} + +.footer-newsletter button { + background-color: #ff7f50; + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background 0.3s; +} + +.footer-newsletter button:hover { + background-color: #ff956b; +} + +/* Social icons */ +.social-icons { + display: flex; + gap: 12px; + margin-top: 10px; +} + +.social-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + color: white; + font-size: 18px; + transition: transform 0.3s, opacity 0.3s; +} + +.social-icon:hover { + transform: scale(1.1); + opacity: 0.85; +} + +/* Specific brand colors */ +.social-icon.linkedin { + background: #0077b5; +} +.social-icon.github { + background: #6e5494; +} +.social-icon.email { + background: #ff8800; +} + +.footer-bottom { + text-align: center; + font-size: 14px; + margin-top: 30px; + border-top: 1px solid #333; + padding-top: 20px; +} +/* #scrollTopBtn { + display: block !important; +} */ + +/* Scroll To Top Button */ +#scrollTopBtn { + position: fixed; + bottom: 30px; + right: 30px; + width: 55px; + height: 55px; + background: linear-gradient(45deg, #ff6ec7, #ffa07a, #ffd700, #87cefa); + border: none; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + font-size: 25px; + color: white; + cursor: pointer; + z-index: 999; + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2); + /* Smooth transition for transform and shadow */ + transition: transform 0.4s ease, box-shadow 0.4s ease; + + /* Floating animation */ + animation: float 2.5s ease-in-out infinite; +} + +#scrollTopBtn:hover { + /* Stops floating smoothly */ + animation-play-state: paused; + transform: translateY(0) scale(1.15); /* resets Y and scales */ + /* Glow effect */ + box-shadow: 0 0 20px rgba(248, 115, 208, 0.6), + 0 0 40px rgba(255, 235, 122, 0.5), 0 0 60px rgba(0, 255, 0, 0.4); + filter: brightness(1.05); +} +@keyframes float { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-8px); + } +} + +/* Show button only after scrolling */ +#scrollTopBtn.hidden { + opacity: 0; + pointer-events: none; + transform: scale(0.8); + animation: none !important; /* stop floating */ + transition: opacity 0.3s ease, transform 0.3s ease; +} + +/* === Cupcake Animation Section === */ + +/* Container */ +.cupcake-animation { + position: relative; + height: 220px; + margin-bottom: 2rem; + text-align: center; +} + +/* Cup (๐Ÿง) */ +.cup { + font-size: 6rem; + position: absolute; + left: 50%; + transform: translateX(-50%); + animation: dropCup 1s ease-out forwards; +} + +/* Cake top (๐Ÿ’) */ +.cake-top { + font-size: 3rem; + position: absolute; + left: 50%; + top: -150px; + transform: translateX(-50%); + opacity: 0; + animation: dropCake 1s ease-out forwards; + animation-delay: 1s; +} + +/* Cup bounce animation */ +@keyframes dropCup { + 0% { + top: -150px; + opacity: 0; + } + 70% { + top: 70px; + opacity: 1; + } + 85% { + top: 55px; + } + 100% { + top: 60px; + } +} + +/* Cake top bounce animation */ +@keyframes dropCake { + 0% { + top: -150px; + opacity: 0; + } + 70% { + top: 0px; + opacity: 1; + } + 85% { + top: 20px; + } + 100% { + top: 10px; + } +} + +/* Sprinkles (colored dots) */ +.sprinkles span { + position: absolute; + width: 8px; + height: 8px; + border-radius: 50%; + top: 30px; + left: 50%; + opacity: 0; + animation: sprinkle 1s ease-out forwards; + animation-delay: 2s; +} + +.sprinkles span:nth-child(1) { + background: #ff69b4; + left: 48%; +} +.sprinkles span:nth-child(2) { + background: #ffa500; + left: 52%; +} +.sprinkles span:nth-child(3) { + background: #32cd32; + left: 55%; +} + +@keyframes sprinkle { + from { + transform: translateY(0); + opacity: 1; + } + to { + transform: translateY(-40px); + opacity: 0; + } +} + +/* === End Cupcake Animation Section === */ + +/* Fix toggle placement beside Scale Now */ +.navbar-container { + display: flex; + align-items: center; + justify-content: space-between; +} + +.cta-btn, +.theme-switch { + margin-left: 15px; /* keep small spacing */ +} + +.theme-switch { + display: inline-flex; + align-items: center; +} +.navbar-container { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: nowrap; +} + +.hamburger { + display: none; + background: none; + border: none; + color: white; + font-size: 1.5rem; + cursor: pointer; + padding: 0.5rem; +} + +@media (max-width: 768px) { + .hamburger { + display: block; + } + + .nav-links { + display: none; + flex-direction: column; + position: absolute; + top: 100%; + left: 0; + right: 0; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + padding: 1rem; + border-radius: 0 0 15px 15px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + z-index: 999; + } + + .nav-links.active { + display: flex; + } + + .nav-links li a { + color: #333 !important; + padding: 0.5rem 1rem; + border-radius: 8px; + transition: all 0.3s ease; + } + + .nav-links li a:hover { + background: rgba(96, 165, 250, 0.1); + color: #60a5fa !important; + } + + .nav-right { + display: none; + flex-direction: column; + position: absolute; + top: 100%; + left: 0; + right: 0; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + padding: 1rem; + border-radius: 0 0 15px 15px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + z-index: 998; + margin-top: 1px; + } + + .nav-right.active { + display: flex; + } +} + + +/*Loading page*/ +#loading-screen { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + color: rgb(205, 151, 16); + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; + transition: opacity 0.5s ease, visibility 0.5s ease; +} + +#loading-screen.hidden { + opacity: 0; + visibility: hidden; +} + +.loader { + text-align: center; +} + +.loader i { + font-size: 4.5rem; + animation: spin 2s linear infinite; +} + +.loader h2 { + margin-top: 1.5rem; + font-size: 2.1rem; +} + +.dots::after { + content: ""; + display: inline-block; + animation: dots 1.5s steps(5, end) infinite; +} + +@keyframes dots { + 0% { + content: ""; + } + 20% { + content: "."; + } + 40% { + content: ".."; + } + 60% { + content: "..."; + } + 80%{ + content: "...."; + } + 100% { + content: ""; + } +} + +/* Spin Animation */ +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +/* scroll to top and bottom in same place home page */ +#scrollToBottomBtn, +#scrollToTopBtn { + position: fixed; + bottom: 30px; + right: 30px; + z-index: 1000; + border: none; + outline: none; + background: linear-gradient(45deg, var(--candy-red), var(--sky-blue)); + color: #fff; + cursor: pointer; + padding: 12px 16px; + border-radius: 50%; + font-size: 20px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); + transition: transform 0.3s ease, background 0.3s ease; + display: none; /* hidden by default */ +} + +#scrollToBottomBtn:hover, +#scrollToTopBtn:hover { + transform: scale(1.05); + background: linear-gradient(45deg, var(--sky-blue), var(--sunny-yellow)); +} + diff --git a/BakeGenuis-AI/css/recipe_hub.css b/BakeGenuis-AI/css/recipe_hub.css new file mode 100644 index 00000000..039bf83d --- /dev/null +++ b/BakeGenuis-AI/css/recipe_hub.css @@ -0,0 +1,1545 @@ +/* Recipe Hub Styles - BakeGenius.ai */ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + } + + :root { + --candy-red: #FF4757; + --sky-blue: #70A1FF; + --sunny-yellow: #FFA502; + --white: #FFFFFF; + --light-pink: #FFE0E6; + --light-blue: #E8F4FF; + --light-yellow: #FFF5E0; + --gradient-1: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --gradient-2: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + --gradient-3: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + } +/* === Dark Theme Overrides for About Us === */ +[data-theme="dark"] body { + background: linear-gradient(135deg, #121212 0%, #1f1f1f 50%, #2a2a2a 100%) !important; + color: #eee; + --navbar-gradient: linear-gradient(90deg, #222222, #111111, #333333); +} + +[data-theme="dark"] .hero-title, +[data-theme="dark"] .hero-subtitle, +[data-theme="dark"] .section-title, +[data-theme="dark"] .creator-name, +[data-theme="dark"] .creator-title, +[data-theme="dark"] .xyz { + color: #fff !important; +} + +[data-theme="dark"] .section-card, +[data-theme="dark"] .creator-section, +[data-theme="dark"] .contributors, +[data-theme="dark"] .step-card { + background: rgba(30, 30, 30, 0.85) !important; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 10px 30px rgba(0,0,0,0.7); + color: #f0f0f0; +} + +[data-theme="dark"] .section-content, +[data-theme="dark"] .step-title, +[data-theme="dark"] .step-description, +[data-theme="dark"] .problem-item, +[data-theme="dark"] .creator-title { + color: #ccc; +} + +[data-theme="dark"] .cta-btn, +[data-theme="dark"] .social-link, +[data-theme="dark"] .scale-nav-btn { + background: linear-gradient(45deg, #bb86fc, #03dac6) !important; + color: #fff !important; + box-shadow: 0 8px 25px rgba(187,134,252,0.3) !important; +} + +[data-theme="dark"] .social-link:hover, +[data-theme="dark"] .cta-btn:hover { + transform: scale(1.05); + box-shadow: 0 10px 30px rgba(187,134,252,0.5); +} + +[data-theme="dark"] .navbar { + background: var(--navbar-gradient); + box-shadow: 0 4px 20px rgba(187,134,252,0.4); + border-bottom: 1px solid rgba(187,134,252,0.2); +} + +[data-theme="dark"] .nav-links li a { + margin-left: -2px; + color: var(--link-color) !important; + text-shadow: 0 0 8px rgba(187,134,252,0.5); +} + +[data-theme="dark"] .nav-links li a:hover { + transform: translateY(-2px); + text-shadow: 0 0 12px rgba(187,134,252,0.8); +} + +[data-theme="dark"] .footer { + background: var(--footer-bg) !important; + color: var(--footer-text) !important; + box-shadow: 0 0 30px rgba(255,255,255,0.05); +} + +[data-theme="dark"] .footer-links ul li a, +[data-theme="dark"] .footer-text { + color: #e0e0e0 !important; +} +[data-theme="dark"] .footer-links ul li a:hover { + color: #ff7f50 !important; +} + +[data-theme="dark"] .contributor-card { + background: rgba(40, 40, 40, 0.85); + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 8px 20px rgba(0,0,0,0.7); +} + +[data-theme="dark"] .creator-avatar { + background: linear-gradient(135deg, #bb86fc, #03dac6); +} + +[data-theme="dark"] .creator-avatar::before { + background: linear-gradient(135deg, #03dac6, #bb86fc, #3700b3); +} + +[data-theme="dark"] .problem-item { + background: rgba(187,134,252,0.1); + border-left: 4px solid #bb86fc; +} + +[data-theme="dark"] .step-card { + background: rgba(30,30,30,0.7); + border: 1px solid rgba(255,255,255,0.1); +} + body { + font-family: 'Comic Neue', cursive; + background: linear-gradient(135deg, var(--light-pink) 0%, var(--light-blue) 30%, var(--light-yellow) 60%, var(--light-pink) 100%); + min-height: 100vh; + position: relative; + overflow-x: hidden; + line-height: 1.6; + } + /* Dark-Light Toggle Slider */ +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; left: 0; right: 0; bottom: 0; + background: rgba(96, 165, 250, 0.7); + border-radius: 34px; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + font-size: 12px; + color: #fff; +} + +.slider:before { + content: ""; + position: absolute; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +/* When checked (dark mode) */ +.theme-switch input:checked + .slider { + background: linear-gradient(45deg, #bf60fa, #fde68a); +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} + /* Advanced Animated Background */ + .animated-bg { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + overflow: hidden; + } + + .floating-element { + position: absolute; + animation: floatAdvanced 8s ease-in-out infinite; + opacity: 0.7; + } + + .floating-element:nth-child(1) { top: 10%; left: 5%; font-size: 3rem; animation-delay: 0s; } + .floating-element:nth-child(2) { top: 20%; right: 10%; font-size: 2.5rem; animation-delay: 2s; } + .floating-element:nth-child(3) { bottom: 30%; left: 15%; font-size: 2rem; animation-delay: 4s; } + .floating-element:nth-child(4) { bottom: 20%; right: 20%; font-size: 2.8rem; animation-delay: 1s; } + .floating-element:nth-child(5) { top: 50%; left: 80%; font-size: 2.2rem; animation-delay: 3s; } + .floating-element:nth-child(6) { top: 70%; left: 10%; font-size: 1.8rem; animation-delay: 5s; } + + @keyframes floatAdvanced { + 0%, 100% { + transform: translateY(0px) translateX(0px) rotate(0deg) scale(1); + opacity: 0.7; + } + 25% { + transform: translateY(-30px) translateX(20px) rotate(5deg) scale(1.1); + opacity: 0.9; + } + 50% { + transform: translateY(-60px) translateX(-10px) rotate(-3deg) scale(0.9); + opacity: 0.6; + } + 75% { + transform: translateY(-20px) translateX(15px) rotate(8deg) scale(1.05); + opacity: 0.8; + } + } + + /* Sparkle Effect */ + .sparkles { + position: absolute; + width: 100%; + height: 100%; + } + + .sparkle { + position: absolute; + width: 4px; + height: 4px; + background: var(--sunny-yellow); + border-radius: 50%; + animation: sparkle 3s linear infinite; + } + + @keyframes sparkle { + 0% { opacity: 0; transform: scale(0); } + 50% { opacity: 1; transform: scale(1); } + 100% { opacity: 0; transform: scale(0); } + } + + /* Navigation Bar */ + /* Navbar Base */ +.navbar { + width: 100%; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); /* light blue โ†’ light pink โ†’ soft yellow */ + padding: 12px 20px; + position: sticky; + top: 0; + z-index: 1000; + box-shadow: 0 4px 15px rgba(0,0,0,0.08); +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; +} + +/* Logo */ +.logo { + font-size: 1.5rem; + font-weight: bold; + color: #ffffff; + letter-spacing: 1px; +} + +.logo a{ + text-decoration: none; + color: #fff; +} + +/* Nav Links */ +.nav-links { + margin-left: -2px; + display: flex; + list-style: none; + gap: 5px; +} + +.nav-links li a { + color: #ffffff; + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 5px; +} + +/* Hover Gradient Underline */ +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after, +.nav-links li a.active::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} +.fb-color { + padding: 8px 15px; + background: linear-gradient(45deg, #60a5fa, #fde68a); + border-radius: 20px; + border: none; + } + .fb-color:hover { + box-shadow: 0 4px 12px rgba(96,165,250,0.5); + transform: translateY(-2px); +} + .fb-color a { + color: white; + text-decoration: none; + } +/* CTA Button */ +.cta-btn { + padding: 0px 20px; + background: linear-gradient(45deg, #60a5fa, #f9a8d4, #fde68a); + color: #ffffff; + font-weight: bold; + text-decoration: none; + border-radius: 30px; + transition: all 0.4s ease; + box-shadow: 0 4px 12px rgba(0,0,0,0.12); +} + +.cta-btn:hover { + transform: scale(1.08); + box-shadow: 0 6px 20px rgba(0,0,0,0.2); +} + + +/* Scale Now Navigation Button (matched with customize.css) */ +.scale-nav-btn { + background: linear-gradient(45deg, #60a5fa, #fde68a); + color: #ffffff; + padding: 0.5rem 1rem; + border-radius: 1.25rem; + font-weight: 600; + text-decoration: none; + transition: all 0.3s ease; + box-shadow: 0 2px 8px rgba(96, 165, 250, 0.3); + display: inline-block; +} + +.scale-nav-btn:hover { + transform: translateY(-2px) scale(1.05); + box-shadow: 0 4px 12px rgba(96, 165, 250, 0.4); +} + +.scale-nav-btn::after { + display: none; +} + + +/* User Info Display */ +.user-info { + display: flex; + align-items: center; + gap: 1rem; + color: #ffffff; + font-weight: 600; +} + +.user-avatar { + width: 40px; + height: 40px; + background: linear-gradient(45deg, #c270f6, #747061); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + color: white; +} + +.logout-btn { + background: linear-gradient(90deg, #ff5f6d, #c31432); + color: #ffffff; + border: none !important; + padding: 0.5rem 1rem; + border-radius: 20px; + font-family: 'Comic Neue', cursive; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + font-size: 0.9rem; + box-shadow: 0 2px 8px rgba(255, 71, 87, 0.3) !important; +} + +.logout-btn:hover { + background: linear-gradient(45deg, #ff3838, #ff2d2d) !important; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 71, 87, 0.4) !important; +} +/* Main Content */ +.main-content { + padding-top: 1rem; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; +} + +/* Hero Section */ +.hero { + text-align: center; + padding: 3rem 0; + margin-bottom: 2rem; +} + +.hero-title { + font-size: 3.5rem; + font-weight: bold; + color: #000; + margin-bottom: 1rem; + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +.hero-subtitle { + font-size: 1.2rem; + color: #666; + opacity: 0.9; + max-width: 600px; + margin: 0 auto; + text-shadow: 1px 1px 2px rgba(0,0,0,0.2); +} + +/* Search Section */ +.search-section { + background: rgba(255,255,255,0.9); + backdrop-filter: blur(15px); + border-radius: 20px; + margin: 2rem 2rem; + padding: 0; + box-shadow: 0 8px 30px rgba(0,0,0,0.1); +} + +.search-container { + max-width: 500px; + margin-inline: auto; + margin-bottom: 2rem; +} + +.search-bar { + display: flex; + flex: 1; + align-items: center; + background: #fff; + border-radius: 50px; + padding: 12px 20px; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); + margin-bottom: 3rem; + width:100%; + flex-wrap: nowrap; + gap: 8px; +} + +.container-search{ + margin-inline: auto; + height: 0; +} + +.search-icon { + color: var(--candy-red); + margin-right: 8px; + font-size: 1.1rem; + flex: 0 0 auto; +} + +.search-input { + flex: 1 1 auto; + min-width: 0; + border: none; + outline: none; + font-size: 1rem; + color: #333; + background: transparent; +} + +.search-input::placeholder { + color: #999; +} +@media (max-width: 480px) { + .search-bar { + flex-direction: row; + align-items: center; + flex-wrap: wrap; + gap: 6px; /* space between icon, input, and button */ + padding: 6px 10px; + border-radius: 25px; + width: auto; /* let it fit container naturally */ + } + + .search-icon { + margin: 0; /* no extra space */ + font-size: 1rem; + } + + .search-input { + flex: 1 1 100%; /* take remaining space */ + min-width: 0; + margin: 0; + } + + .filter-toggle-btn { + flex: 1 1 100%; + padding: 4px 10px; /* small & neat */ + font-size: 0.8rem; + border-radius: 18px; + } +} + + +/* Toggle button */ +.filter-toggle-btn { + flex: 0 0 auto; + white-space: nowrap; + background: linear-gradient(135deg, var(--candy-red), #ff7676); + color: white; + border: none; + padding: 8px 16px; + border-radius: 30px; + cursor: pointer; + font-weight: 600; + font-size: 0.95rem; + letter-spacing: 0.3px; + transition: all 0.3s ease; + box-shadow: 0 4px 12px rgba(255, 82, 82, 0.3); +} + +.filter-toggle-btn:hover { + background: linear-gradient(135deg, #ff5252, #ff8a8a); + transform: translateY(-2px) scale(1.03); + box-shadow: 0 6px 18px rgba(255, 82, 82, 0.4); +} + +/* Filter panel */ +.filters-panel { + display: none; + grid-template-columns: 1fr; + gap: 1rem; + padding: 1rem; + background: linear-gradient(135deg, #fff, #fdf3f3); + border-radius: 18px; + margin-top: 5rem; + width: 95%; + max-width: 600px; + margin-inline: auto; + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08); + border: 1px solid #ffe1e1; + animation: fadeSlide 0.35s ease; +} + +.filters-panel.active { + display: grid; +} + +/* 2 columns for bigger screens */ +@media (min-width: 768px) { + .filters-panel.active { + grid-template-columns: 1fr 1fr; + padding: 2rem; + border-radius: 22px; + } +} + +/* Filter groups */ +.filter-group { + display: flex; + flex-direction: column; + gap: 6px; + background: #fff; + padding: 10px 12px; + border-radius: 14px; + box-shadow: 0 2px 6px rgba(0,0,0,0.05); + transition: transform 0.2s ease; +} + +.filter-group:hover { + transform: translateY(-2px); +} + +/* Labels */ +.filter-group label { + font-weight: 600; + color: #ff5252; + font-size: 0.85rem; +} + +/* Inputs & dropdowns */ +.filter-group select, +.filter-group input { + padding: 8px 10px; + border: 2px solid #ffe1e1; + border-radius: 10px; + outline: none; + transition: all 0.3s ease; + font-size: 0.9rem; + background: #fff; + max-width: 100%; + appearance: none; +} + +.filter-group select:focus, +.filter-group input:focus { + border-color: var(--candy-red); + box-shadow: 0 0 8px rgba(255, 82, 82, 0.25); +} +/* Difficulty Filter */ +#difficultyFilter { + width: 100%; + max-width: 100%; + box-sizing: border-box; + font-size: 1rem; + padding: 10px 12px; +} + +/* Time Filter */ +#timeFilter { + width: 100%; + max-width: 100%; + box-sizing: border-box; + font-size: 1rem; + padding: 10px 12px; +} + +/* Dietary Filter */ +#dietaryFilter { + width: 100%; + max-width: 100%; + box-sizing: border-box; + font-size: 1rem; + padding: 10px 12px; +} + +/* Ingredient Filter (input box) */ +#ingredientFilter { + width: 100%; + max-width: 100%; + box-sizing: border-box; + font-size: 1rem; + padding: 10px 12px; +} + +/* Mobile specific tweaks */ +@media (max-width: 480px) { + #difficultyFilter, + #timeFilter, + #dietaryFilter, + #ingredientFilter { + font-size: 0.9rem; + padding: 8px 10px; + } +} +/* Mobile specific adjustments */ +@media (max-width: 480px) { + .filters-panel { + width: 100%; + max-width: 100%; + overflow-x: hidden; /* โœ… prevents horizontal scroll */ + } + + .filter-group select, + .filter-group input { + font-size: 0.9rem; + padding: 8px 10px; + } +} +/* Mobile responsiveness */ +@media (max-width: 480px) { + .filter-group label { + font-size: 0.8rem; /* smaller labels */ + } + + .filter-group select, + .filter-group input { + font-size: 0.9rem; /* text shrinks a bit */ + padding: 8px 10px; /* compact padding */ + } +} +/* Small animation */ +@keyframes fadeSlide { + from { + opacity: 0; + transform: translateY(-12px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Featured Sections */ +.featured-sections { + margin: 3rem 0; +} + +.section-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1.5rem; +} + +.section-title { + font-size: 2rem; + font-weight: bold; + color: #fff; + text-shadow: 2px 2px 4px rgba(0,0,0,0.5); +} + +.recipe-feed .section-title { + color: #333; + text-shadow: none; + background: linear-gradient(45deg, var(--candy-red), var(--sky-blue)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.view-all-btn { + background: rgba(255,255,255,0.9); + border: none; + padding: 10px 20px; + border-radius: 25px; + color: var(--candy-red); + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; +} + +.view-all-btn:hover { + background: #fff; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0,0,0,0.1); +} + +/* Recipe Carousel */ +.recipe-carousel { + display: flex; + gap: 1.5rem; + overflow-x: auto; + padding: 1rem 0; + scroll-behavior: smooth; + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ +} + +.recipe-carousel::-webkit-scrollbar { + display: none; /* Chrome, Safari, Opera */ +} + +.recipe-carousel .recipe-card { + min-width: 300px; + flex-shrink: 0; +} + +.recipe-carousel::-webkit-scrollbar { + height: 8px; +} + +.recipe-carousel::-webkit-scrollbar-track { + background: rgba(255,255,255,0.2); + border-radius: 10px; +} + +.recipe-carousel::-webkit-scrollbar-thumb { + background: var(--candy-red); + border-radius: 10px; +} + +/* Recipe Feed */ +.recipe-feed { + background: rgba(255,255,255,0.9); + backdrop-filter: blur(15px); + border-radius: 20px; + padding: 2rem; + box-shadow: 0 8px 30px rgba(0,0,0,0.1); +} + +.sort-options select { + padding: 8px 16px; + border: 2px solid #e9ecef; + border-radius: 10px; + background: white; + color: #333; + font-weight: 500; + cursor: pointer; + outline: none; +} + +.sort-options select:focus { + border-color: var(--candy-red); +} + +/* Recipe Grid */ +.recipe-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 2rem; + margin-top: 2rem; +} + +/* Recipe Card */ +.recipe-card { + background: #fff; + border-radius: 20px; + overflow: hidden; + box-shadow: 0 8px 25px rgba(0,0,0,0.1); + transition: all 0.3s ease; + position: relative; +} + +.recipe-card:hover { + transform: translateY(-8px); + box-shadow: 0 15px 40px rgba(0,0,0,0.15); +} + +.recipe-image-container { + position: relative; + height: 200px; + overflow: hidden; +} + +.recipe-image { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.3s ease; + background: linear-gradient(135deg, var(--soft-pink), var(--lavender)); +} + +.recipe-image:not([src]), +.recipe-image[src=""] { + background: linear-gradient(135deg, var(--soft-pink), var(--lavender)); + display: flex; + align-items: center; + justify-content: center; +} + +.recipe-image:not([src])::before, +.recipe-image[src=""]::before { + content: "๐Ÿฐ"; + font-size: 3rem; + opacity: 0.7; +} + +.creator-avatar { + width: 32px; + height: 32px; + border-radius: 50%; + object-fit: cover; + background: linear-gradient(135deg, var(--sky-blue), var(--mint-green)); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: bold; + font-size: 0.8rem; +} + +.creator-avatar:not([src]), +.creator-avatar[src=""] { + background: linear-gradient(135deg, var(--sky-blue), var(--mint-green)); +} + +.creator-avatar:not([src])::before, +.creator-avatar[src=""]::before { + content: "๐Ÿ‘ค"; + font-size: 1rem; +} + +.recipe-card:hover .recipe-image { + transform: scale(1.05); +} + +.recipe-overlay { + position: absolute; + top: 10px; + left: 10px; + right: 10px; + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +.recipe-difficulty { + background: rgba(0,0,0,0.7); + color: white; + padding: 4px 8px; + border-radius: 12px; + font-size: 0.8rem; + font-weight: 600; +} + +.recipe-difficulty.easy { background: var(--mint-green); color: #333; } +.recipe-difficulty.medium { background: var(--sunny-yellow); color: #333; } +.recipe-difficulty.hard { background: var(--candy-red); } + +.recipe-time { + background: rgba(0,0,0,0.7); + color: white; + padding: 4px 8px; + border-radius: 12px; + font-size: 0.8rem; + display: flex; + align-items: center; + gap: 4px; +} + +.save-btn { + position: absolute; + top: 10px; + right: 80px; + background: rgba(255,255,255,0.9); + border: none; + width: 40px; + height: 30px; + border-radius: 50%; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; +} + +.save-btn:hover { + background: var(--candy-red); + color: white; + transform: scale(1.1); +} + +.save-btn.saved { + background: var(--candy-red); + color: white; +} + +/* Recipe Content */ +.recipe-content { + padding: 1.5rem; +} + +.recipe-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 0.5rem; +} + +.recipe-title { + font-size: 1.3rem; + font-weight: bold; + color: #333; + margin: 0; + line-height: 1.2; +} + +.recipe-rating { + display: flex; + align-items: center; + gap: 5px; +} + +.stars { + display: flex; + gap: 2px; +} + +.star { + color: #ddd; + font-size: 1rem; +} + +.star.filled { + color: var(--sunny-yellow); +} + +.rating-count { + font-size: 0.8rem; + color: #666; +} + +.recipe-description { + color: #666; + margin: 0.5rem 0 1rem 0; + line-height: 1.4; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.recipe-creator { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 1rem; + padding-bottom: 1rem; + border-bottom: 1px solid #eee; +} + +.creator-name { + font-weight: 600; + color: #333; + flex: 1; +} + +.follow-btn { + background: var(--sky-blue); + color: white; + border: none; + padding: 4px 12px; + border-radius: 15px; + font-size: 0.8rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; +} + +.follow-btn:hover { + background: #3dbeb5; + transform: translateY(-1px); +} + +.follow-btn.following { + background: #6c757d; +} + +/* Recipe Actions */ +.recipe-actions { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; +} + +.action-btn { + background: none; + border: none; + cursor: pointer; + display: flex; + align-items: center; + gap: 5px; + padding: 8px; + border-radius: 10px; + transition: all 0.3s ease; + color: #666; + font-size: 0.9rem; +} + +.action-btn:hover { + background: #f8f9fa; + color: #333; + transform: translateY(-2px); +} + +.like-btn:hover { color: var(--candy-red); } +.comment-btn:hover { color: var(--sky-blue); } +.share-btn:hover { color: var(--mint-green); } +.copy-btn:hover { color: var(--sunny-yellow); } + +.like-btn.liked { + color: var(--candy-red); +} + +.action-btn .count { + font-size: 0.8rem; + font-weight: 600; +} + +/* Recipe Tags */ +.recipe-tags { + display: flex; + flex-wrap: wrap; + gap: 5px; +} + +.recipe-tag { + background: var(--lavender); + color: #6c5ce7; + padding: 2px 8px; + border-radius: 10px; + font-size: 0.7rem; + font-weight: 600; +} + +/* Load More */ +.load-more-container { + text-align: center; + margin-top: 3rem; +} + +.load-more-btn { + background: var(--gradient-primary); + color: white; + border: none; + padding: 15px 30px; + border-radius: 50px; + font-size: 1.1rem; + font-weight: bold; + cursor: pointer; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); +} + +.load-more-btn:hover { + transform: translateY(-3px); + box-shadow: 0 8px 25px rgba(0,0,0,0.15); +} + +/* Responsive Design */ +@media (max-width: 768px) { + .navbar { + padding: 10px 15px; + } + + .hero-title { + font-size: 2.5rem; + } + + .hero-subtitle { + font-size: 1rem; + } + + .search-bar { + flex-direction: column; + gap: 10px; + align-items: stretch; + } + + .filter-toggle-btn { + margin: 0; + } + + .filters-panel { + grid-template-columns: 1fr; + } + + .recipe-grid { + grid-template-columns: 1fr; + gap: 1.5rem; + } + + .section-header { + flex-direction: column; + gap: 1rem; + align-items: flex-start; + } + + .recipe-header { + flex-direction: column; + gap: 0.5rem; + align-items: flex-start; + } + + .nav-links { + gap: 15px; + } + + .nav-links li a { + font-size: 0.9rem; + } + + .navbar-container { + padding: 0 10px; + } + + .container { + padding: 0 15px; + } +} + +@media (max-width: 480px) { + .hero-title { + font-size: 2rem; + } + + .recipe-actions { + flex-wrap: wrap; + gap: 5px; + } + + .action-btn { + padding: 6px; + font-size: 0.8rem; + } +} + + + +.footer { + background-color:#FFB6C1 ; + color: #fff; + padding: 40px 20px; + font-family: sans-serif; +} + +.footer-container { + max-width: 1200px; + margin: auto; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 30px; +} + +.footer h2 { + color: #ff7f50; +} + +.footer h3 { + margin-bottom: 10px; + color: #ff7f50; +} + +.footer p { + font-size: 14px; + line-height: 1.5; +} + +.footer-links ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-links ul li { + margin-bottom: 6px; +} + +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: color 0.3s; +} + +.footer-links ul li a:hover { + color: #ff7f50; +} + +.footer-newsletter input { + padding: 10px; + width: 100%; + margin-bottom: 10px; + border: none; + border-radius: 4px; +} + +.footer-newsletter button { + background-color: #ff7f50; + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background 0.3s; +} + +.footer-newsletter button:hover { + background-color: #ff956b; +} + +/* Social icons */ +.social-icons { + display: flex; + gap: 12px; + margin-top: 10px; +} + +.social-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + color: white; + font-size: 18px; + transition: transform 0.3s, opacity 0.3s; +} + +.social-icon:hover { + transform: scale(1.1); + opacity: 0.85; +} + +/* Specific brand colors */ +.social-icon.linkedin { background: #0077b5; } +.social-icon.github { background: #6e5494; } +.social-icon.email { background: #ff8800; } + +.footer-bottom { + text-align: center; + font-size: 14px; + margin-top: 30px; + border-top: 1px solid #333; + padding-top: 20px; +} + +/* Back to Top Button */ +#scrollTopBtn { + display: none; + position: fixed; + bottom: 30px; + right: 30px; + z-index: 99; + font-size: 30px; + border: none; + outline: none; + background: linear-gradient(45deg, #ff6ec7, #ffa07a, #87cefa); + color: black; + cursor: pointer; + padding: 7px 15px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + transition: all 0.3s ease; +} + +#scrollTopBtn:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(0,0,0,0.3); +} +/* Floating Tip Button */ +.tip-btn { + position: fixed; + bottom: 20px; + left: 20px; + background: linear-gradient(135deg, #ffb6c1, #ff69b4); /* candy pink */ + color: white; + border: none; + border-radius: 50%; + width: 55px; + height: 55px; + font-size: 1.3rem; /* smaller so bulb fits */ + display: flex; /* center emoji */ + align-items: center; + justify-content: center; + cursor: pointer; + box-shadow: 0 4px 10px rgba(0,0,0,0.2); + transition: transform 0.2s ease, box-shadow 0.2s ease; + z-index: 1000; +} + +.tip-btn:hover { + transform: scale(1.1) rotate(10deg); + background: linear-gradient(135deg, #ff69b4, #ff1493); + box-shadow: 0 0 12px #ff69b4, 0 0 20px #ff1493; +} + +/* Tip Popup Card */ +.tip-popup { + position: fixed; + bottom: 90px; + left: 20px; + background: #fff0f5; /* light candy pink */ + border: 2px solid #ff69b4; + border-radius: 16px; + padding: 15px 20px; + max-width: 250px; + box-shadow: 0 6px 16px rgba(0,0,0,0.2); + font-family: 'Comic Neue', cursive; + color: #333; + display: none; /* hidden by default */ + z-index: 1000; + animation: fadeIn 0.3s ease-in-out; + box-shadow: 0 6px 16px rgba(255,105,180,0.3); /* pinkish glow */ +} + + +.tip-popup p { + margin: 0; + font-size: 0.95rem; + line-height: 1.4; + color: #444; + padding-right: 22px; /* space for close button */ +} + +/* Close Button */ +.close-tip { + position: absolute; + top: 8px; + right: 8px; + background: transparent; + border: none; + color: #ff1493; + font-size: 14px; /* neat size */ + font-weight: bold; + cursor: pointer; + line-height: 1; + transition: transform 0.15s ease, color 0.15s ease; +} + +.close-tip:hover { + color: #ff007f; + +} + +/* Animation */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +}/* ============================= */ +/* Dark Theme Styling */ +/* ============================= */ +[data-theme="dark"] { + --bg-color: #121212; + --card-bg: #1e1e1e; + --text-color: #f1f1f1; + --muted-text: #b0b0b0; + --accent: #ff6b6b; + --border-color: #2c2c2c; + --btn-bg: #2a2a2a; + --btn-hover: #3a3a3a; +} + +/* Section */ +[data-theme="dark"] .recipe-feed { + background: var(--bg-color); + color: var(--text-color); +} + +/* Section Header */ +[data-theme="dark"] .section-header { + border-bottom: 1px solid var(--border-color); +} + +[data-theme="dark"] .section-title { + color: var(--accent); +} + +[data-theme="dark"] .sort-options select { + background: var(--card-bg); + color: var(--text-color); + border: 1px solid var(--border-color); + border-radius: 8px; + padding: 6px 10px; +} + +/* Recipe Card */ +[data-theme="dark"] .recipe-card { + background: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: 15px; + box-shadow: 0 4px 10px rgba(0,0,0,0.4); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +[data-theme="dark"] .recipe-card:hover { + transform: translateY(-3px); + box-shadow: 0 6px 15px rgba(0,0,0,0.6); +} + +/* Text */ +[data-theme="dark"] .recipe-title, +[data-theme="dark"] .creator-name { + color: var(--text-color); +} + +[data-theme="dark"] .recipe-description, +[data-theme="dark"] .rating-count, +[data-theme="dark"] .recipe-time span { + color: var(--muted-text); +} + +/* Overlay */ +[data-theme="dark"] .recipe-overlay { + /* background: linear-gradient(to top, rgba(18,18,18,0.9), rgba(18,18,18,0.1)); */ + color: var(--text-color); +} + +/* Buttons */ +[data-theme="dark"] .save-btn, +[data-theme="dark"] .follow-btn, +[data-theme="dark"] .action-btn { + background: rgba(0,0,0,0.8); /* or var(--btn-bg-dark) */ + color: var(--text-color); + border: 1px solid var(--border-color); + border-radius: 50%; /* Match light mode roundness */ + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; +} + +[data-theme="dark"] .save-btn:hover, +[data-theme="dark"] .follow-btn:hover, +[data-theme="dark"] .action-btn:hover { + background: var(--candy-red); + color: white; + transform: scale(1.1); +} + +[data-theme="dark"] .save-btn.saved { + background: var(--candy-red); + color: white; +} + +[data-theme="dark"] .follow-btn.following { + background: var(--sky-blue); + color: white; +} + +/* Tags */ +[data-theme="dark"] .recipe-tags span { + background: var(--btn-bg); + color: var(--text-color); + border-radius: 8px; + padding: 3px 8px; + margin: 2px; + font-size: 0.8rem; +} + +/* Load More Button */ +[data-theme="dark"] .load-more-btn { + background: var(--accent); + color: #fff; + border: none; + border-radius: 20px; + padding: 8px 16px; + transition: transform 0.2s ease; +} + +[data-theme="dark"] .load-more-btn:hover { + transform: translateY(-2px); + opacity: 0.9; +} \ No newline at end of file diff --git a/BakeGenuis-AI/css/scale.css b/BakeGenuis-AI/css/scale.css new file mode 100644 index 00000000..0c16bdae --- /dev/null +++ b/BakeGenuis-AI/css/scale.css @@ -0,0 +1,932 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + } +[data-theme="dark"] { + --bg-color: #121212; + --text-color: #ffffff; + + --body-gradient: linear-gradient(135deg, #121212 0%, #1f1f1f 50%, #2a2a3c 100%); + --navbar-gradient: linear-gradient(90deg, #222222, #111111, #333333); + --link-color: #ffffff; + --link-hover-gradient: linear-gradient(90deg, #bb86fc, #03dac6); + --cta-gradient: linear-gradient(45deg, #bb86fc, #03dac6); + --cta-text: #ffffff; + + --card-bg: rgba(42,42,60,0.85); + --card-hover-bg: rgba(50,50,70,0.95); + --card-shadow: rgba(0, 0, 0, 0.4); + --hero-bg: rgba(30,30,30,0.85); + --footer-bg: #1a1a1a; + --footer-text: #ffffff; +} + +/* Body */ +[data-theme="dark"] body { + background: var(--body-gradient); + color: var(--text-color); +} + +/* Navbar */ +[data-theme="dark"] .navbar { + background: var(--navbar-gradient); + box-shadow: 0 4px 20px rgba(187,134,252,0.4); + border-bottom: 1px solid rgba(187,134,252,0.2); +} + +[data-theme="dark"] .nav-links li a { + color: var(--link-color) !important; + text-shadow: 0 0 8px rgba(187,134,252,0.5); +} + +[data-theme="dark"] .nav-links li a:hover { + transform: translateY(-2px); + text-shadow: 0 0 12px rgba(187,134,252,0.8); +} + +/* Hero / Header */ +[data-theme="dark"] .header h1, +[data-theme="dark"] .header p { + color: #ffffff; +} + +/* Cards & Sections */ +[data-theme="dark"] .input-section, +[data-theme="dark"] .output-section, +[data-theme="dark"] .suggestions-box, +[data-theme="dark"] .feature-card, +[data-theme="dark"] .section-card, +[data-theme="dark"] .step-card { + background: linear-gradient(145deg, #2a2a3c, #33334d); + color: #e0e0e0; + border-radius: 15px; + padding: 1.5rem; + box-shadow: 0 8px 20px rgba(0,0,0,0.4); + backdrop-filter: blur(5px); +} + +[data-theme="dark"] .feature-title, +[data-theme="dark"] .feature-desc, +[data-theme="dark"] .section-title, +[data-theme="dark"] .section-content, +[data-theme="dark"] .step-title, +[data-theme="dark"] .step-description, +[data-theme="dark"] .step-number { + color: #f0f0f0; +} + +/* Inputs and Textareas */ +[data-theme="dark"] input, +[data-theme="dark"] textarea { + background: #2e2e3f; + color: #f0f0f0; + border: 2px solid #4ecdc4; + border-radius: 12px; + padding: 0.8rem 1rem; + font-family: 'Comic Neue', cursive; +} +/* Recipe input / textarea */ +[data-theme="dark"] .recipe-textarea, +[data-theme="dark"] .serving-input input { + background: #2e2e3f; /* dark but not black */ + color: #f0f0f0; /* white text */ + border: 2px solid #4ecdc4; /* highlight border */ +} + +[data-theme="dark"] .recipe-textarea::placeholder, +[data-theme="dark"] .serving-input input::placeholder { + color: #bbbbbb; /* visible placeholder */ +} + +[data-theme="dark"] input::placeholder, +[data-theme="dark"] textarea::placeholder { + color: #cccccc; +} + +[data-theme="dark"] input:focus, +[data-theme="dark"] textarea:focus { + outline: none; + border-color: #bb86fc; + box-shadow: 0 0 8px rgba(187,134,252,0.4); +} +/* Dark mode for recipe input section */ +[data-theme="dark"] .input-group label { + color: #ffffff; /* white text for label */ +} + +[data-theme="dark"] .input-group textarea { + background: #2e2e3f; /* darkish background */ + color: #ffffff; /* white text */ + border: 2px solid #4ecdc4; /* visible border */ +} + +[data-theme="dark"] .input-group textarea::placeholder { + color: #bbbbbb; /* placeholder visible */ +} +/* Buttons */ +[data-theme="dark"] .btn-primary { + background: var(--cta-gradient); + color: var(--cta-text); + box-shadow: 0 8px 25px rgba(0,0,0,0.5); +} + +[data-theme="dark"] .btn-secondary { + background: #444455; + color: #f0f0f0; + box-shadow: 0 5px 15px rgba(0,0,0,0.3); +} + +/* Feedback button */ +[data-theme="dark"] .fb-color { + padding: 8px 18px; + background: linear-gradient(135deg, rgba(245,115,197,0.9), rgba(190,8,245,0.7)); + border-radius: 25px; + border: 1px solid rgba(190, 8, 245, 0.3); + display: inline-block; + transition: all 0.3s ease; + box-shadow: 0 0 10px rgba(190, 8, 245, 0.3); +} + +[data-theme="dark"] .fb-color:hover { + background: linear-gradient(135deg, rgba(243,19,224,0.85), rgba(190,8,245,0.9)); + transform: scale(1.05); + box-shadow: 0 0 20px rgba(190, 8, 245, 0.6); +} + +[data-theme="dark"] .fb-color a { + color: #fff; +} + +/* Footer */ +[data-theme="dark"] .footer { + background: var(--footer-bg) !important; + color: var(--footer-text) !important; + box-shadow: 0 0 30px rgba(255,255,255,0.05); +} + +[data-theme="dark"] .footer-links ul li a, +[data-theme="dark"] .footer-text { + color: #e0e0e0 !important; +} +[data-theme="dark"] .footer-links ul li a:hover { + color: #ff7f50 !important; +} + body { + font-family: 'Comic Neue', cursive; + background: linear-gradient(135deg, #FF6B6B 0%, #4ECDC4 50%, #FFE66D 100%); + min-height: 100vh; + position: relative; + overflow-x: hidden; + } + /* Dark-Light Toggle Slider */ +.theme-switch { + position: relative; + display: inline-block; + width: 50px; + height: 26px; +} + +.theme-switch input { + display: none; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; left: 0; right: 0; bottom: 0; + background: #ccc; + border-radius: 34px; + transition: 0.4s; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 5px; + font-size: 10px; + color: #fff; +} + +.slider:before { + content: ""; + position: absolute; + height: 18px; + width: 18px; + left: 4px; + bottom: 4px; + background: white; + border-radius: 50%; + transition: 0.4s; +} + +/* When checked (dark mode) */ +.theme-switch input:checked + .slider { + background: #4ECDC4; /* you can use any gradient if you want */ +} + +.theme-switch input:checked + .slider:before { + transform: translateX(24px); +} + /* Animated Background Elements */ + .floating-elements { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + } + + .floating-cupcake { + position: absolute; + font-size: 2rem; + animation: float 6s ease-in-out infinite; + } + + .floating-cupcake:nth-child(1) { top: 10%; left: 10%; animation-delay: 0s; } + .floating-cupcake:nth-child(2) { top: 20%; right: 15%; animation-delay: 2s; } + .floating-cupcake:nth-child(3) { bottom: 30%; left: 20%; animation-delay: 4s; } + .floating-cupcake:nth-child(4) { bottom: 15%; right: 10%; animation-delay: 1s; } + + @keyframes float { + 0%, 100% { transform: translateY(0px) rotate(0deg); } + 50% { transform: translateY(-20px) rotate(5deg); } + } + + /* Navigation */ + /* Navbar Base */ +.navbar { + width: 100%; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); /* light blue โ†’ light pink โ†’ soft yellow */ + padding: 12px 20px; + position: sticky; + top: 0; + z-index: 1000; + box-shadow: 0 4px 15px rgba(0,0,0,0.08); +} + +.navbar-container { + display: flex; + justify-content: space-between; + align-items: center; + max-width: 1200px; + margin: auto; +} + +/* Logo */ +.logo { + font-size: 1.5rem; + font-weight: bold; + color: #ffffff; + letter-spacing: 1px; +} + +.logo a{ + text-decoration: none; + color: #fff; +} + +/* Nav Links */ +.nav-links { + display: flex; + list-style: none; + gap: 25px; +} + +.nav-links li a { + color: #ffffff; + font-weight: 500; + text-decoration: none; + position: relative; + transition: all 0.3s ease-in-out; + padding: 5px 0; +} + +/* Hover Gradient Underline */ +.nav-links li a::after { + content: ""; + position: absolute; + left: 0; + bottom: -4px; + width: 0%; + height: 3px; + background: linear-gradient(90deg, #60a5fa, #f9a8d4, #fde68a); + border-radius: 5px; + transition: width 0.4s ease; +} + +.nav-links li a:hover::after, +.nav-links li a.active::after { + width: 100%; +} + +.nav-links li a:hover { + transform: translateY(-2px); +} +.fb-color { + padding: 8px 15px; + background-color: rgba(238, 255, 0, 0.356); + border-radius: 20px; + border: black 1px solid; +} +.fb-color:hover{ + background-color: rgba(169, 196, 13, 0.39); +} +.fb-color a { + color: black; + text-decoration: none; +} + +/* CTA Button */ +.cta-btn { + padding: 10px 20px; + background: linear-gradient(45deg, #60a5fa, #f9a8d4, #fde68a); + color: #ffffff; + font-weight: bold; + text-decoration: none; + border-radius: 30px; + transition: all 0.4s ease; + box-shadow: 0 4px 12px rgba(0,0,0,0.12); +} + +.cta-btn:hover { + transform: scale(1.08); + box-shadow: 0 6px 20px rgba(0,0,0,0.2); +} + +/* Scale Now Navigation Button */ +.scale-nav-btn { + background: linear-gradient(45deg, #60a5fa, #fde68a) !important; + color: #ffffff !important; + padding: 8px 16px !important; + border-radius: 20px !important; + font-weight: 600 !important; + text-decoration: none !important; + transition: all 0.3s ease !important; + box-shadow: 0 2px 8px rgba(96, 165, 250, 0.3) !important; + display: inline-block !important; +} + +.scale-nav-btn:hover { + transform: translateY(-2px) scale(1.05) !important; + box-shadow: 0 4px 12px rgba(96, 165, 250, 0.4) !important; +} + +.scale-nav-btn::after { + display: none !important; +} + +/* User Info Display */ +.user-info { + display: flex; + align-items: center; + gap: 1rem; + color: #ffffff; + font-weight: 600; +} + +.user-avatar { + width: 40px; + height: 40px; + background-color: coral; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.2rem; + color: white; +} + +.logout-btn { + background: linear-gradient(45deg, #ff4757, #ff3838) !important; + color: #ffffff; + border: none !important; + padding: 0.5rem 1rem; + border-radius: 20px; + font-family: 'Comic Neue', cursive; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + font-size: 0.9rem; + box-shadow: 0 2px 8px rgba(255, 71, 87, 0.3) !important; +} + +.logout-btn:hover { + background: linear-gradient(45deg, #ff3838, #ff2d2d) !important; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(255, 71, 87, 0.4) !important; +} + + /* Main Container */ + .container { + max-width: 1200px; + margin: 0 auto; + padding: 1rem 2rem 2rem; + position: relative; + z-index: 10; + } + + /* Header Section */ + .header { + text-align: center; + margin-bottom: 3rem; + } + + .header h1 { + font-size: 3rem; + color: white; + text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); + margin-bottom: 1rem; + animation: bounce 2s infinite; + } + + @keyframes bounce { + 0%, 20%, 50%, 80%, 100% { transform: translateY(0); } + 40% { transform: translateY(-10px); } + 60% { transform: translateY(-5px); } + } + + .header p { + font-size: 1.3rem; + color: rgba(255, 255, 255, 0.9); + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3); + } + + /* Main Content */ + .main-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2rem; + margin-bottom: 2rem; + } + + .input-section, .output-section { + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + padding: 2rem; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + } + + .section-title { + font-size: 1.8rem; + color: #FF6B6B; + margin-bottom: 1.5rem; + text-align: center; + position: relative; + } + + .section-title::after { + content: ''; + position: absolute; + bottom: -5px; + left: 50%; + transform: translateX(-50%); + width: 50px; + height: 3px; + background: #4ECDC4; + border-radius: 2px; + } + + /* Input Elements */ + .input-group { + margin-bottom: 1.5rem; + } + + .input-group label { + display: block; + font-weight: 600; + color: #333; + margin-bottom: 0.5rem; + font-size: 1.1rem; + } + + .serving-inputs { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + margin-bottom: 1.5rem; + } + + .serving-input { + position: relative; + } + + .serving-input input { + width: 100%; + padding: 1rem; + border: 3px solid #FFE66D; + border-radius: 15px; + font-size: 1.1rem; + font-family: 'Comic Neue', cursive; + text-align: center; + transition: all 0.3s ease; + } + + .serving-input input:focus { + outline: none; + border-color: #4ECDC4; + transform: scale(1.05); + box-shadow: 0 5px 15px rgba(78, 205, 196, 0.3); + } + + .recipe-textarea { + width: 100%; + min-height: 200px; + padding: 1rem; + border: 3px solid #FFE66D; + border-radius: 15px; + font-size: 1rem; + font-family: 'Comic Neue', cursive; + resize: vertical; + transition: all 0.3s ease; + } + + .recipe-textarea:focus { + outline: none; + border-color: #4ECDC4; + box-shadow: 0 5px 15px rgba(78, 205, 196, 0.3); + } + + /* Buttons */ + .btn-group { + display: flex; + gap: 1rem; + justify-content: center; + margin-top: 1.5rem; + } + + .btn { + padding: 1rem 2rem; + border: none; + border-radius: 25px; + font-size: 1.1rem; + font-weight: 600; + font-family: 'Comic Neue', cursive; + cursor: pointer; + transition: all 0.3s ease; + position: relative; + overflow: hidden; + } + + .btn-primary { + background: linear-gradient(45deg, #FF6B6B, #4ECDC4); + color: white; + box-shadow: 0 5px 15px rgba(255, 107, 107, 0.3); + } + + .btn-primary:hover { + transform: translateY(-3px); + box-shadow: 0 10px 25px rgba(255, 107, 107, 0.4); + animation: shimmer 1s ease-in-out; + } + + @keyframes shimmer { + 0% { background-position: -200% center; } + 100% { background-position: 200% center; } + } + + .btn-secondary { + background: #FFE66D; + color: #333; + box-shadow: 0 5px 15px rgba(255, 230, 109, 0.3); + } + + .btn-secondary:hover { + background: #FFD93D; + transform: translateY(-3px); + } + + /* Toggle Switch */ + .toggle-container { + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + margin: 1rem 0; + } + + .toggle-switch { + position: relative; + display: inline-block; + width: 60px; + height: 34px; + } + + .toggle-switch input { + opacity: 0; + width: 0; + height: 0; + } + + .slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: .4s; + border-radius: 34px; + } + + .slider:before { + position: absolute; + content: ""; + height: 26px; + width: 26px; + left: 4px; + bottom: 4px; + background-color: white; + transition: .4s; + border-radius: 50%; + } + + input:checked + .slider { + background-color: #4ECDC4; + } + + input:checked + .slider:before { + transform: translateX(26px); + } + + /* Results Section */ + .results-container { + display: none; + } + + .results-container.show { + display: block; + animation: fadeInUp 0.5s ease-out; + } + + @keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + .results-table { + width: 100%; + border-collapse: collapse; + margin-top: 1rem; + background: white; + border-radius: 15px; + overflow: hidden; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); + } + + .results-table th, + .results-table td { + padding: 1rem; + text-align: left; + border-bottom: 1px solid #f0f0f0; + } + + .results-table th { + background: linear-gradient(45deg, #FF6B6B, #4ECDC4); + color: white; + font-weight: 600; + } + + .results-table tr:hover { + background-color: #f8f9fa; + } + + .ingredient-icon { + font-size: 1.5rem; + margin-right: 0.5rem; + } + + /* Suggestions Box */ + .suggestions-box { + background: rgba(255, 230, 109, 0.2); + border: 2px solid #FFE66D; + border-radius: 15px; + padding: 1.5rem; + margin-top: 1rem; + } + + .suggestions-box h3 { + color: #FF6B6B; + margin-bottom: 1rem; + font-size: 1.3rem; + } + + .suggestions-box p { + color: #333; + line-height: 1.6; + margin-bottom: 0.5rem; + } + + /* Loading Animation */ + .loading { + display: none; + text-align: center; + padding: 2rem; + } + + .loading.show { + display: block; + } + + .spinner { + width: 50px; + height: 50px; + border: 5px solid #f3f3f3; + border-top: 5px solid #FF6B6B; + border-radius: 50%; + animation: spin 1s linear infinite; + margin: 0 auto 1rem; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + /* Responsive Design */ + @media (max-width: 768px) { + .navbar { + padding: 10px 15px; + } + + .nav-links { + flex-direction: column; + gap: 0.5rem; + } + + .main-content { + grid-template-columns: 1fr; + gap: 1rem; + } + + .serving-inputs { + grid-template-columns: 1fr; + } + + .header h1 { + font-size: 2rem; + } + + .container { + padding: 1rem; + } + + .btn-group { + flex-direction: column; + } + } + + @media (max-width: 480px) { + .nav-container { + flex-direction: column; + gap: 1rem; + } + + .nav-links { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + } + } + + +.footer { + background-color: #FFB6C1; + color: #fff; + padding: 40px 20px; + font-family: sans-serif; +} + +.footer-container { + max-width: 1200px; + margin: auto; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 30px; +} + +.footer h2 { + color: #ff7f50; +} + +.footer h3 { + margin-bottom: 10px; + color: #ff7f50; +} + +.footer p { + font-size: 14px; + line-height: 1.5; +} + +.footer-links ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-links ul li { + margin-bottom: 6px; +} + +.footer-links ul li a { + color: #fff; + text-decoration: none; + transition: color 0.3s; +} + +.footer-links ul li a:hover { + color: #ff7f50; +} + +.footer-newsletter input { + padding: 10px; + width: 100%; + margin-bottom: 10px; + border: none; + border-radius: 4px; +} + +.footer-newsletter button { + background-color: #ff7f50; + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background 0.3s; +} + +.footer-newsletter button:hover { + background-color: #ff956b; +} + +/* Social icons */ +.social-icons { + display: flex; + gap: 12px; + margin-top: 10px; +} + +.social-icon { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + color: white; + font-size: 18px; + transition: transform 0.3s, opacity 0.3s; +} + +.social-icon:hover { + transform: scale(1.1); + opacity: 0.85; +} + +/* Specific brand colors */ +.social-icon.linkedin { background: #0077b5; } +.social-icon.github { background: #6e5494; } +.social-icon.email { background: #ff8800; } + +.footer-bottom { + text-align: center; + font-size: 14px; + margin-top: 30px; + border-top: 1px solid #333; + padding-top: 20px; +} + +/* Back to Top Button */ +#scrollTopBtn { + display: none; + position: fixed; + bottom: 30px; + right: 30px; + z-index: 99; + font-size: 20px; + border: none; + outline: none; + background: linear-gradient(45deg, #ff6ec7, #ffa07a, #ffd700, #87cefa); + color: white; + cursor: pointer; + padding: 15px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0,0,0,0.2); + transition: all 0.3s ease; +} + +#scrollTopBtn:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(0,0,0,0.3); +} diff --git a/BakeGenuis-AI/css/toast.css b/BakeGenuis-AI/css/toast.css new file mode 100644 index 00000000..6b4e1b73 --- /dev/null +++ b/BakeGenuis-AI/css/toast.css @@ -0,0 +1,141 @@ +/* Toast Styles */ +.toast-container { + position: fixed; + top: 20px; + right: 20px; + z-index: 9999; + display: flex; + flex-direction: column; + gap: 10px; + max-width: 400px; +} + +.toast { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 16px 20px; + border-radius: 12px; + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); + transform: translateX(400px); + opacity: 0; + transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55); + display: flex; + align-items: center; + gap: 12px; + position: relative; + overflow: hidden; + font-family: 'Comic Neue', cursive; + font-size: 14px; + line-height: 1.4; +} + +.toast.show { + transform: translateX(0); + opacity: 1; +} + +.toast.success { + background: linear-gradient(135deg, #4ecdc4 0%, #44a08d 100%); +} + +.toast.error { + background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); +} + +.toast.warning { + background: linear-gradient(135deg, #feca57 0%, #ff9ff3 100%); +} + +.toast.info { + background: linear-gradient(135deg, #74b9ff 0%, #0984e3 100%); +} + +.toast-icon { + font-size: 20px; + flex-shrink: 0; +} + +.toast-content { + flex: 1; +} + +.toast-title { + font-weight: 700; + margin: 0 0 4px 0; + font-size: 15px; +} + +.toast-message { + margin: 0; + opacity: 0.9; + font-size: 13px; +} + +.toast-close { + background: none; + border: none; + color: white; + cursor: pointer; + font-size: 18px; + padding: 0; + margin-left: 8px; + opacity: 0.7; + transition: opacity 0.2s; + flex-shrink: 0; +} + +.toast-close:hover { + opacity: 1; +} + +.toast-progress { + position: absolute; + bottom: 0; + left: 0; + height: 3px; + background: rgba(255, 255, 255, 0.3); + width: 100%; + transform-origin: left; + animation: toast-progress 5s linear forwards; +} + +@keyframes toast-progress { + from { + transform: scaleX(1); + } + to { + transform: scaleX(0); + } +} + +/* Mobile responsiveness */ +@media (max-width: 768px) { + .toast-container { + top: 10px; + right: 10px; + left: 10px; + max-width: none; + } + + .toast { + transform: translateY(-100px); + margin: 0; + } + + .toast.show { + transform: translateY(0); + } +} + +/* Animation for multiple toasts */ +.toast:nth-child(2) { + animation-delay: 0.1s; +} + +.toast:nth-child(3) { + animation-delay: 0.2s; +} + +.toast:nth-child(4) { + animation-delay: 0.3s; +} \ No newline at end of file diff --git a/BakeGenuis-AI/css/toggle.css b/BakeGenuis-AI/css/toggle.css new file mode 100644 index 00000000..9b3db5f3 --- /dev/null +++ b/BakeGenuis-AI/css/toggle.css @@ -0,0 +1,65 @@ +/* Make toggle show properly on all screen sizes */ +.nav-links li .theme-switch { + display: flex !important; + align-items: center; + justify-content: center; + margin-left: auto; /* pushes toggle to the right on big screens */ +} + +/* On small screens, make it wrap nicely */ +@media (max-width: 768px) { + .nav-links { + flex-wrap: wrap; /* allow items to go to next line */ + justify-content: flex-start; /* align items nicely */ + gap: 15px; + } + + .nav-links li .theme-switch { + margin-left: 0; /* remove auto margin on small screens */ + width: 100%; /* full width so itโ€™s not squeezed */ + justify-content: flex-start; /* toggle aligns left */ + margin-top: 10px; /* spacing below links */ + } +} +/* Always show toggle */ +.nav-links li .theme-switch { + display: flex !important; + align-items: center; + justify-content: center; +} + +/* Mobile fix */ +@media (max-width: 768px) { + .nav-links { + flex-wrap: wrap; + justify-content: flex-start; + gap: 15px; + } + + .nav-links li .theme-switch { + width: 100%; + order: 99; /* push it to the next line */ + margin-top: 10px; + justify-content: flex-start; + } +} +/* Make sure toggle is always visible */ +.theme-switch { + display: flex; + align-items: center; + justify-content: center; + margin-left: 15px; +} + +/* On small screens force toggle to stay visible */ +@media (max-width: 768px) { + .navbar-container { + flex-wrap: wrap; /* so it doesnโ€™t overflow */ + justify-content: space-between; /* spread logo vs. toggle */ + } + + .theme-switch { + order: 3; /* push toggle below nav links */ + margin: 10px auto 0; /* center on mobile */ + } +} diff --git a/BakeGenuis-AI/favicon-16x16.png b/BakeGenuis-AI/favicon-16x16.png new file mode 100644 index 00000000..ae6ad67b Binary files /dev/null and b/BakeGenuis-AI/favicon-16x16.png differ diff --git a/BakeGenuis-AI/favicon-32x32.png b/BakeGenuis-AI/favicon-32x32.png new file mode 100644 index 00000000..66cf0907 Binary files /dev/null and b/BakeGenuis-AI/favicon-32x32.png differ diff --git a/BakeGenuis-AI/favicon.ico b/BakeGenuis-AI/favicon.ico new file mode 100644 index 00000000..6568f7a0 Binary files /dev/null and b/BakeGenuis-AI/favicon.ico differ diff --git a/BakeGenuis-AI/gssoc logo.png b/BakeGenuis-AI/gssoc logo.png new file mode 100644 index 00000000..c01f8514 Binary files /dev/null and b/BakeGenuis-AI/gssoc logo.png differ diff --git a/BakeGenuis-AI/html/about.html b/BakeGenuis-AI/html/about.html new file mode 100644 index 00000000..7bb4524c --- /dev/null +++ b/BakeGenuis-AI/html/about.html @@ -0,0 +1,279 @@ + + + + + + About Us - BakeGenius.ai + + + + + + + + + + + +
+ +
+
๐Ÿง
+
๐Ÿฐ
+
๐Ÿฅง
+
๐Ÿช
+
๐Ÿฅ„
+
โš–๏ธ
+ + +
+
+ + + + + + + + +
+

About BakeGenius.ai

+

+ Revolutionizing baking with AI-powered precision +

+
+ + +
+ +
+
+ ๐Ÿง +

What is BakeGenius.ai?

+
+
+

+ BakeGenius.ai is an AI-powered baking assistant that transforms + vague recipe instructions like "1 cup of flour" into precise + gram-based conversions. Whether you're a home baker discovering + the joy of perfect cookies or a professional pastry chef crafting + delicate macarons, BakeGenius helps you achieve consistent, + restaurant-quality results every single time. +

+
+

+ Our advanced artificial intelligence understands the nuances of + baking ingredients, recognizing that "1 cup of sifted flour" + weighs differently than "1 cup of packed flour." By combining + cutting-edge natural language processing with real-world + ingredient databases, we've created the most accurate baking + conversion tool available today. +

+
+
+ + +
+
๐Ÿ‘ฉโ€๐Ÿ’ป
+

Supriya Pandey

+

AI Engineer & Passionate Baker

+
+

+ Hi there! I'm Supriya, and I created BakeGenius.ai from my own + frustration with inconsistent baking results. As someone + passionate about both artificial intelligence and the art of + baking, I realized that the precision we demand in machine + learning should also exist in our kitchens. +

+
+

+ After countless failed attempts at scaling my grandmother's cookie + recipe and watching friends struggle with international recipes, I + decided to combine my expertise in AI and web development to solve + this problem once and for all. BakeGenius.ai represents the + intersection of cutting-edge technology and timeless baking + traditions. +

+
+

+ When I'm not coding or training AI models, you'll find me in my + kitchen testing new recipes and perfecting the algorithms that + power BakeGenius. My mission is to make professional-quality + baking accessible to everyone, one gram at a time. +

+
+
+ +
+
+ ๐Ÿ‘ฉโ€๐Ÿ’ป + Our Contributors +
+ +
+
+
+
+ +
+ + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/about_BACKUP_1224.html b/BakeGenuis-AI/html/about_BACKUP_1224.html new file mode 100644 index 00000000..c22ca9c5 --- /dev/null +++ b/BakeGenuis-AI/html/about_BACKUP_1224.html @@ -0,0 +1,178 @@ + + + + + + About Us - BakeGenius.ai + + + + + + + +
+
๐Ÿง
+
๐Ÿฐ
+
๐Ÿฅง
+
๐Ÿช
+
๐Ÿฅ„
+
โš–๏ธ
+ + +
+
+ + +<<<<<<< Updated upstream + +======= + +>>>>>>> Stashed changes + + + + + +
+

About BakeGenius.ai

+

Revolutionizing baking with AI-powered precision

+
+ + +
+ +
+
+ ๐Ÿง +

What is BakeGenius.ai?

+
+
+

BakeGenius.ai is an AI-powered baking assistant that transforms vague recipe instructions like "1 cup of flour" into precise gram-based conversions. Whether you're a home baker discovering the joy of perfect cookies or a professional pastry chef crafting delicate macarons, BakeGenius helps you achieve consistent, restaurant-quality results every single time.

+
+

Our advanced artificial intelligence understands the nuances of baking ingredients, recognizing that "1 cup of sifted flour" weighs differently than "1 cup of packed flour." By combining cutting-edge natural language processing with real-world ingredient databases, we've created the most accurate baking conversion tool available today.

+
+
+ + +
+
๐Ÿ‘ฉโ€๐Ÿ’ป
+

Supriya Pandey

+

AI Engineer & Passionate Baker

+
+

Hi there! I'm Supriya, and I created BakeGenius.ai from my own frustration with inconsistent baking results. As someone passionate about both artificial intelligence and the art of baking, I realized that the precision we demand in machine learning should also exist in our kitchens.

+
+

After countless failed attempts at scaling my grandmother's cookie recipe and watching friends struggle with international recipes, I decided to combine my expertise in AI and web development to solve this problem once and for all. BakeGenius.ai represents the intersection of cutting-edge technology and timeless baking traditions.

+
+

When I'm not coding or training AI models, you'll find me in my kitchen testing new recipes and perfecting the algorithms that power BakeGenius. My mission is to make professional-quality baking accessible to everyone, one gram at a time.

+
+
+ +
+
+ ๐Ÿ‘ฉโ€๐Ÿ’ป + Our Contributors +
+ +
+
+
+ + +
+ + +
+ + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/about_BASE_1224.html b/BakeGenuis-AI/html/about_BASE_1224.html new file mode 100644 index 00000000..f70b92ed --- /dev/null +++ b/BakeGenuis-AI/html/about_BASE_1224.html @@ -0,0 +1,200 @@ + + + + + + About Us - BakeGenius.ai + + + + + + +
+
๐Ÿง
+
๐Ÿฐ
+
๐Ÿฅง
+
๐Ÿช
+
๐Ÿฅ„
+
โš–๏ธ
+ + +
+
+ + + + + + + + +
+

About BakeGenius.ai

+

Revolutionizing baking with AI-powered precision

+
+ + +
+ +
+
+ ๐Ÿง +

What is BakeGenius.ai?

+
+
+

BakeGenius.ai is an AI-powered baking assistant that transforms vague recipe instructions like "1 cup of flour" into precise gram-based conversions. Whether you're a home baker discovering the joy of perfect cookies or a professional pastry chef crafting delicate macarons, BakeGenius helps you achieve consistent, restaurant-quality results every single time.

+
+

Our advanced artificial intelligence understands the nuances of baking ingredients, recognizing that "1 cup of sifted flour" weighs differently than "1 cup of packed flour." By combining cutting-edge natural language processing with real-world ingredient databases, we've created the most accurate baking conversion tool available today.

+
+
+ + +
+
+ ๐ŸŽฏ +

What Problem Does It Solve?

+
+
+

Baking is a science, but traditional recipes treat it like guesswork. Here are the critical problems we solve:

+
    +
  • Recipes use non-standard, volume-based units that vary wildly between regions and measuring tools
  • +
  • "1 cup" means different weights for different people, leading to failed batches and wasted ingredients
  • +
  • Inconsistent baking results, especially in sensitive recipes like soufflรฉs, macarons, and artisan breads
  • +
  • Professional bakers can't scale home recipes reliably without precise measurements
  • +
  • International recipe sharing is nearly impossible due to measurement system differences
  • +
+
+

BakeGenius uses AI and real-world density data to eliminate these problems forever. No more failed batches, no more guesswork โ€“ just perfect, consistent baking results every time.

+
+
+ + +
+
+ ๐Ÿ› ๏ธ +

How Does It Work?

+
+
+

Our sophisticated AI system combines multiple technologies to deliver unparalleled accuracy:

+ +
+
+
1
+
Natural Language Processing
+
Our Gemini AI analyzes your recipe text, understanding context, ingredient types, and measurement nuances like "heaped," "packed," or "sifted."
+
+ +
+
2
+
Ingredient Normalization
+
The system identifies and standardizes ingredients, converting "AP flour" to "All-purpose flour" and understanding regional variations and brand differences.
+
+ +
+
3
+
Precise Conversion
+
Using our comprehensive density database, we convert measurements to grams with scientific precision, accounting for ingredient preparation methods.
+
+ +
+
4
+
Smart Customization
+
Our platform learns your preferences, remembers brand-specific adjustments, and allows fine-tuning for your specific baking style and ingredients.
+
+
+ +

The result? Professional-grade precision that transforms your baking from hit-or-miss to consistently perfect. Whether you're scaling a recipe for 2 people or 200, BakeGenius ensures every batch turns out exactly as intended.

+
+
+ + +
+
๐Ÿ‘ฉโ€๐Ÿ’ป
+

Supriya Pandey

+

AI Engineer & Passionate Baker

+
+

Hi there! I'm Supriya, and I created BakeGenius.ai from my own frustration with inconsistent baking results. As someone passionate about both artificial intelligence and the art of baking, I realized that the precision we demand in machine learning should also exist in our kitchens.

+
+

After countless failed attempts at scaling my grandmother's cookie recipe and watching friends struggle with international recipes, I decided to combine my expertise in AI and web development to solve this problem once and for all. BakeGenius.ai represents the intersection of cutting-edge technology and timeless baking traditions.

+
+

When I'm not coding or training AI models, you'll find me in my kitchen testing new recipes and perfecting the algorithms that power BakeGenius. My mission is to make professional-quality baking accessible to everyone, one gram at a time.

+
+
+ +
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/about_LOCAL_1224.html b/BakeGenuis-AI/html/about_LOCAL_1224.html new file mode 100644 index 00000000..affe2a7a --- /dev/null +++ b/BakeGenuis-AI/html/about_LOCAL_1224.html @@ -0,0 +1,153 @@ + + + + + + About Us - BakeGenius.ai + + + + + + + +
+
๐Ÿง
+
๐Ÿฐ
+
๐Ÿฅง
+
๐Ÿช
+
๐Ÿฅ„
+
โš–๏ธ
+ + +
+
+ + + + + + + + +
+

About BakeGenius.ai

+

Revolutionizing baking with AI-powered precision

+
+ + +
+ +
+
+ ๐Ÿง +

What is BakeGenius.ai?

+
+
+

BakeGenius.ai is an AI-powered baking assistant that transforms vague recipe instructions like "1 cup of flour" into precise gram-based conversions. Whether you're a home baker discovering the joy of perfect cookies or a professional pastry chef crafting delicate macarons, BakeGenius helps you achieve consistent, restaurant-quality results every single time.

+
+

Our advanced artificial intelligence understands the nuances of baking ingredients, recognizing that "1 cup of sifted flour" weighs differently than "1 cup of packed flour." By combining cutting-edge natural language processing with real-world ingredient databases, we've created the most accurate baking conversion tool available today.

+
+
+ + +
+
๐Ÿ‘ฉโ€๐Ÿ’ป
+

Supriya Pandey

+

AI Engineer & Passionate Baker

+
+

Hi there! I'm Supriya, and I created BakeGenius.ai from my own frustration with inconsistent baking results. As someone passionate about both artificial intelligence and the art of baking, I realized that the precision we demand in machine learning should also exist in our kitchens.

+
+

After countless failed attempts at scaling my grandmother's cookie recipe and watching friends struggle with international recipes, I decided to combine my expertise in AI and web development to solve this problem once and for all. BakeGenius.ai represents the intersection of cutting-edge technology and timeless baking traditions.

+
+

When I'm not coding or training AI models, you'll find me in my kitchen testing new recipes and perfecting the algorithms that power BakeGenius. My mission is to make professional-quality baking accessible to everyone, one gram at a time.

+
+
+ +
+
+ ๐Ÿ‘ฉโ€๐Ÿ’ป + Our Contributors +
+ +
+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/about_REMOTE_1224.html b/BakeGenuis-AI/html/about_REMOTE_1224.html new file mode 100644 index 00000000..3da77235 --- /dev/null +++ b/BakeGenuis-AI/html/about_REMOTE_1224.html @@ -0,0 +1,210 @@ + + + + + + About Us - BakeGenius.ai + + + + + + +
+
๐Ÿง
+
๐Ÿฐ
+
๐Ÿฅง
+
๐Ÿช
+
๐Ÿฅ„
+
โš–๏ธ
+ + +
+
+ + + + + + + + +
+

About BakeGenius.ai

+

Revolutionizing baking with AI-powered precision

+
+ + +
+ +
+
+ ๐Ÿง +

What is BakeGenius.ai?

+
+
+

BakeGenius.ai is an AI-powered baking assistant that transforms vague recipe instructions like "1 cup of flour" into precise gram-based conversions. Whether you're a home baker discovering the joy of perfect cookies or a professional pastry chef crafting delicate macarons, BakeGenius helps you achieve consistent, restaurant-quality results every single time.

+
+

Our advanced artificial intelligence understands the nuances of baking ingredients, recognizing that "1 cup of sifted flour" weighs differently than "1 cup of packed flour." By combining cutting-edge natural language processing with real-world ingredient databases, we've created the most accurate baking conversion tool available today.

+
+
+ + +
+
+ ๐ŸŽฏ +

What Problem Does It Solve?

+
+
+

Baking is a science, but traditional recipes treat it like guesswork. Here are the critical problems we solve:

+
    +
  • Recipes use non-standard, volume-based units that vary wildly between regions and measuring tools
  • +
  • "1 cup" means different weights for different people, leading to failed batches and wasted ingredients
  • +
  • Inconsistent baking results, especially in sensitive recipes like soufflรฉs, macarons, and artisan breads
  • +
  • Professional bakers can't scale home recipes reliably without precise measurements
  • +
  • International recipe sharing is nearly impossible due to measurement system differences
  • +
+
+

BakeGenius uses AI and real-world density data to eliminate these problems forever. No more failed batches, no more guesswork โ€“ just perfect, consistent baking results every time.

+
+
+ + +
+
+ ๐Ÿ› ๏ธ +

How Does It Work?

+
+
+

Our sophisticated AI system combines multiple technologies to deliver unparalleled accuracy:

+ +
+
+
1
+
Natural Language Processing
+
Our Gemini AI analyzes your recipe text, understanding context, ingredient types, and measurement nuances like "heaped," "packed," or "sifted."
+
+ +
+
2
+
Ingredient Normalization
+
The system identifies and standardizes ingredients, converting "AP flour" to "All-purpose flour" and understanding regional variations and brand differences.
+
+ +
+
3
+
Precise Conversion
+
Using our comprehensive density database, we convert measurements to grams with scientific precision, accounting for ingredient preparation methods.
+
+ +
+
4
+
Smart Customization
+
Our platform learns your preferences, remembers brand-specific adjustments, and allows fine-tuning for your specific baking style and ingredients.
+
+
+ +

The result? Professional-grade precision that transforms your baking from hit-or-miss to consistently perfect. Whether you're scaling a recipe for 2 people or 200, BakeGenius ensures every batch turns out exactly as intended.

+
+
+ + +
+
๐Ÿ‘ฉโ€๐Ÿ’ป
+

Supriya Pandey

+

AI Engineer & Passionate Baker

+
+

Hi there! I'm Supriya, and I created BakeGenius.ai from my own frustration with inconsistent baking results. As someone passionate about both artificial intelligence and the art of baking, I realized that the precision we demand in machine learning should also exist in our kitchens.

+
+

After countless failed attempts at scaling my grandmother's cookie recipe and watching friends struggle with international recipes, I decided to combine my expertise in AI and web development to solve this problem once and for all. BakeGenius.ai represents the intersection of cutting-edge technology and timeless baking traditions.

+
+

When I'm not coding or training AI models, you'll find me in my kitchen testing new recipes and perfecting the algorithms that power BakeGenius. My mission is to make professional-quality baking accessible to everyone, one gram at a time.

+
+
+ +
+
+ + +
+ + +
+ + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/convert.html b/BakeGenuis-AI/html/convert.html new file mode 100644 index 00000000..a9019fc5 --- /dev/null +++ b/BakeGenuis-AI/html/convert.html @@ -0,0 +1,210 @@ + + + + + + Convert Recipe - BakeGenius.ai + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ + +
+ +
+ + +
+ + + (Press Ctrl + Enter) +
+ + +
+
+

๐ŸŽฏ Conversion Results

+
+ + +
+
+ + + + + + + + + + + + + +
IngredientOriginalGramsNotes
+
+
+
+ + + + + + + +
+
+

โš ๏ธ Ambiguous Measurement

+

+ +
+ + +
+ + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/customize.html b/BakeGenuis-AI/html/customize.html new file mode 100644 index 00000000..7bc73e51 --- /dev/null +++ b/BakeGenuis-AI/html/customize.html @@ -0,0 +1,190 @@ + + + + + + Customize - BakeGenius.ai + + + + + + + + + + + + + + +
+
๐Ÿง
+
๐Ÿฐ
+
๐Ÿฅง
+
๐Ÿช
+
+ + + + + + + + + + +
+ + + +
+

๐Ÿท๏ธ Choose Your Preferred Brand

+
+
Standard/Generic
+
King Arthur Flour
+
Bob's Red Mill
+
Gold Medal
+
+
+ + +
+ +
+ +
+

โš–๏ธ Ingredient Density Editor

+
+ + + +
+
    +
    + + +
    + โœจ Settings saved successfully! Your customizations will be applied to future conversions. +
    + + +
    + + + +
    +
    + + +
    + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/feedback.html b/BakeGenuis-AI/html/feedback.html new file mode 100644 index 00000000..6ff39896 --- /dev/null +++ b/BakeGenuis-AI/html/feedback.html @@ -0,0 +1,243 @@ + + + + + + + Feedback - BakeGenius.ai + + + + + + + + + + + +
    + +
    +
    ๐Ÿง
    +
    ๐Ÿฐ
    +
    ๐Ÿฅง
    +
    ๐Ÿช
    +
    ๐Ÿฅ„
    +
    โš–๏ธ
    + + +
    +
    + + + + + + + + +
    +

    ๐Ÿ’ฌ Share Your Feedback

    +

    Help us make BakeGenius.ai even better with your valuable insights

    +
    + + +
    + +
    +
    + ๐Ÿ“ +

    Tell Us What You Think

    +
    +
    + +
    +
    + + +
    +
    + +

    Thank You!

    +

    Your feedback has been submitted successfully. We appreciate your input!

    + +
    +
    + + + +
    +
    + +
    + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/login.html b/BakeGenuis-AI/html/login.html new file mode 100644 index 00000000..914b464e --- /dev/null +++ b/BakeGenuis-AI/html/login.html @@ -0,0 +1,204 @@ + + + + + + Login - BakeGenius.ai + + + + + + + + + + + + + + + + + + + + +
    +
    ๐Ÿง
    +
    ๐Ÿฐ
    +
    ๐Ÿฅง
    +
    ๐Ÿช
    +
    + + + + + +
    +
    +
    +

    ๐Ÿ” Welcome Back!

    +

    Sign in to continue your baking journey

    +
    + +
    + +
    + + +
    + + +
    + +
    + + +
    +
    + + +
    + + + + + +
    or continue with
    + + + +
    + + +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/recipe_hub.html b/BakeGenuis-AI/html/recipe_hub.html new file mode 100644 index 00000000..694caa20 --- /dev/null +++ b/BakeGenuis-AI/html/recipe_hub.html @@ -0,0 +1,312 @@ + + + + + + Recipe Sharing Hub - BakeGenius.ai + + + + + + + + + + +
    + +
    ๐Ÿฐ
    +
    ๐Ÿฅง
    +
    ๐Ÿช
    +
    ๐Ÿฅ„
    + + + +
    +
    + + + + + + + +
    + +
    +

    ๐ŸŒŸ Recipe Sharing Hub

    +

    Discover, share, and save amazing recipes from our community of baking enthusiasts

    +
    + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + + + + + + +
    +
    +
    +

    ๐Ÿฝ๏ธ Community Recipes

    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    + + + + + + +
    + + +
    + + + + +
    +

    Hereโ€™s a random tip!

    + +
    + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/scale.html b/BakeGenuis-AI/html/scale.html new file mode 100644 index 00000000..529222fc --- /dev/null +++ b/BakeGenuis-AI/html/scale.html @@ -0,0 +1,221 @@ + + + + + + Scale Recipes - BakeGenius.ai + + + + + + + + + + +
    +
    ๐Ÿง
    +
    ๐Ÿฐ
    +
    ๐Ÿฅง
    +
    ๐Ÿช
    +
    + + + + + + + + +
    + +
    +

    ๐Ÿ“ Scale Your Recipes

    +

    Perfect portions for any crowd - from intimate dinners to grand celebrations!

    +
    + + +
    + +
    +

    ๐ŸŽฏ Recipe Scaling

    + +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    + +
    + Keep Original Units + + Convert to Grams +
    + +
    + + +
    +
    + + +
    +

    ๐Ÿ“Š Scaled Results

    + +
    +
    +

    Scaling your recipe with AI magic... ๐Ÿช„

    +
    + +
    +
    + + + + + + + + + + +
    IngredientOriginalScaled
    + +
    +

    ๐Ÿ”ฎ Smart Baking Tips

    +
    +
    +
    +
    +
    +
    + + +
    + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/html/signup.html b/BakeGenuis-AI/html/signup.html new file mode 100644 index 00000000..c8e2d25f --- /dev/null +++ b/BakeGenuis-AI/html/signup.html @@ -0,0 +1,246 @@ + + + + + + Sign Up - BakeGenius.ai + + + + + + + + + + + + + +
    +
    ๐Ÿง
    +
    ๐Ÿฐ
    +
    ๐Ÿฅง
    +
    ๐Ÿช
    +
    + + + + + +
    +
    +
    +

    ๐ŸŽ‚ Join BakeGenius!

    +

    Create your account and start baking with precision

    +
    + +
    +
    + + +
    + +
    + + +
    + +
    + +
    + + +
    +
    +
    + +
    + +
    + + +
    +
    + +
    + + +
    + + +
    or continue with
    + + + + + + + + + + Google Login Example + + + + + +
    +
    + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/index.html b/BakeGenuis-AI/index.html new file mode 100644 index 00000000..80ed44fe --- /dev/null +++ b/BakeGenuis-AI/index.html @@ -0,0 +1,236 @@ + + + + + + BakeGenius.ai - AI-Powered Baking Conversions + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    ๐Ÿง
    +
    ๐Ÿ’
    +
    +
    + +
    +
    +

    Welcome to BakeGenius.ai

    +

    + From spoon to scale โ€” get exact gram conversions with AI magic โœจ
    + Transform vague recipe measurements into precise, consistent results every time! +

    + Start Converting Now ๐Ÿš€ +
    + + +
    +
    + +

    AI-Powered Precision

    +

    Advanced AI converts "cups" and "spoons" into exact gram measurements.

    +
    +
    + +

    Smart Recipe Scaling

    +

    Effortlessly scale recipes up or down while keeping ratios perfect.

    +
    +
    + +

    Custom Preferences

    +

    Personalize conversions for consistent results every time.

    +
    +
    +
    + + +
    + + +
    + + + + + + +
    +
    โœ”๏ธ
    +
    Subscribed successfully!
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BakeGenuis-AI/js/about.js b/BakeGenuis-AI/js/about.js new file mode 100644 index 00000000..f3695a7b --- /dev/null +++ b/BakeGenuis-AI/js/about.js @@ -0,0 +1,239 @@ +// DOM Content Loaded Event +document.addEventListener('DOMContentLoaded', function() { + + // Generate Sparkles + function createSparkles() { + const sparklesContainer = document.getElementById('sparkles'); + const sparkleCount = 20; + + for (let i = 0; i < sparkleCount; i++) { + const sparkle = document.createElement('div'); + sparkle.className = 'sparkle'; + sparkle.style.left = Math.random() * 100 + '%'; + sparkle.style.top = Math.random() * 100 + '%'; + sparkle.style.animationDelay = Math.random() * 3 + 's'; + sparkle.style.animationDuration = (Math.random() * 2 + 2) + 's'; + sparklesContainer.appendChild(sparkle); + } + } + + // Scroll Animation Observer + function initScrollAnimations() { + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('animated'); + } + }); + }, observerOptions); + + // Observe all elements with animate-on-scroll class + document.querySelectorAll('.animate-on-scroll').forEach(el => { + observer.observe(el); + }); + } + + // Smooth Scrolling for Navigation Links + function initSmoothScrolling() { + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + const target = document.querySelector(this.getAttribute('href')); + if (target) { + target.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + } + }); + }); + } + + // Mobile Menu Toggle (if needed for responsive design) + function initMobileMenu() { + const navLinks = document.querySelector('.nav-links'); + const burger = document.querySelector('.burger-menu'); + + if (burger) { + burger.addEventListener('click', () => { + navLinks.classList.toggle('nav-active'); + burger.classList.toggle('toggle'); + }); + } + } + + // Add parallax effect to floating elements + function initParallaxEffect() { + window.addEventListener('scroll', () => { + const scrolled = window.pageYOffset; + const parallaxElements = document.querySelectorAll('.floating-element'); + + parallaxElements.forEach((element, index) => { + const speed = 0.5 + (index * 0.1); + const yPos = -(scrolled * speed); + element.style.transform = `translateY(${yPos}px)`; + }); + }); + } + + // Add hover effects for cards + function initCardEffects() { + const cards = document.querySelectorAll('.section-card, .step-card'); + + cards.forEach(card => { + card.addEventListener('mouseenter', function() { + this.style.transform = 'translateY(-10px) scale(1.02)'; + }); + + card.addEventListener('mouseleave', function() { + this.style.transform = 'translateY(0) scale(1)'; + }); + }); + } + + // Add typing effect to hero title + function initTypingEffect() { + const heroTitle = document.querySelector('.hero-title'); + if (heroTitle) { + const text = heroTitle.textContent; + heroTitle.textContent = ''; + // heroTitle.style.borderRight = '2px solid'; + + let i = 0; + const typeWriter = () => { + if (i < text.length) { + heroTitle.textContent += text.charAt(i); + i++; + setTimeout(typeWriter, 100); + } + }; + + setTimeout(typeWriter, 500); + } + } + + // Add random floating animation to problem items + function initProblemItemAnimations() { + const problemItems = document.querySelectorAll('.problem-item'); + + problemItems.forEach((item, index) => { + item.style.animationDelay = (index * 0.2) + 's'; + + item.addEventListener('mouseenter', function() { + this.style.animation = 'none'; + this.style.transform = 'translateX(15px) scale(1.02)'; + }); + + item.addEventListener('mouseleave', function() { + this.style.transform = 'translateX(0) scale(1)'; + }); + }); + } + + // Add interactive step card animations + function initStepCardAnimations() { + const stepCards = document.querySelectorAll('.step-card'); + + stepCards.forEach((card, index) => { + card.addEventListener('mouseenter', function() { + // Add a subtle rotation based on card position + const rotation = (index % 2 === 0) ? 'rotate(2deg)' : 'rotate(-2deg)'; + this.style.transform = `translateY(-10px) scale(1.05) ${rotation}`; + }); + + card.addEventListener('mouseleave', function() { + this.style.transform = 'translateY(0) scale(1) rotate(0deg)'; + }); + }); + } + + // Add floating animation to creator avatar + function initCreatorAvatarEffect() { + const avatar = document.querySelector('.creator-avatar'); + if (avatar) { + let isHovered = false; + + avatar.addEventListener('mouseenter', function() { + isHovered = true; + this.style.animation = 'none'; + this.style.transform = 'translateY(-20px) scale(1.1) rotate(10deg)'; + }); + + avatar.addEventListener('mouseleave', function() { + isHovered = false; + this.style.animation = 'avatarFloat 3s ease-in-out infinite'; + this.style.transform = 'translateY(0) scale(1) rotate(0deg)'; + }); + } + } + + // Add loading animation + function initLoadingAnimation() { + document.body.style.opacity = '0'; + document.body.style.transition = 'opacity 0.5s ease-in-out'; + + window.addEventListener('load', () => { + document.body.style.opacity = '1'; + }); + } + + // Add scroll progress indicator + + const owner = "supriya46788"; + const repo = "BakeGenuis-AI"; + const contributorsContainer = document.getElementById("contributors-container"); + + async function loadContributors() { + const contributorsContainer = document.getElementById("contributors-container"); + contributorsContainer.innerHTML = "Loading contributors..."; + + try { + const res = await fetch(`https://api.github.com/repos/supriya46788/BakeGenuis-AI/contributors`); + const contributors = await res.json(); + + if (!Array.isArray(contributors)) { + contributorsContainer.innerHTML = "

    โš  Unable to load contributors.

    "; + return; + } + + contributorsContainer.innerHTML = ""; // Clear loading + + contributors.forEach(contributor => { + const card = document.createElement("div"); + card.classList.add("contributor-card"); + card.innerHTML = ` + ${contributor.login} + ${contributor.login} + `; + contributorsContainer.appendChild(card); + }); + + } catch (error) { + // Handle contributor loading error gracefully + contributorsContainer.innerHTML = "

    โš  Unable to load contributors at this time.

    "; + } +} + +loadContributors(); + // Initialize all functions + createSparkles(); + initScrollAnimations(); + initSmoothScrolling(); + initMobileMenu(); + initParallaxEffect(); + initCardEffects(); + initTypingEffect(); + initProblemItemAnimations(); + initStepCardAnimations(); + initCreatorAvatarEffect(); + initLoadingAnimation(); + // initScrollProgress(); + // Add some extra sparkle regeneration + setInterval(createSparkles, 10000); +}); + \ No newline at end of file diff --git a/BakeGenuis-AI/js/auth.js b/BakeGenuis-AI/js/auth.js new file mode 100644 index 00000000..2efcf5b5 --- /dev/null +++ b/BakeGenuis-AI/js/auth.js @@ -0,0 +1,763 @@ +// Authentication System for BakeGenius AI +class AuthSystem { + constructor() { + this.users = this.loadUsers(); + this.currentUser = this.getCurrentUser(); + } + + // Load users from localStorage + loadUsers() { + const users = localStorage.getItem('bakegenius_users'); + return users ? JSON.parse(users) : []; + } + + // Save users to localStorage + saveUsers() { + localStorage.setItem('bakegenius_users', JSON.stringify(this.users)); + } + + // Get current logged-in user + getCurrentUser() { + const user = localStorage.getItem('bakegenius_current_user'); + return user ? JSON.parse(user) : null; + } + + // Set current user + setCurrentUser(user) { + localStorage.setItem('bakegenius_current_user', JSON.stringify(user)); + this.currentUser = user; + } + + // Clear current user (logout) + clearCurrentUser() { + localStorage.removeItem('bakegenius_current_user'); + this.currentUser = null; + } + + // Check if email already exists + emailExists(email) { + return this.users.some( + (user) => user.email.toLowerCase() === email.toLowerCase().trim() + ); + } + + // Register new user + signup(name, email, password) { + if (this.emailExists(email)) { + toastManager.error('An account with this email already exists', 'Signup Error'); + // throw new Error('An account with this email already exists'); + return; + } + + const newUser = { + id: Date.now().toString(), + name: name.trim(), + email: email.toLowerCase().trim(), + password: password, // NOTE: For production, hash the password + createdAt: new Date().toISOString(), + }; + + this.users.push(newUser); + this.saveUsers(); + + // Auto-login after signup + this.setCurrentUser({ + id: newUser.id, + name: newUser.name, + email: newUser.email, + }); + + return true; + } + + // Login user + login(email, password) { + const user = this.users.find( + (u) => + u.email.toLowerCase() === email.toLowerCase().trim() && + u.password === password + ); + if (!user) { + toastManager.error('Invalid email or password', 'Login Error'); + // throw new Error('Invalid email or password'); + return; + } + this.setCurrentUser({ + id: user.id, + name: user.name, + email: user.email, + }); + return true; + } + + // Logout user + logout() { + this.clearCurrentUser(); + } + + // Check if user is logged in + isLoggedIn() { + return this.currentUser !== null; + } +} + +// Global auth instance +const auth = new AuthSystem(); + +/* ---------- Toast System ---------- */ +class ToastManager { + constructor() { + this.container = this.createContainer(); + this.toasts = []; + } + + createContainer() { + let container = document.querySelector('.toast-container'); + if (!container) { + container = document.createElement('div'); + container.className = 'toast-container'; + document.body.appendChild(container); + } + return container; + } + + show(message, type = 'info', title = '', duration = 5000) { + const toast = this.createToast(message, type, title); + this.container.appendChild(toast); + this.toasts.push(toast); + + // Trigger animation + setTimeout(() => toast.classList.add('show'), 100); + + // Auto remove + const removeTimer = setTimeout(() => { + this.remove(toast); + }, duration); + + // Store timer reference for manual removal + toast._removeTimer = removeTimer; + + // Limit number of toasts + if (this.toasts.length > 5) { + this.remove(this.toasts[0]); + } + + return toast; + } + + createToast(message, type, title) { + const toast = document.createElement('div'); + toast.className = `toast ${type}`; + + const icons = { + success: '๐ŸŽ‰', + error: 'โŒ', + warning: 'โš ๏ธ', + info: 'โ„น๏ธ' + }; + + const toastTitle = title || { + success: 'Success!', + error: 'Error!', + warning: 'Warning!', + info: 'Info' + }[type]; + + toast.innerHTML = ` +
    ${icons[type] || icons.info}
    +
    +
    ${toastTitle}
    +
    ${message}
    +
    + +
    + `; + + return toast; + } + + remove(toast) { + if (!toast || !toast.parentElement) return; + + // Clear timer if exists + if (toast._removeTimer) { + clearTimeout(toast._removeTimer); + } + + toast.classList.remove('show'); + + setTimeout(() => { + if (toast.parentElement) { + toast.parentElement.removeChild(toast); + } + this.toasts = this.toasts.filter(t => t !== toast); + }, 400); + } + + success(message, title = 'Success!', duration = 5000) { + return this.show(message, 'success', title, duration); + } + + error(message, title = 'Error!', duration = 6000) { + return this.show(message, 'error', title, duration); + } + + warning(message, title = 'Warning!', duration = 5000) { + return this.show(message, 'warning', title, duration); + } + + info(message, title = 'Info', duration = 4000) { + return this.show(message, 'info', title, duration); + } +} + +// Global toast manager instance +const toastManager = new ToastManager(); + +/* ---------- UI Helpers ---------- */ +function getErrorEl() { + return document.getElementById('errorMessage'); +} +function getSuccessEl() { + return document.getElementById('successMessage'); +} + +function showError(message) { + // Show toast for critical errors + const criticalErrors = [ + 'An account with this email already exists', + 'Invalid email or password', + 'Network error - please check your connection', + 'Passwords do not match', + 'Please enter a valid email address' + ]; + + if (criticalErrors.some(error => message.includes(error))) { + toastManager.error(message, 'Authentication Error'); + } + + // Keep inline messages for all errors + const el = getErrorEl(); + if (!el) return; + el.textContent = message; + el.classList.add('show'); + + // Hide success if visible + const success = getSuccessEl(); + if (success) success.classList.remove('show'); + + clearTimeout(el._hideTimer); + el._hideTimer = setTimeout(() => { + el.classList.remove('show'); + }, 5000); +} + +function hideError() { + const el = getErrorEl(); + if (el) el.classList.remove('show'); +} + +function showSuccess(message) { + // Don't show success toasts here - only in specific success handlers + const el = getSuccessEl(); + if (!el) return; + el.textContent = message; + el.classList.add('show'); + + hideError(); + + clearTimeout(el._hideTimer); + el._hideTimer = setTimeout(() => { + el.classList.remove('show'); + }, 3000); + + el.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); +} + +function setLoading(isLoading, buttonId = 'loginButton') { + const button = document.getElementById(buttonId); + if (!button) return; + const spinner = button.querySelector('.loading-spinner'); + const buttonText = button.querySelector('.button-text'); + + if (isLoading) { + button.disabled = true; + if (spinner) spinner.style.display = 'inline-block'; + if (buttonText) buttonText.style.opacity = '0.7'; + } else { + button.disabled = false; + if (spinner) spinner.style.display = 'none'; + if (buttonText) buttonText.style.opacity = '1'; + } +} + +function togglePassword(inputId) { + const input = document.getElementById(inputId); + if (!input) return; + const icon = input.parentElement.querySelector('.password-toggle i'); + if (input.type === 'password') { + input.type = 'text'; + if (icon) { + icon.classList.remove('fa-eye'); + icon.classList.add('fa-eye-slash'); + } + } else { + input.type = 'password'; + if (icon) { + icon.classList.remove('fa-eye-slash'); + icon.classList.add('fa-eye'); + } + } +} + +function checkPasswordStrength(password) { + const strengthElement = document.getElementById('passwordStrength'); + if (!strengthElement) return; + + let strength = 0; + let message = ''; + + if (password.length >= 6) strength++; + if (/[a-z]/.test(password)) strength++; + if (/[A-Z]/.test(password)) strength++; + if (/[0-9]/.test(password)) strength++; + if (/[^a-zA-Z0-9]/.test(password)) strength++; + + switch (strength) { + case 0: + case 1: + message = 'โš ๏ธ Weak password'; + strengthElement.className = 'password-strength weak'; + break; + case 2: + case 3: + message = 'โšก Medium strength'; + strengthElement.className = 'password-strength medium'; + break; + case 4: + case 5: + message = 'โœ… Strong password'; + strengthElement.className = 'password-strength strong'; + break; + } + + strengthElement.textContent = message; +} + +// Use the more permissive email validation (keep your version) +function validateEmail(email) { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailRegex.test(email); +} + +/* ---------- Page Init ---------- */ +function initLoginPage() { + if (auth.isLoggedIn()) { + window.location.href = '../index.html'; + return; + } + + const loginForm = document.getElementById('loginForm'); + if (loginForm) { + loginForm.addEventListener('submit', handleLogin); + } + + hideError(); + + // Initialize Google Sign-In button if available + initGoogleSignIn('login'); +} + +function initSignupPage() { + if (auth.isLoggedIn()) { + window.location.href = '../index.html'; + return; + } + + const signupForm = document.getElementById('signupForm'); + if (signupForm) { + signupForm.addEventListener('submit', handleSignup); + } + + const passwordInput = document.getElementById('password'); + if (passwordInput) { + passwordInput.addEventListener('input', (e) => + checkPasswordStrength(e.target.value) + ); + } + + hideError(); + + // Initialize Google Sign-In button if available + initGoogleSignIn('signup'); +} + +/* ---------- Submit Handlers ---------- */ +async function handleLogin(event) { + event.preventDefault(); + hideError(); + setLoading(true, 'loginButton'); + + const formData = new FormData(event.target); + const email = formData.get('email'); + const password = formData.get('password'); + + try { + if (!email || !password) { + toastManager.error('Please fill in all fields', 'Login Error'); + // throw new Error('Please fill in all fields'); + return; + } + if (!validateEmail(email)) { + toastManager.error('Enter a valid email address', 'Login Error'); + // throw new Error('Please enter a valid email address'); + return; + } + if (password.length < 6) { + toastManager.error('Password must be at least 6 characters long', 'Login Error'); + // throw new Error('Password must be at least 6 characters long'); + return; + } + + await new Promise((r) => setTimeout(r, 800)); + + if(auth.login(email, password)){ + // Success toast ONLY for successful login + toastManager.success(`Welcome back, ${auth.currentUser.name.split(' ')[0]}! ๐ŸŽ‰`, 'Login Successful!'); + setTimeout(() => { + window.location.href = '../index.html'; + }, 1200); + } + + + } catch (err) { + toastManager.error(err.message || 'Something went wrong. Please try again.', 'Login Error'); + // showError(err.message || 'Something went wrong. Please try again.'); + } finally { + setLoading(false, 'loginButton'); + } +} + +async function handleSignup(event) { + event.preventDefault(); + hideError(); + setLoading(true, 'signupButton'); + + const formData = new FormData(event.target); + const name = formData.get('name'); + const email = formData.get('email'); + const password = formData.get('password'); + const confirmPassword = formData.get('confirmPassword'); + + try { + if (!name || !email || !password || !confirmPassword) { + toastManager.error('Please fill in all fields', 'Signup Error'); + // throw new Error('Please fill in all fields'); + return; + } + if (name.trim().length < 2) { + toastManager.error('Name must be at least 2 characters long', 'Signup Error'); + // throw new Error('Name must be at least 2 characters long'); + return; + } + if (!validateEmail(email)) { + toastManager.error('Please enter a valid email address', 'Signup Error'); + // throw new Error('Please enter a valid email address'); + return; + } + if (password.length < 6) { + toastManager.error('Password must be at least 6 characters long', 'Signup Error'); + // throw new Error('Password must be at least 6 characters long'); + return; + } + if (password !== confirmPassword) { + toastManager.error('Passwords do not match', 'Signup Error'); + // throw new Error('Passwords do not match'); + return; + } + + await new Promise((r) => setTimeout(r, 1000)); + + if(auth.signup(name, email, password)){ + // Success toast ONLY for successful signup + toastManager.success(`Welcome to BakeGenius, ${name.split(' ')[0]}! ๐ŸŽ‚`, 'Account Created!'); + + setTimeout(() => { + window.location.href = '../index.html'; + }, 1400); + } + } catch (err) { + // showError(err.message || 'Something went wrong. Please try again.'); + toastManager.error(err.message || 'Something went wrong. Please try again.', 'Signup Error'); + } finally { + setLoading(false, 'signupButton'); + } +} + +/* ---------- Navigation & Auth ---------- */ +function updateNavigation() { + if (!auth.isLoggedIn()) return; + + const navbarContainer = document.querySelector('.navbar-container'); + if (!navbarContainer) return; + + // Hide login/signup buttons + const loginBtn = document.querySelector('.login-btn'); + const signupBtn = document.querySelector('.signup-btn'); + if (loginBtn) loginBtn.style.display = 'none'; + if (signupBtn) signupBtn.style.display = 'none'; + + // Remove existing user-info if present + const existingUserInfo = navbarContainer.querySelector('.user-info'); + if (existingUserInfo) existingUserInfo.remove(); + + // Build user info div + const userInfo = document.createElement('div'); + userInfo.className = 'user-info'; + const hasAvatar = auth.currentUser && auth.currentUser.avatarUrl; + const avatarHtml = hasAvatar + ? `avatar` + : `
    ${auth.currentUser.name.charAt(0).toUpperCase()}
    `; + + userInfo.innerHTML = ` + ${avatarHtml} + Hi, ${auth.currentUser.name.split(' ')[0]}! + + `; + + // Insert user info in place of CTA button or at the end + const ctaBtn = navbarContainer.querySelector('.cta-btn'); + const authButtons = navbarContainer.querySelector('.auth-buttons'); + if (authButtons) { + authButtons.parentNode.replaceChild(userInfo, authButtons); + } else { + navbarContainer.appendChild(userInfo); + } +} + +function handleLogout() { + if (typeof Swal !== 'undefined') { + Swal.fire({ + title: 'Are you sure you want to log out?', + icon: 'question', + showCancelButton: true, + confirmButtonColor: '#FF4757', + cancelButtonColor: '#70A1FF', + confirmButtonText: 'Yes, log out', + cancelButtonText: 'Cancel', + customClass: { + popup: 'swal-popup', + title: 'swal-title', + confirmButton: 'swal-confirm-btn', + cancelButton: 'swal-cancel-btn' + } + }).then((result) => { + if (result.isConfirmed) { + performLogout(); + } + }); + } else { + if (confirm('Are you sure you want to logout?')) { + performLogout(); + } + } +} + +function performLogout() { + auth.logout(); + + // Disable Google auto-select so the next visit doesn't auto sign-in + if (window.google && google.accounts && google.accounts.id) { + try { google.accounts.id.disableAutoSelect(); } catch (e) {} + } + + // Success toast ONLY for successful logout + toastManager.success('You have been logged out successfully', 'Goodbye!', 2000); + + const currentPath = window.location.pathname; + setTimeout(() => { + if (currentPath.includes('/html/')) { + window.location.href = 'login.html'; + } else { + window.location.href = 'html/login.html'; + } + }, 1800); +} + +// Enhanced checkAuth function to handle more scenarios +function checkAuth() { + const protectedPages = ['convert.html', 'customize.html', 'scale.html', 'recipe_hub.html']; + const currentPage = window.location.pathname.split('/').pop(); + + // Redirect to login if trying to access protected page without authentication + if (protectedPages.includes(currentPage) && !auth.isLoggedIn()) { + window.location.href = 'login.html'; + return false; + } + + // Redirect away from login/signup pages if already authenticated + const authPages = ['login.html', 'signup.html']; + if (authPages.includes(currentPage) && auth.isLoggedIn()) { + window.location.href = '../index.html'; + return false; + } + + // Update navigation based on auth status + if (auth.isLoggedIn()) { + updateNavigation(); + } else { + // Ensure auth elements are visible when logged out + const authElements = document.querySelectorAll('a[href*="login.html"], a[href*="signup.html"], .login-btn, .signup-btn'); + authElements.forEach(element => { + element.style.display = ''; + }); + + // Ensure Scale Now button is always visible + const scaleButtons = document.querySelectorAll('.cta-btn, .scale-nav-btn, a[href*="scale.html"]'); + scaleButtons.forEach(button => { + button.style.display = ''; + }); + + const userInfo = document.querySelector('.user-info'); + if (userInfo) { + userInfo.remove(); + } + } + + return true; +} + +document.addEventListener('DOMContentLoaded', function() { + checkAuth(); + window.addEventListener('storage', function(e) { + if (e.key === 'bakegenius_current_user') { + checkAuth(); + } + }); +}); + +if (typeof module !== 'undefined' && module.exports) { + module.exports = { auth, checkAuth, updateNavigation, handleLogout }; +} + +// -------------------- +// Google Sign-In Setup +// -------------------- + +function base64UrlDecode(input) { + const base64 = input.replace(/-/g, '+').replace(/_/g, '/'); + const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '='); + try { + return decodeURIComponent(atob(padded).split('').map(function(c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + } catch (e) { + return atob(padded); + } +} + +function parseJwt(idToken) { + try { + const payload = idToken.split('.')[1]; + const json = base64UrlDecode(payload); + return JSON.parse(json); + } catch (e) { + return null; + } +} + +function handleGoogleCredentialResponse(response) { + const credential = response && response.credential; + if (!credential) { + toastManager.error('Google sign-in failed. Please try again.', 'Google Sign-In Error'); + return; + } + const payload = parseJwt(credential); + if (!payload || !payload.email) { + toastManager.error('Unable to parse Google user.', 'Google Sign-In Error'); + return; + } + + const googleUser = { + id: 'google:' + (payload.sub || payload.email), + name: payload.name || payload.given_name || payload.email.split('@')[0], + email: (payload.email || '').toLowerCase(), + avatarUrl: payload.picture || '', + provider: 'google', + createdAt: new Date().toISOString() + }; + + const existingLocal = auth.users.find(u => u.email.toLowerCase() === googleUser.email); + if (!existingLocal) { + auth.users.push(googleUser); + auth.saveUsers(); + } else { + // Merge avatar and provider info for existing user + existingLocal.provider = existingLocal.provider || 'local'; + if (googleUser.avatarUrl && !existingLocal.avatarUrl) { + existingLocal.avatarUrl = googleUser.avatarUrl; + auth.saveUsers(); + } + } + + auth.setCurrentUser({ + id: googleUser.id, + name: googleUser.name, + email: googleUser.email, + avatarUrl: googleUser.avatarUrl + }); + + // Success toast for Google Sign-In + toastManager.success(`Welcome, ${googleUser.name.split(' ')[0]}! ๐ŸŽ‰`, 'Google Sign-In Successful!'); + + // Redirect to home + setTimeout(() => { + window.location.href = '../index.html'; + }, 1200); +} + +function initGoogleSignIn(page) { + const target = document.getElementById('google-login-btn'); + if (!target) return; + + const clientId = (window.GOOGLE_CLIENT_ID || '').trim(); + if (!clientId) { + // Show guidance if client id is not configured + target.style.display = 'block'; + target.innerHTML = '
    Set GOOGLE_CLIENT_ID in js/google_config.js to enable Google Sign-In.
    '; + console.warn('Google Sign-In: Missing window.GOOGLE_CLIENT_ID. Set it in js/google_config.js'); + return; + } + + let attempts = 0; + const maxAttempts = 40; // ~4s + const timer = setInterval(function() { + attempts++; + if (window.google && google.accounts && google.accounts.id) { + clearInterval(timer); + try { + google.accounts.id.initialize({ + client_id: clientId, + callback: handleGoogleCredentialResponse, + auto_select: false, + cancel_on_tap_outside: true, + use_fedcm_for_prompt: true + }); + + // Add click handler to existing button + target.addEventListener('click', function() { + google.accounts.id.prompt(); + }); + + } catch (e) { + console.error('Failed to initialize Google Sign-In', e); + target.style.display = 'block'; + target.innerHTML = '
    Failed to initialize Google Sign-In. Check console.
    '; + } + } else if (attempts >= maxAttempts) { + clearInterval(timer); + target.style.display = 'block'; + target.innerHTML = '
    Could not load Google script. Check network/ad-blockers.
    '; + } + }, 100); +} \ No newline at end of file diff --git a/BakeGenuis-AI/js/carousel_autoscroll.js b/BakeGenuis-AI/js/carousel_autoscroll.js new file mode 100644 index 00000000..7b43c048 --- /dev/null +++ b/BakeGenuis-AI/js/carousel_autoscroll.js @@ -0,0 +1,37 @@ +// Auto-scroll for recipe carousels +// This script scrolls the trending and featured carousels automatically and loops them. + +function autoScrollCarousel(carouselId, speed = 1) { + const carousel = document.getElementById(carouselId); + if (!carousel) return; + let scrollAmount = 0; + let direction = 1; + let isHovered = false; + + // Pause on hover + carousel.addEventListener('mouseenter', () => { isHovered = true; }); + carousel.addEventListener('mouseleave', () => { isHovered = false; }); + + function scrollStep() { + if (!isHovered) { + carousel.scrollLeft += speed * direction; + scrollAmount += speed * direction; + // If reached end, loop back + if (carousel.scrollLeft + carousel.clientWidth >= carousel.scrollWidth - 1) { + carousel.scrollLeft = 0; + scrollAmount = 0; + } + // If at start, go forward + if (carousel.scrollLeft <= 0) { + direction = 1; + } + } + requestAnimationFrame(scrollStep); + } + requestAnimationFrame(scrollStep); +} + +document.addEventListener('DOMContentLoaded', function() { + autoScrollCarousel('trendingRecipes', 1); + autoScrollCarousel('featuredRecipes', 1); +}); diff --git a/BakeGenuis-AI/js/config.js b/BakeGenuis-AI/js/config.js new file mode 100644 index 00000000..d00ba253 --- /dev/null +++ b/BakeGenuis-AI/js/config.js @@ -0,0 +1,59 @@ +/** + * BakeGenius.AI Configuration + * Production-ready configuration file + */ + +const CONFIG = { + // Development settings + development: { + enableLogging: false, + enableDebug: false, + apiTimeout: 10000 + }, + + // Production settings + production: { + enableLogging: false, + enableDebug: false, + apiTimeout: 5000 + }, + + // Feature flags + features: { + floatingEmojis: true, + smoothScrolling: true, + darkMode: true, + analytics: false + }, + + // API configuration (move sensitive data to server-side) + api: { + // Note: In production, API calls should be made through your backend + // Never expose API keys in client-side code + baseUrl: null, + timeout: 5000 + }, + + // UI configuration + ui: { + animationDuration: 300, + scrollOffset: 50, + mobileBreakpoint: 768 + }, + + // Performance settings + performance: { + lazyLoadImages: true, + preloadCriticalResources: true, + enableServiceWorker: false + } +}; + +// Environment detection +const isProduction = window.location.hostname !== 'localhost' && + window.location.hostname !== '127.0.0.1'; + +// Export current environment config +window.BAKEGENIUS_CONFIG = isProduction ? CONFIG.production : CONFIG.development; +window.BAKEGENIUS_FEATURES = CONFIG.features; +window.BAKEGENIUS_UI = CONFIG.ui; diff --git a/BakeGenuis-AI/js/convert.js b/BakeGenuis-AI/js/convert.js new file mode 100644 index 00000000..4d6584e9 --- /dev/null +++ b/BakeGenuis-AI/js/convert.js @@ -0,0 +1,271 @@ + // Note: API keys removed for security - implement server-side API calls in production + const GEMINI_API_KEY = null; + const GEMINI_API_URL = null; + + let currentUnit = 'metric'; + let convertedData = []; + + // Ingredient to emoji mapping + const ingredientEmojis = { + 'flour': '๐ŸŒพ', + 'sugar': '๐Ÿฏ', + 'butter': '๐Ÿงˆ', + 'egg': '๐Ÿฅš', + 'milk': '๐Ÿฅ›', + 'vanilla': '๐ŸŒฟ', + 'baking powder': 'โšก', + 'salt': '๐Ÿง‚', + 'chocolate': '๐Ÿซ', + 'cocoa': '๐Ÿซ', + 'oil': '๐Ÿซ’', + 'honey': '๐Ÿฏ', + 'cream': '๐Ÿฅ›', + 'cheese': '๐Ÿง€', + 'nuts': '๐Ÿฅœ', + 'fruit': '๐Ÿ“', + 'lemon': '๐Ÿ‹', + 'orange': '๐ŸŠ', + 'cinnamon': '๐ŸŒฟ', + 'default': '๐Ÿฅ„' + }; + + function toggleMobileMenu() { + const navLinks = document.getElementById('navLinks'); + navLinks.classList.toggle('active'); + } + + function handleFileUpload(event) { + const file = event.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = function(e) { + document.getElementById('recipeInput').value = e.target.result; + }; + reader.readAsText(file); + } + } + + function getIngredientEmoji(ingredient) { + const lower = ingredient.toLowerCase(); + for (const [key, emoji] of Object.entries(ingredientEmojis)) { + if (lower.includes(key)) { + return emoji; + } + } + return ingredientEmojis.default; + } + + async function convertRecipe() { + const recipeText = document.getElementById('recipeInput').value.trim(); + + if (!recipeText) { + showWarning('Please enter a recipe to convert!'); + return; + } + + setLoading(true); + + try { + const response = await fetch(`${GEMINI_API_URL}?key=${GEMINI_API_KEY}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + contents: [{ + parts: [{ + text: `Convert this recipe to precise gram measurements. For each ingredient, provide: +1. Normalized ingredient name +2. Original measurement +3. Gram equivalent +4. Any relevant notes about the conversion + +Please format the response as JSON with this structure: +{ + "ingredients": [ + { + "ingredient": "All-purpose flour", + "original": "2 cups", + "grams": 240, + "notes": "Sifted measurement" + } + ], + "warnings": ["Any ambiguous measurements that need clarification"] +} + +Recipe to convert: +${recipeText}` + }] + }] + }) + }); + + if (!response.ok) { + throw new Error('API request failed'); + } + + const data = await response.json(); + const aiResponse = data.candidates[0].content.parts[0].text; + + // Parse the AI response + try { + const jsonMatch = aiResponse.match(/\{[\s\S]*\}/); + if (jsonMatch) { + const parsedData = JSON.parse(jsonMatch[0]); + convertedData = parsedData.ingredients || []; + displayResults(convertedData); + + // Show warnings if any + if (parsedData.warnings && parsedData.warnings.length > 0) { + showWarning(parsedData.warnings.join('\n')); + } + } else { + throw new Error('Could not parse AI response'); + } + } catch (parseError) { + console.error('Parse error:', parseError); + // Fallback: create results from plain text + convertedData = parseTextResponse(aiResponse); + displayResults(convertedData); + } + + } catch (error) { + console.error('Conversion error:', error); + showWarning('Sorry, there was an error converting your recipe. Please try again.'); + } finally { + setLoading(false); + } + } + + function parseTextResponse(text) { + // Simple fallback parser for plain text responses + const lines = text.split('\n').filter(line => line.trim()); + const ingredients = []; + + lines.forEach(line => { + if (line.includes('cup') || line.includes('tbsp') || line.includes('tsp') || line.includes('pound') || line.includes('oz')) { + const parts = line.split(/[:;-]/); + if (parts.length >= 2) { + ingredients.push({ + ingredient: parts[0].trim(), + original: parts[1].trim(), + grams: Math.round(Math.random() * 200 + 50), // Placeholder + notes: 'Estimated conversion' + }); + } + } + }); + + return ingredients; + } + + function displayResults(ingredients) { + const resultsSection = document.getElementById('resultsSection'); + const resultsBody = document.getElementById('resultsBody'); + + resultsBody.innerHTML = ''; + + ingredients.forEach(item => { + const row = document.createElement('tr'); + row.className = 'ingredient-row'; + + const emoji = getIngredientEmoji(item.ingredient); + + row.innerHTML = ` + + ${emoji} + ${item.ingredient} + + ${item.original} + + ${item.grams}g + + ${item.notes || 'Standard'} + `; + + resultsBody.appendChild(row); + }); + + resultsSection.style.display = 'block'; + resultsSection.scrollIntoView({ behavior: 'smooth' }); + } + + function toggleUnits(unit) { + currentUnit = unit; + + // Update active button + document.querySelectorAll('.unit-toggle button').forEach(btn => { + btn.classList.remove('active'); + }); + event.target.classList.add('active'); + + // Update display (for now, just refresh the current data) + if (convertedData.length > 0) { + displayResults(convertedData); + } + } + + function setLoading(isLoading) { + const button = document.querySelector('.convert-button'); + const spinner = document.getElementById('loadingSpinner'); + const buttonText = document.getElementById('buttonText'); + + if (isLoading) { + button.disabled = true; + spinner.style.display = 'inline-block'; + buttonText.textContent = 'Converting...'; + } else { + button.disabled = false; + spinner.style.display = 'none'; + buttonText.textContent = 'Magically Convert โœจ'; + } + } + + function showWarning(message) { + const overlay = document.getElementById('overlay'); + const popup = document.getElementById('warningPopup'); + const messageEl = document.getElementById('warningMessage'); + + messageEl.textContent = message; + overlay.style.display = 'block'; + popup.style.display = 'block'; + } + + function closeWarning() { + const overlay = document.getElementById('overlay'); + const popup = document.getElementById('warningPopup'); + + overlay.style.display = 'none'; + popup.style.display = 'none'; + } + + // Add some sample data for demo purposes + document.addEventListener('DOMContentLoaded', function() { + const textarea = document.getElementById('recipeInput'); + + // Add floating animation to page elements + const animateElements = document.querySelectorAll('.input-section, .results-section'); + animateElements.forEach((el, index) => { + el.style.animation = `fadeInUp 0.6s ease forwards ${index * 0.2}s`; + el.style.opacity = '0'; + el.style.transform = 'translateY(30px)'; + }); + }); + + // Add fadeInUp animation + const style = document.createElement('style'); + style.textContent = ` + @keyframes fadeInUp { + to { + opacity: 1; + transform: translateY(0); + } + } + `; + document.head.appendChild(style); + document.addEventListener('keydown', function (event) { + if (event.ctrlKey && event.key === 'Enter') { + event.preventDefault(); // avoid accidental new line in textarea + convertRecipe(); + } +}); \ No newline at end of file diff --git a/BakeGenuis-AI/js/customize.js b/BakeGenuis-AI/js/customize.js new file mode 100644 index 00000000..25051398 --- /dev/null +++ b/BakeGenuis-AI/js/customize.js @@ -0,0 +1,232 @@ +// Sample ingredients data (in real app, this would come from previous conversion) + const defaultIngredients = [ + { name: 'All-Purpose Flour', icon: '๐ŸŒพ', currentGrams: 120, measurementType: 'sifted', originalAmount: '1 cup', density: 0.593 }, + { name: 'Brown Sugar', icon: '๐Ÿฏ', currentGrams: 200, measurementType: 'packed', originalAmount: '1 cup', density: 0.721 }, + { name: 'Butter', icon: '๐Ÿงˆ', currentGrams: 226, measurementType: 'softened', originalAmount: '1 cup', density: 0.911 }, + { name: 'Vanilla Extract', icon: '๐ŸŒŸ', currentGrams: 4, measurementType: 'liquid', originalAmount: '1 tsp', density: 1.0 }, + { name: 'Baking Powder', icon: 'โšก', currentGrams: 4, measurementType: 'leveled', originalAmount: '1 tsp', density: 0.9 } + ]; + + // Load ingredients + function loadIngredients() { + const savedIngredients = localStorage.getItem('bakegenius_ingredients'); + return savedIngredients ? JSON.parse(savedIngredients) : JSON.parse(JSON.stringify(defaultIngredients)); + } + + // Utility to get density safely (check user-updated density first, else fallback to default) + function getDensity(ingredient) { + if (ingredient.density && !isNaN(ingredient.density)) { + return ingredient.density; // user override + } + const defaultMatch = defaultIngredients.find(d => d.name === ingredient.name); + return defaultMatch ? defaultMatch.density : 1.0; // fallback + } + + // Render ingredient cards + function renderIngredients() { + const ingredients = loadIngredients(); + const container = document.getElementById('ingredientsContainer'); + + container.innerHTML = ingredients.map((ingredient, index) => ` +
    +
    + ${ingredient.icon} + ${ingredient.name} + โ„น๏ธ +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + `).join(''); + + // Add event listeners + addEventListeners(); + } + + // Add event listeners to all controls + function addEventListeners() { + const selects = document.querySelectorAll('.custom-select'); + const inputs = document.querySelectorAll('.custom-input'); + + [...selects, ...inputs].forEach(element => { + element.addEventListener('change', updateIngredient); + }); + + // Brand selector listeners + document.querySelectorAll('.brand-option').forEach(option => { + option.addEventListener('click', selectBrand); + }); + } + + // Update ingredient data when controls change + function updateIngredient(event) { + const ingredientIndex = parseInt(event.target.dataset.ingredient); + const field = event.target.dataset.field; + const value = event.target.type === 'number' ? parseFloat(event.target.value) : event.target.value; + + const ingredients = loadIngredients(); + ingredients[ingredientIndex][field] = value; + + // Recalculate grams if density was updated + if (field === 'density') { + const newDensity = getDensity(ingredients[ingredientIndex]); + ingredients[ingredientIndex].currentGrams = +(ingredients[ingredientIndex].currentGrams * (newDensity / defaultIngredients[ingredientIndex].density)).toFixed(2); + } + + // Auto-save changes + localStorage.setItem('bakegenius_ingredients', JSON.stringify(ingredients)); + } + + // Brand selection + function selectBrand(event) { + document.querySelectorAll('.brand-option').forEach(option => { + option.classList.remove('selected'); + }); + event.target.classList.add('selected'); + + const selectedBrand = event.target.dataset.brand; + localStorage.setItem('bakegenius_brand', selectedBrand); + + // Adjust gram values based on brand (simulation) + adjustForBrand(selectedBrand); + } + + // Adjust ingredient weights based on selected brand + function adjustForBrand(brand) { + const ingredients = loadIngredients(); + const adjustments = { + 'king-arthur': { 'All-Purpose Flour': 125 }, + 'bob-red-mill': { 'All-Purpose Flour': 118 }, + 'gold-medal': { 'All-Purpose Flour': 120 }, + 'standard': { 'All-Purpose Flour': 120 } + }; + + if (adjustments[brand]) { + ingredients.forEach(ingredient => { + if (adjustments[brand][ingredient.name]) { + ingredient.currentGrams = adjustments[brand][ingredient.name]; + } + }); + + localStorage.setItem('bakegenius_ingredients', JSON.stringify(ingredients)); + renderIngredients(); + } + } + + // Apply changes function + function applyChanges(event) { + const button = event.target; + button.style.transform = 'scale(0.95)'; + button.innerHTML = 'โณ Applying...'; + + setTimeout(() => { + button.style.transform = ''; + button.innerHTML = 'โœจ Apply Changes'; + showSuccessMessage('Changes applied successfully!', 'apply'); + }, 1000); + } + + // Reset to defaults + function resetToDefaults() { + if (confirm('Are you sure you want to reset all customizations to default values?')) { + localStorage.removeItem('bakegenius_ingredients'); + localStorage.removeItem('bakegenius_brand'); + + // Reset brand selection + document.querySelectorAll('.brand-option').forEach(option => { + option.classList.remove('selected'); + }); + document.querySelector('[data-brand="standard"]').classList.add('selected'); + + renderIngredients(); + showSuccessMessage('Reset to defaults successfully!'); + } + } + + // Save settings + function saveSettings(event) { + const button = event.target; + button.style.transform = 'scale(0.95)'; + button.innerHTML = '๐Ÿ’พ Saving...'; + + setTimeout(() => { + button.style.transform = ''; + button.innerHTML = '๐Ÿ’พ Save Settings'; + showSuccessMessage('Settings saved to your browser!'); + }, 800); + } + +// Show success message +function showSuccessMessage(message, type = "default") { + const successDiv = document.getElementById('successMessage'); + successDiv.textContent = `โœจ ${message}`; + successDiv.style.display = 'block'; + + // Different colors based on type + if (type === "apply") { + successDiv.style.borderColor = "var(--candy-red)"; + successDiv.style.color = "var(--candy-red)"; + successDiv.style.background = "rgba(255, 71, 87, 0.1)"; + } else { + successDiv.style.borderColor = "#2ED573"; + successDiv.style.color = "#2ED573"; + successDiv.style.background = "rgba(46, 213, 115, 0.1)"; + } + + setTimeout(() => { + successDiv.style.display = 'none'; + }, 3000); +} + + // Load saved brand preference + function loadBrandPreference() { + const savedBrand = localStorage.getItem('bakegenius_brand') || 'standard'; + document.querySelectorAll('.brand-option').forEach(option => { + option.classList.remove('selected'); + }); + document.querySelector(`[data-brand="${savedBrand}"]`)?.classList.add('selected'); + } + + // Initialize page + document.addEventListener('DOMContentLoaded', () => { + renderIngredients(); + loadBrandPreference(); + }); + + // Add some fun interactions + document.addEventListener('click', (e) => { + if (e.target.classList.contains('ingredient-icon')) { + e.target.style.animation = 'none'; + setTimeout(() => { + e.target.style.animation = 'bounce 0.5s ease'; + }, 10); + } + }); \ No newline at end of file diff --git a/BakeGenuis-AI/js/feature.js b/BakeGenuis-AI/js/feature.js new file mode 100644 index 00000000..d54de216 --- /dev/null +++ b/BakeGenuis-AI/js/feature.js @@ -0,0 +1,60 @@ +// Smooth scrolling with Lenis +function smoothScrolling() { + // Check if Lenis is available + if (typeof Lenis === 'undefined') { + // Lenis library not available - use default scrolling + return; + } + + try { + // Initialize Lenis with smooth scrolling settings + const lenis = new Lenis({ + duration: 1.9, + smooth: true, + smoothTouch: false, // Disable smooth scrolling on touch devices for better performance + touchMultiplier: 2, + }); + + // Create animation loop + function raf(time) { + lenis.raf(time); + requestAnimationFrame(raf); + } + + // Start the animation loop + requestAnimationFrame(raf); + + // Smooth scrolling initialized successfully + } catch (error) { + // Fallback to default scrolling behavior + } +} + +// Wait for DOM to be fully loaded before initializing +window.addEventListener('DOMContentLoaded', function() { + setTimeout(smoothScrolling, 100); // Small delay to ensure everything is properly loaded +}); + + +//globle scrolling progression bar across all pages +function initScrollProgress() { + const progressBar = document.createElement('div'); + progressBar.style.cssText = ` + position: fixed; + top: 0; + left: 0; + width: 0%; + height: 4px; + background: linear-gradient(90deg, var(--candy-red), var(--sky-blue), var(--sunny-yellow)); + z-index: 9999; + transition: width 0.3s ease; + `; + document.body.appendChild(progressBar); + + window.addEventListener('scroll', () => { + const scrollPercent = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100; + progressBar.style.width = scrollPercent + '%'; + }); + } + + initScrollProgress(); \ No newline at end of file diff --git a/BakeGenuis-AI/js/feedback.js b/BakeGenuis-AI/js/feedback.js new file mode 100644 index 00000000..51a3f2f8 --- /dev/null +++ b/BakeGenuis-AI/js/feedback.js @@ -0,0 +1,264 @@ +// Feedback System for BakeGenius AI +class FeedbackSystem { + constructor() { + this.feedbacks = this.loadFeedbacks(); + this.initializeEventListeners(); + this.initializeAnimations(); + } + + // Load feedbacks from localStorage + loadFeedbacks() { + const feedbacks = localStorage.getItem('bakegenius_feedbacks'); + return feedbacks ? JSON.parse(feedbacks) : []; + } + + // Save feedbacks to localStorage + saveFeedbacks() { + localStorage.setItem('bakegenius_feedbacks', JSON.stringify(this.feedbacks)); + } + + // Initialize event listeners + initializeEventListeners() { + const feedbackForm = document.getElementById('feedbackForm'); + if (feedbackForm) { + feedbackForm.addEventListener('submit', this.handleSubmit.bind(this)); + + // ๐Ÿ”ฅ Keyboard shortcuts for quick submit + window.addEventListener('keydown', (e) => { + if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { + e.preventDefault(); + feedbackForm.requestSubmit(); + } + }); + } +} + + // Handle form submission + async handleSubmit(event) { + event.preventDefault(); + + const formData = new FormData(event.target); + const feedback = { + id: Date.now().toString(), + name: formData.get('name').trim(), + email: formData.get('email').trim(), + message: formData.get('message').trim(), + rating: formData.get('rating'), + sentiment: this.detectSentiment(formData.get('message')), + timestamp: new Date().toISOString(), + date: new Date().toLocaleDateString('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric' + }) + }; + + // Validate form data + if (!feedback.name || !feedback.email || !feedback.message) { + this.showError('Please fill in all fields'); + return; + } + + if (!this.validateEmail(feedback.email)) { + this.showError('Please enter a valid email address'); + return; + } + + // Show loading state + this.setLoading(true); + + try { + // Simulate API delay + await new Promise(resolve => setTimeout(resolve, 1500)); + + // Add feedback to storage + this.feedbacks.unshift(feedback); + this.saveFeedbacks(); + + // Show success and feedback list + this.showSuccess(); + this.displayFeedbackList(); + + } catch (error) { + // Handle feedback submission error gracefully + this.showError('Something went wrong. Please try again.'); + } finally { + this.setLoading(false); + } + } + + // Validate email format + validateEmail(email) { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailRegex.test(email); + } + + // Set loading state + setLoading(isLoading) { + const submitBtn = document.getElementById('submitBtn'); + const spinner = document.getElementById('loadingSpinner'); + const buttonText = submitBtn.querySelector('.button-text'); + + if (isLoading) { + submitBtn.disabled = true; + spinner.style.display = 'inline-block'; + buttonText.textContent = 'โณ Submitting...'; + } else { + submitBtn.disabled = false; + spinner.style.display = 'none'; + buttonText.textContent = '๐Ÿš€ Submit Feedback'; + } + } + + // Show success message + showSuccess() { + const formSection = document.getElementById('feedbackFormSection'); + const successMessage = document.getElementById('successMessage'); + + formSection.style.display = 'none'; + successMessage.classList.add('show'); + + // Scroll to success message + successMessage.scrollIntoView({ behavior: 'smooth' }); + } + + // Show error message + showError(message) { + // Create or update error message + let errorDiv = document.getElementById('errorMessage'); + if (!errorDiv) { + errorDiv = document.createElement('div'); + errorDiv.id = 'errorMessage'; + errorDiv.className = 'error-message'; + + const form = document.getElementById('feedbackForm'); + form.insertBefore(errorDiv, form.querySelector('.form-actions')); + } + + errorDiv.textContent = message; + errorDiv.style.display = 'block'; + errorDiv.style.background = 'rgba(255, 71, 87, 0.1)'; + errorDiv.style.border = '2px solid #FF4757'; + errorDiv.style.borderRadius = '15px'; + errorDiv.style.padding = '1rem'; + errorDiv.style.marginBottom = '1rem'; + errorDiv.style.color = '#FF4757'; + errorDiv.style.fontWeight = '600'; + errorDiv.style.textAlign = 'center'; + + // Auto-hide after 5 seconds + setTimeout(() => { + errorDiv.style.display = 'none'; + }, 5000); + } + + // Detect sentiment (simple keyword-based for demo purposes) + detectSentiment(message) { + const positiveWords = ['good', 'great', 'amazing', 'love', 'excellent','nice']; + const negativeWords = ['bad', 'poor', 'terrible', 'hate', 'awful']; + + let score = 0; + const lowerMsg = message.toLowerCase(); + + positiveWords.forEach(word => { if (lowerMsg.includes(word)) score++; }); + negativeWords.forEach(word => { if (lowerMsg.includes(word)) score--; }); + + if (score > 0) return 'Positive'; + if (score < 0) return 'Negative'; + return 'Neutral'; + } + // Display feedback list + displayFeedbackList() { + const listSection = document.getElementById('feedbackListSection'); + const feedbackList = document.getElementById('feedbackList'); + + if (this.feedbacks.length === 0) { + feedbackList.innerHTML = '

    No feedback submitted yet.

    '; + } else { + feedbackList.innerHTML = this.feedbacks.map(feedback => ` + + `).join(''); + } + + listSection.style.display = 'block'; + listSection.scrollIntoView({ behavior: 'smooth' }); + } + + // Escape HTML to prevent XSS + escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } + + // Initialize animations + initializeAnimations() { + this.createSparkles(); + this.initScrollAnimations(); + + // Regenerate sparkles periodically + setInterval(() => this.createSparkles(), 10000); + } + + // Generate sparkles + createSparkles() { + const sparklesContainer = document.getElementById('sparkles'); + if (!sparklesContainer) return; + + // Clear existing sparkles + sparklesContainer.innerHTML = ''; + + const sparkleCount = 20; + + for (let i = 0; i < sparkleCount; i++) { + const sparkle = document.createElement('div'); + sparkle.className = 'sparkle'; + sparkle.style.left = Math.random() * 100 + '%'; + sparkle.style.top = Math.random() * 100 + '%'; + sparkle.style.animationDelay = Math.random() * 3 + 's'; + sparkle.style.animationDuration = (Math.random() * 2 + 2) + 's'; + sparklesContainer.appendChild(sparkle); + } + } + + // Initialize scroll animations + initScrollAnimations() { + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('animated'); + } + }); + }, observerOptions); + + document.querySelectorAll('.animate-on-scroll').forEach(el => { + observer.observe(el); + }); + } +} + +// Global functions +function goToHome() { + window.location.href = '../index.html'; +} + +// Initialize feedback system when DOM is loaded +document.addEventListener('DOMContentLoaded', function() { + new FeedbackSystem(); + + // Feedback page initialization complete +}); \ No newline at end of file diff --git a/BakeGenuis-AI/js/floating_emoji_footer_fix.js b/BakeGenuis-AI/js/floating_emoji_footer_fix.js new file mode 100644 index 00000000..87f48e08 --- /dev/null +++ b/BakeGenuis-AI/js/floating_emoji_footer_fix.js @@ -0,0 +1,153 @@ +/** + * Floating Emoji Footer Fix + * Prevents floating emoji decorations from overlapping footer content + * by detecting when footer enters viewport and hiding/repositioning emojis + */ + +(function() { + 'use strict'; + + // Configuration + const CONFIG = { + footerSelector: '.footer, footer', + floatingElementsSelectors: [ + '.floating-elements', + '.floating-element', + '.floating-cupcake', + '.animated-bg .floating-element' + ], + observerOptions: { + threshold: 0.1, + rootMargin: '50px 0px 0px 0px' // Start hiding slightly before footer comes into view + } + }; + + let footerObserver; + let isFooterVisible = false; + + /** + * Initialize the footer observer when DOM is ready + */ + function init() { + // Wait for DOM to be fully loaded + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initFooterObserver); + } else { + initFooterObserver(); + } + } + + /** + * Set up Intersection Observer to watch for footer visibility + */ + function initFooterObserver() { + const footer = document.querySelector(CONFIG.footerSelector); + + if (!footer) { + // Footer not found - emoji fix not needed + return; + } + + // Create intersection observer + footerObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + hideFloatingEmojis(); + isFooterVisible = true; + } else { + showFloatingEmojis(); + isFooterVisible = false; + } + }); + }, CONFIG.observerOptions); + + // Start observing the footer + footerObserver.observe(footer); + } + + /** + * Hide all floating emoji elements + */ + function hideFloatingEmojis() { + const elements = getAllFloatingElements(); + elements.forEach(element => { + element.style.opacity = '0'; + element.style.pointerEvents = 'none'; + element.style.transition = 'opacity 0.3s ease-out'; + }); + } + + /** + * Show all floating emoji elements + */ + function showFloatingEmojis() { + const elements = getAllFloatingElements(); + elements.forEach(element => { + element.style.opacity = ''; + element.style.pointerEvents = ''; + element.style.transition = 'opacity 0.3s ease-in'; + }); + } + + /** + * Get all floating emoji elements from the page + */ + function getAllFloatingElements() { + const elements = []; + + CONFIG.floatingElementsSelectors.forEach(selector => { + const found = document.querySelectorAll(selector); + elements.push(...found); + }); + + return elements; + } + + /** + * Alternative approach: Lower z-index instead of hiding + * This keeps emojis visible but puts them behind footer + */ + function lowerEmojiZIndex() { + const elements = getAllFloatingElements(); + elements.forEach(element => { + element.style.zIndex = '-1'; + element.style.transition = 'opacity 0.3s ease-out'; + }); + } + + /** + * Restore original z-index + */ + function restoreEmojiZIndex() { + const elements = getAllFloatingElements(); + elements.forEach(element => { + element.style.zIndex = ''; + element.style.transition = 'opacity 0.3s ease-in'; + }); + } + + /** + * Cleanup function + */ + function cleanup() { + if (footerObserver) { + footerObserver.disconnect(); + } + showFloatingEmojis(); + } + + // Initialize when script loads + init(); + + // Cleanup on page unload + window.addEventListener('beforeunload', cleanup); + + // Expose functions for manual control if needed + window.FloatingEmojiFooterFix = { + hide: hideFloatingEmojis, + show: showFloatingEmojis, + isFooterVisible: () => isFooterVisible, + cleanup: cleanup + }; + +})(); diff --git a/BakeGenuis-AI/js/google_config.example.js b/BakeGenuis-AI/js/google_config.example.js new file mode 100644 index 00000000..2a368d00 --- /dev/null +++ b/BakeGenuis-AI/js/google_config.example.js @@ -0,0 +1,11 @@ +// Google OAuth Configuration Template +// +// 1. Copy this file to google_config.js +// 2. Get your Google OAuth client ID from Google Cloud Console: +// https://console.cloud.google.com/apis/credentials +// 3. Replace the empty string below with your client ID +// 4. Add js/google_config.js to .gitignore to keep your client ID private + +window.GOOGLE_CLIENT_ID = ""; // e.g., "1234567890-abc123def456.apps.googleusercontent.com" + +// Note: Never commit your actual client ID to version control! diff --git a/BakeGenuis-AI/js/index.js b/BakeGenuis-AI/js/index.js new file mode 100644 index 00000000..c028b8fe --- /dev/null +++ b/BakeGenuis-AI/js/index.js @@ -0,0 +1,129 @@ +// ================= Mobile Navigation Toggle ================= +const hamburger = document.getElementById('hamburger'); +const navLinks = document.getElementById('navLinks'); +const navRight = document.querySelector('.nav-right'); + +if (hamburger && navLinks) { + hamburger.addEventListener('click', () => { + navLinks.classList.toggle('active'); + if (navRight) { + navRight.classList.toggle('active'); + } + hamburger.classList.toggle('active'); + }); + + // Close mobile menu when clicking on a link + const navItems = document.querySelectorAll('.nav-links a, .nav-right a'); + navItems.forEach(item => { + item.addEventListener('click', () => { + navLinks.classList.remove('active'); + if (navRight) { + navRight.classList.remove('active'); + } + hamburger.classList.remove('active'); + }); + }); + + // Close menu when clicking outside + document.addEventListener('click', (e) => { + if (!hamburger.contains(e.target) && !navLinks.contains(e.target) && (!navRight || !navRight.contains(e.target))) { + navLinks.classList.remove('active'); + if (navRight) { + navRight.classList.remove('active'); + } + hamburger.classList.remove('active'); + } + }); +} + +// ================= Smooth scroll for CTA button ================= +const ctaButton = document.querySelector('.cta-button'); +if (ctaButton) { + ctaButton.addEventListener('click', (e) => { + e.preventDefault(); + // Add a fun animation on click + ctaButton.style.animation = 'bounce 0.5s ease-in-out'; + setTimeout(() => { + ctaButton.style.animation = 'pulse 2s ease-in-out infinite'; + // Navigate to convert page (in real app) + window.location.href = 'html/convert.html'; + }, 500); + }); +} + +// ================= Parallax effect for decorative icons ================= +window.addEventListener('scroll', () => { + const scrolled = window.pageYOffset; + const parallax = scrolled * 0.5; + + document.querySelectorAll('.baking-icon').forEach((icon, index) => { + icon.style.transform = `translateY(${parallax * (index + 1) * 0.1}px) rotate(${parallax * 0.05}deg)`; + }); +}); + +// ================= Add sparkle effect on hover for feature cards ================= +document.querySelectorAll('.feature-card').forEach(card => { + card.addEventListener('mouseenter', () => { + card.style.background = 'rgba(255, 255, 255, 0.95)'; + card.style.boxShadow = '0 20px 60px rgba(0, 0, 0, 0.15)'; + }); + + card.addEventListener('mouseleave', () => { + card.style.background = 'rgba(255, 255, 255, 0.8)'; + card.style.boxShadow = 'none'; + }); +}); + +// ================= Scroll-to-Top & Bottom Toggle ================= +const scrollToBottomBtn = document.getElementById("scrollToBottomBtn"); +const scrollToTopBtn = document.getElementById("scrollToTopBtn"); + +if (scrollToBottomBtn && scrollToTopBtn) { + const showThreshold = 300; // px from top + + function toggleScrollBtns() { + const scrollY = window.scrollY; + const documentHeight = Math.max( + document.body.scrollHeight, + document.body.offsetHeight, + document.documentElement.clientHeight, + document.documentElement.scrollHeight, + document.documentElement.offsetHeight + ); + const nearBottom = scrollY >= documentHeight - window.innerHeight - 200; + + if (scrollY <= showThreshold) { + // At top โ†’ show bottom button, hide top + scrollToBottomBtn.style.display = "block"; + scrollToTopBtn.style.display = "none"; + } else if (nearBottom) { + // At bottom โ†’ show top button only + scrollToBottomBtn.style.display = "none"; + scrollToTopBtn.style.display = "block"; + } else { + // In between โ†’ show top button + scrollToBottomBtn.style.display = "none"; + scrollToTopBtn.style.display = "block"; + } + } + + window.addEventListener("scroll", toggleScrollBtns, { passive: true }); + toggleScrollBtns(); + + // Scroll smoothly to bottom + scrollToBottomBtn.addEventListener("click", () => { + const documentHeight = Math.max( + document.body.scrollHeight, + document.body.offsetHeight, + document.documentElement.clientHeight, + document.documentElement.scrollHeight, + document.documentElement.offsetHeight + ); + window.scrollTo({ top: documentHeight, behavior: "smooth" }); + }); + + // Scroll smoothly to top + scrollToTopBtn.addEventListener("click", () => { + window.scrollTo({ top: 0, behavior: "smooth" }); + }); +} diff --git a/BakeGenuis-AI/js/mouse-trail.js b/BakeGenuis-AI/js/mouse-trail.js new file mode 100644 index 00000000..f787c42f --- /dev/null +++ b/BakeGenuis-AI/js/mouse-trail.js @@ -0,0 +1,47 @@ +/*console.log("Mouse trail script loaded โœ…"); + +const canvas = document.createElement("canvas"); +canvas.id = "trailCanvas"; +document.body.appendChild(canvas); + +const ctx = canvas.getContext("2d"); +let points = []; + +// Config +const color = "rgba(0, 150, 255, 0.6)"; +const trailLength = 15; +const maxRadius = 12; + +function resizeCanvas() { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; +} +resizeCanvas(); +window.addEventListener("resize", resizeCanvas); + +document.addEventListener("mousemove", (e) => { + points.push({ x: e.clientX, y: e.clientY }); + if (points.length > trailLength) { + points.shift(); + } +}); + +function animate() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + for (let i = 0; i < points.length; i++) { + const p = points[i]; + ctx.beginPath(); + ctx.arc(p.x, p.y, (i / trailLength) * maxRadius, 0, 2 * Math.PI); + ctx.fillStyle = color; + ctx.fill(); + } + requestAnimationFrame(animate); +} +animate(); + +// Style +canvas.style.position = "fixed"; +canvas.style.top = "0"; +canvas.style.left = "0"; +canvas.style.pointerEvents = "none"; +canvas.style.zIndex = "9999";*/ diff --git a/BakeGenuis-AI/js/recipe_hub.js b/BakeGenuis-AI/js/recipe_hub.js new file mode 100644 index 00000000..9924a652 --- /dev/null +++ b/BakeGenuis-AI/js/recipe_hub.js @@ -0,0 +1,650 @@ +// Recipe Hub JavaScript - BakeGenius.ai + +class RecipeHub { + constructor() { + this.recipes = []; + this.filteredRecipes = []; + this.currentPage = 1; + this.recipesPerPage = 12; + this.savedRecipes = JSON.parse(localStorage.getItem('savedRecipes') || '[]'); + this.followedCreators = JSON.parse(localStorage.getItem('followedCreators') || '[]'); + this.likedRecipes = JSON.parse(localStorage.getItem('likedRecipes') || '[]'); + this.recipeLikes = JSON.parse(localStorage.getItem('recipeLikes') || '{}'); + + this.init(); + } + + init() { + this.loadSampleRecipes(); + this.setupEventListeners(); + this.createSparkles(); + this.renderTrendingRecipes(); + this.renderFeaturedRecipes(); + this.renderRecipeGrid(); + } + + setupEventListeners() { + // Search functionality + const searchInput = document.getElementById('searchInput'); + const filterToggle = document.getElementById('filterToggle'); + const filtersPanel = document.getElementById('filtersPanel'); + const sortBy = document.getElementById('sortBy'); + const loadMoreBtn = document.getElementById('loadMoreBtn'); + + searchInput?.addEventListener('input', (e) => this.handleSearch(e.target.value)); + filterToggle?.addEventListener('click', () => this.toggleFilters()); + sortBy?.addEventListener('change', (e) => this.handleSort(e.target.value)); + loadMoreBtn?.addEventListener('click', () => this.loadMoreRecipes()); + + // Filter inputs + const filterInputs = ['difficultyFilter', 'timeFilter', 'dietaryFilter', 'ingredientFilter']; + filterInputs.forEach(filterId => { + const element = document.getElementById(filterId); + element?.addEventListener('change', () => this.applyFilters()); + }); + + // View All buttons for Trending and Featured (show in main grid) + const trendingViewAll = document.getElementById('viewAllTrending'); + const featuredViewAll = document.getElementById('viewAllFeatured'); + if (trendingViewAll) { + trendingViewAll.addEventListener('click', () => this.showAllTrendingInGrid()); + } + if (featuredViewAll) { + featuredViewAll.addEventListener('click', () => this.showAllFeaturedInGrid()); + } + } + + showAllTrendingInGrid() { + // Show all trending recipes in the main recipe grid + this.filteredRecipes = this.recipes.filter(recipe => recipe.trending); + this.currentPage = 1; + this.renderRecipeGrid(); + // Optionally scroll to the grid + const grid = document.getElementById('recipeGrid'); + if (grid) grid.scrollIntoView({ behavior: 'smooth' }); + } + + showAllFeaturedInGrid() { + // Show all featured recipes in the main recipe grid + this.filteredRecipes = this.recipes.filter(recipe => recipe.featured); + this.currentPage = 1; + this.renderRecipeGrid(); + // Optionally scroll to the grid + const grid = document.getElementById('recipeGrid'); + if (grid) grid.scrollIntoView({ behavior: 'smooth' }); + } + + createSparkles() { + const sparklesContainer = document.getElementById('sparkles'); + if (!sparklesContainer) return; + + // Clear existing sparkles + sparklesContainer.innerHTML = ''; + + // Create individual sparkle elements + for (let i = 0; i < 30; i++) { + const sparkle = document.createElement('div'); + sparkle.classList.add('sparkle'); + sparkle.style.left = Math.random() * 100 + '%'; + sparkle.style.top = Math.random() * 100 + '%'; + sparkle.style.animationDelay = Math.random() * 3 + 's'; + sparklesContainer.appendChild(sparkle); + } + } + + loadSampleRecipes() { + // Sample recipe data with reliable placeholder images + this.recipes = [ + { + id: 1, + title: "Classic Chocolate Chip Cookies", + description: "Soft, chewy, and packed with chocolate chips. The perfect comfort food that never goes out of style.", + image: "https://images.pexels.com/photos/890577/pexels-photo-890577.jpeg?auto=compress&cs=tinysrgb&w=400&h=300&dpr=1", + creator: { + name: "Sarah Baker", + avatar: "https://i.pravatar.cc/50?img=1" + }, + difficulty: "easy", + cookTime: 25, + rating: 4.8, + ratingCount: 324, + likes: 156, + comments: 23, + dietary: ["vegetarian"], + ingredients: ["flour", "chocolate chips", "butter", "sugar"], + tags: ["cookies", "chocolate", "dessert", "easy"], + trending: true, + featured: false + }, + { + id: 2, + title: "Artisan Sourdough Bread", + description: "Traditional sourdough with a perfect crust and tangy flavor. Made with wild yeast starter for authentic taste.", + image: "https://images.pexels.com/photos/209196/pexels-photo-209196.jpeg?auto=compress&cs=tinysrgb&w=400&h=300&dpr=1", + creator: { + name: "Mike Artisan", + avatar: "https://i.pravatar.cc/50?img=2" + }, + difficulty: "hard", + cookTime: 240, + rating: 4.9, + ratingCount: 189, + likes: 89, + comments: 45, + dietary: ["vegan"], + ingredients: ["flour", "water", "salt", "sourdough starter"], + tags: ["bread", "sourdough", "artisan", "vegan"], + trending: false, + featured: true + }, + { + id: 3, + title: "Rainbow Unicorn Cupcakes", + description: "Magical vanilla cupcakes with rainbow layers and sparkly buttercream frosting. Perfect for celebrations!", + image: "https://images.pexels.com/photos/1055272/pexels-photo-1055272.jpeg?auto=compress&cs=tinysrgb&w=400&h=300&dpr=1", + creator: { + name: "Emma Sweet", + avatar: "https://i.pravatar.cc/50?img=3" + }, + difficulty: "medium", + cookTime: 45, + rating: 4.7, + ratingCount: 267, + likes: 201, + comments: 34, + dietary: ["vegetarian"], + ingredients: ["flour", "sugar", "eggs", "food coloring", "buttercream"], + tags: ["cupcakes", "rainbow", "party", "colorful"], + trending: true, + featured: true + }, + { + id: 4, + title: "Vegan Chocolate Brownies", + description: "Rich, fudgy brownies that happen to be vegan. No one will believe they're dairy and egg-free!", + image: "https://images.pexels.com/photos/2373520/pexels-photo-2373520.jpeg?auto=compress&cs=tinysrgb&w=400&h=300&dpr=1", + creator: { + name: "Alex Green", + avatar: "https://i.pravatar.cc/50?img=4" + }, + difficulty: "easy", + cookTime: 35, + rating: 4.6, + ratingCount: 156, + likes: 78, + comments: 19, + dietary: ["vegan", "dairy-free"], + ingredients: ["cocoa powder", "flour", "coconut oil", "maple syrup"], + tags: ["brownies", "vegan", "chocolate", "healthy"], + trending: false, + featured: false + }, + { + id: 5, + title: "French Macarons Masterclass", + description: "Delicate French macarons with perfect feet and smooth tops. Multiple flavor variations included.", + image: "https://images.pexels.com/photos/230325/pexels-photo-230325.jpeg?auto=compress&cs=tinysrgb&w=400&h=300&dpr=1", + creator: { + name: "Chef Laurent", + avatar: "https://i.pravatar.cc/50?img=5" + }, + difficulty: "hard", + cookTime: 90, + rating: 4.9, + ratingCount: 145, + likes: 234, + comments: 67, + dietary: ["gluten-free", "vegetarian"], + ingredients: ["almond flour", "powdered sugar", "egg whites", "food coloring"], + tags: ["macarons", "french", "elegant", "gluten-free"], + trending: true, + featured: true + }, + { + id: 6, + title: "Quick Cinnamon Rolls", + description: "Soft, gooey cinnamon rolls ready in just 30 minutes. Perfect for weekend breakfast treats.", + image: "https://images.pexels.com/photos/1055270/pexels-photo-1055270.jpeg?auto=compress&cs=tinysrgb&w=400&h=300&dpr=1", + creator: { + name: "Jenny Morning", + avatar: "https://i.pravatar.cc/50?img=6" + }, + difficulty: "medium", + cookTime: 30, + rating: 4.5, + ratingCount: 298, + likes: 167, + comments: 41, + dietary: ["vegetarian"], + ingredients: ["flour", "cinnamon", "butter", "brown sugar", "yeast"], + tags: ["cinnamon rolls", "breakfast", "quick", "sweet"], + trending: false, + featured: false + } + ]; + + this.filteredRecipes = [...this.recipes]; + this.recipes.forEach(recipe => { + if (this.recipeLikes[recipe.id] !== undefined) { + recipe.likes = this.recipeLikes[recipe.id]; + } + }); + } + + toggleFilters() { + const filtersPanel = document.getElementById('filtersPanel'); + filtersPanel?.classList.toggle('active'); + } + + handleSearch(query) { + const searchTerm = query.toLowerCase().trim(); + + if (!searchTerm) { + this.filteredRecipes = [...this.recipes]; + } else { + this.filteredRecipes = this.recipes.filter(recipe => + recipe.title.toLowerCase().includes(searchTerm) || + recipe.description.toLowerCase().includes(searchTerm) || + recipe.creator.name.toLowerCase().includes(searchTerm) || + recipe.ingredients.some(ingredient => ingredient.toLowerCase().includes(searchTerm)) || + recipe.tags.some(tag => tag.toLowerCase().includes(searchTerm)) + ); + } + + this.applyFilters(); + } + + applyFilters() { + let filtered = [...this.filteredRecipes]; + + const difficulty = document.getElementById('difficultyFilter')?.value; + const time = document.getElementById('timeFilter')?.value; + const dietary = document.getElementById('dietaryFilter')?.value; + const ingredient = document.getElementById('ingredientFilter')?.value.toLowerCase().trim(); + + if (difficulty) { + filtered = filtered.filter(recipe => recipe.difficulty === difficulty); + } + + if (time) { + const maxTime = parseInt(time); + filtered = filtered.filter(recipe => recipe.cookTime <= maxTime); + } + + if (dietary) { + filtered = filtered.filter(recipe => recipe.dietary.includes(dietary)); + } + + if (ingredient) { + filtered = filtered.filter(recipe => + recipe.ingredients.some(ing => ing.toLowerCase().includes(ingredient)) + ); + } + + this.filteredRecipes = filtered; + this.currentPage = 1; + this.renderRecipeGrid(); + } + + handleSort(sortBy) { + switch (sortBy) { + case 'latest': + this.filteredRecipes.sort((a, b) => b.id - a.id); + break; + case 'popular': + this.filteredRecipes.sort((a, b) => b.likes - a.likes); + break; + case 'rated': + this.filteredRecipes.sort((a, b) => b.rating - a.rating); + break; + } + + this.renderRecipeGrid(); + } + + renderTrendingRecipes() { + const container = document.getElementById('trendingRecipes'); + if (!container) return; + + const trendingRecipes = this.recipes.filter(recipe => recipe.trending); + container.innerHTML = trendingRecipes.map(recipe => this.createRecipeCard(recipe, true)).join(''); + this.attachCardEventListeners(container); + } + + renderFeaturedRecipes() { + const container = document.getElementById('featuredRecipes'); + if (!container) return; + + const featuredRecipes = this.recipes.filter(recipe => recipe.featured); + container.innerHTML = featuredRecipes.map(recipe => this.createRecipeCard(recipe, true)).join(''); + this.attachCardEventListeners(container); + } + + renderRecipeGrid() { + const container = document.getElementById('recipeGrid'); + if (!container) return; + // Show all recipes (no pagination) + container.innerHTML = this.filteredRecipes.map(recipe => this.createRecipeCard(recipe)).join(''); + this.attachCardEventListeners(container); + // Hide load more button + const loadMoreBtn = document.getElementById('loadMoreBtn'); + if (loadMoreBtn) { + loadMoreBtn.style.display = 'none'; + } + } + + loadMoreRecipes() { + this.currentPage++; + this.renderRecipeGrid(); + } + + createRecipeCard(recipe, isCarousel = false) { + const isLiked = this.likedRecipes.includes(recipe.id); + const isSaved = this.savedRecipes.includes(recipe.id); + const isFollowing = this.followedCreators.includes(recipe.creator.name); + + const stars = this.createStarRating(recipe.rating); + const difficultyClass = recipe.difficulty; + const tags = recipe.tags.slice(0, 3).map(tag => `${tag}`).join(''); + + return ` +
    +
    + ${recipe.title} +
    +
    ${recipe.difficulty}
    +
    + + ${recipe.cookTime}m +
    +
    + +
    +
    +
    +

    ${recipe.title}

    +
    +
    ${stars}
    + (${recipe.ratingCount}) +
    +
    +

    ${recipe.description}

    +
    + ${recipe.creator.name} + ${recipe.creator.name} + +
    +
    + + + + +
    +
    ${tags}
    +
    +
    + `; + } + + createStarRating(rating) { + const fullStars = Math.floor(rating); + const hasHalfStar = rating % 1 !== 0; + let stars = ''; + + for (let i = 0; i < fullStars; i++) { + stars += ''; + } + + if (hasHalfStar) { + stars += ''; + } + + const emptyStars = 5 - fullStars - (hasHalfStar ? 1 : 0); + for (let i = 0; i < emptyStars; i++) { + stars += ''; + } + + return stars; + } + + attachCardEventListeners(container) { + // Save button functionality + container.querySelectorAll('.save-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const recipeId = parseInt(btn.closest('.recipe-card').dataset.recipeId); + this.toggleSaveRecipe(recipeId, btn); + }); + }); + + // Like button functionality + container.querySelectorAll('.like-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const recipeId = parseInt(btn.closest('.recipe-card').dataset.recipeId); + this.toggleLikeRecipe(recipeId, btn); + }); + }); + + // Follow button functionality + container.querySelectorAll('.follow-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const creatorName = btn.previousElementSibling.textContent; + this.toggleFollowCreator(creatorName, btn); + }); + }); + + // Share button functionality + container.querySelectorAll('.share-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const recipeId = parseInt(btn.closest('.recipe-card').dataset.recipeId); + this.shareRecipe(recipeId); + }); + }); + + // Copy button functionality + container.querySelectorAll('.copy-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const recipeId = parseInt(btn.closest('.recipe-card').dataset.recipeId); + this.copyRecipe(recipeId); + }); + }); + + // Comment button functionality + container.querySelectorAll('.comment-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const recipeId = parseInt(btn.closest('.recipe-card').dataset.recipeId); + this.showComments(recipeId); + }); + }); + } + + toggleSaveRecipe(recipeId, btn) { + const index = this.savedRecipes.indexOf(recipeId); + + if (index > -1) { + this.savedRecipes.splice(index, 1); + btn.classList.remove('saved'); + this.showNotification('Recipe removed from cookbook', 'info'); + } else { + this.savedRecipes.push(recipeId); + btn.classList.add('saved'); + this.showNotification('Recipe saved to cookbook!', 'success'); + } + + localStorage.setItem('savedRecipes', JSON.stringify(this.savedRecipes)); + } + + toggleLikeRecipe(recipeId, btn) { + const index = this.likedRecipes.indexOf(recipeId); + const countSpan = btn.querySelector('.count'); + const recipe = this.recipes.find(r => r.id === recipeId); + + if (index > -1) { + this.likedRecipes.splice(index, 1); + btn.classList.remove('liked'); + recipe.likes--; + } else { + this.likedRecipes.push(recipeId); + btn.classList.add('liked'); + recipe.likes++; + } + + this.recipeLikes[recipeId] = recipe.likes; + countSpan.textContent = recipe.likes; + localStorage.setItem('likedRecipes', JSON.stringify(this.likedRecipes)); + localStorage.setItem('recipeLikes', JSON.stringify(this.recipeLikes)); + } + + toggleFollowCreator(creatorName, btn) { + const index = this.followedCreators.indexOf(creatorName); + + if (index > -1) { + this.followedCreators.splice(index, 1); + btn.classList.remove('following'); + btn.textContent = 'Follow'; + this.showNotification(`Unfollowed ${creatorName}`, 'info'); + } else { + this.followedCreators.push(creatorName); + btn.classList.add('following'); + btn.textContent = 'Following'; + this.showNotification(`Now following ${creatorName}!`, 'success'); + } + + localStorage.setItem('followedCreators', JSON.stringify(this.followedCreators)); + } + + shareRecipe(recipeId) { + const recipe = this.recipes.find(r => r.id === recipeId); + + if (navigator.share) { + navigator.share({ + title: recipe.title, + text: recipe.description, + url: window.location.href + `?recipe=${recipeId}` + }); + } else { + // Fallback: copy to clipboard + const shareUrl = window.location.href + `?recipe=${recipeId}`; + navigator.clipboard.writeText(shareUrl).then(() => { + this.showNotification('Recipe link copied to clipboard!', 'success'); + }); + } + } + + copyRecipe(recipeId) { + const recipe = this.recipes.find(r => r.id === recipeId); + const recipeText = `${recipe.title}\n\n${recipe.description}\n\nIngredients: ${recipe.ingredients.join(', ')}\nCook Time: ${recipe.cookTime} minutes\nDifficulty: ${recipe.difficulty}`; + + navigator.clipboard.writeText(recipeText).then(() => { + this.showNotification('Recipe copied to clipboard!', 'success'); + }); + } + + showComments(recipeId) { + // Placeholder for comments functionality + this.showNotification('Comments feature coming soon!', 'info'); + } + + showNotification(message, type = 'info') { + // Create notification element + const notification = document.createElement('div'); + notification.className = `notification notification-${type}`; + notification.textContent = message; + + // Style the notification + Object.assign(notification.style, { + position: 'fixed', + top: '20px', + right: '20px', + padding: '12px 20px', + borderRadius: '10px', + color: 'white', + fontWeight: '600', + zIndex: '9999', + transform: 'translateX(100%)', + transition: 'transform 0.3s ease' + }); + + // Set background color based on type + const colors = { + success: '#4ecdc4', + error: '#ff6b6b', + info: '#60a5fa' + }; + notification.style.backgroundColor = colors[type] || colors.info; + + // Add to page + document.body.appendChild(notification); + + // Animate in + setTimeout(() => { + notification.style.transform = 'translateX(0)'; + }, 100); + + // Remove after 3 seconds + setTimeout(() => { + notification.style.transform = 'translateX(100%)'; + setTimeout(() => { + document.body.removeChild(notification); + }, 300); + }, 3000); + } +} + +// Initialize Recipe Hub when DOM is loaded +document.addEventListener('DOMContentLoaded', () => { + new RecipeHub(); +}); + +// Export for potential use in other modules +if (typeof module !== 'undefined' && module.exports) { + module.exports = RecipeHub; +} +// Baking Tips Array +const bakingTips = [ + "Always preheat your oven for even baking. ๐Ÿ”ฅ", + "Use room temperature eggs and butter for smoother batters. ๐Ÿฅš๐Ÿงˆ", + "Donโ€™t open the oven door too oftenโ€”it drops the temperature! ๐ŸšชโŒ", + "Weigh your ingredients for accuracy instead of using cups. โš–๏ธ", + "Chill cookie dough before baking for thicker cookies. ๐Ÿช", + "Line pans with parchment paper to prevent sticking. ๐Ÿ“œ", + "Let cakes cool before frosting or the icing will melt. ๐ŸŽ‚", + "Use unsalted butter to control salt levels better. ๐Ÿงˆ", + "Always taste your batter for balance (except raw egg doughs ๐Ÿ˜‰).", + "A pinch of salt enhances the sweetness of desserts. ๐Ÿง‚๐Ÿซ" +]; + +// DOM Elements +const tipBtn = document.getElementById("tipBtn"); +const tipPopup = document.getElementById("tipPopup"); +const tipText = document.getElementById("tipText"); +const closeTip = document.getElementById("closeTip"); + +// Show Random Tip +tipBtn.addEventListener("click", () => { + const randomIndex = Math.floor(Math.random() * bakingTips.length); + tipText.textContent = bakingTips[randomIndex]; + tipPopup.style.display = "block"; +}); + +// Close Popup +closeTip.addEventListener("click", () => { + tipPopup.style.display = "none"; +}); \ No newline at end of file diff --git a/BakeGenuis-AI/js/scale.js b/BakeGenuis-AI/js/scale.js new file mode 100644 index 00000000..9e6a3c27 --- /dev/null +++ b/BakeGenuis-AI/js/scale.js @@ -0,0 +1,282 @@ + // Note: API keys removed for security - implement server-side API calls in production +const API_KEY = null; +const API_URL = null; + + // Ingredient icons mapping + const ingredientIcons = { + 'flour': '๐ŸŒพ', + 'sugar': '๐Ÿฏ', + 'butter': '๐Ÿงˆ', + 'egg': '๐Ÿฅš', + 'milk': '๐Ÿฅ›', + 'baking powder': '๐Ÿฅ„', + 'baking soda': '๐Ÿฅ„', + 'salt': '๐Ÿง‚', + 'vanilla': '๐ŸŒฟ', + 'chocolate': '๐Ÿซ', + 'cocoa': '๐Ÿซ', + 'oil': '๐Ÿซ’', + 'honey': '๐Ÿฏ', + 'yeast': '๐Ÿž', + 'default': '๐Ÿฅ„' + }; + + // Unit conversion data (grams) + const unitConversions = { + 'cup': { + 'flour': 120, + 'sugar': 200, + 'butter': 225, + 'milk': 240, + 'oil': 240, + 'cocoa': 75, + 'default': 240 + }, + 'tablespoon': { + 'flour': 8, + 'sugar': 12, + 'butter': 14, + 'oil': 14, + 'default': 15 + }, + 'teaspoon': { + 'default': 5 + } + }; + + function getIngredientIcon(ingredient) { + const normalizedIngredient = ingredient.toLowerCase(); + for (const [key, icon] of Object.entries(ingredientIcons)) { + if (normalizedIngredient.includes(key)) { + return icon; + } + } + return ingredientIcons.default; + } + + function parseIngredientLine(line) { + // Enhanced regex to capture amount, unit, and ingredient + const patterns = [ + /^(\d+(?:\.\d+)?(?:\/\d+)?)\s*(cups?|cup|tbsp|tablespoons?|tsp|teaspoons?|lbs?|pounds?|oz|ounces?|g|grams?|kg|kilograms?|ml|milliliters?|l|liters?)\s+(.+)$/i, + /^(\d+(?:\.\d+)?(?:\/\d+)?)\s+(.+)$/i + ]; + + for (const pattern of patterns) { + const match = line.trim().match(pattern); + if (match) { + if (match.length === 4) { + return { + amount: parseAmount(match[1]), + unit: match[2].toLowerCase(), + ingredient: match[3].trim() + }; + } else { + return { + amount: parseAmount(match[1]), + unit: 'unit', + ingredient: match[2].trim() + }; + } + } + } + + return { + amount: 1, + unit: 'unit', + ingredient: line.trim() + }; + } + + function parseAmount(value) { + if (value.includes('/')) { + const [num, den] = value.split('/').map(Number); + return num / den; + } + return parseFloat(value); + } + + + function convertToGrams(amount, unit, ingredient) { + const normalizedUnit = unit.toLowerCase(); + const normalizedIngredient = ingredient.toLowerCase(); + + if (normalizedUnit.includes('cup')) { + for (const [key, value] of Object.entries(unitConversions.cup)) { + if (normalizedIngredient.includes(key)) { + return Math.round(amount * value); + } + } + return Math.round(amount * unitConversions.cup.default); + } + + if (normalizedUnit.includes('tbsp') || normalizedUnit.includes('tablespoon')) { + for (const [key, value] of Object.entries(unitConversions.tablespoon)) { + if (normalizedIngredient.includes(key)) { + return Math.round(amount * value); + } + } + return Math.round(amount * unitConversions.tablespoon.default); + } + + if (normalizedUnit.includes('tsp') || normalizedUnit.includes('teaspoon')) { + return Math.round(amount * unitConversions.teaspoon.default); + } + + return null; // Return null if no conversion available + } + + function adjustLeavening(ingredient, originalAmount, scale) { + const normalizedIngredient = ingredient.toLowerCase(); + if (normalizedIngredient.includes('baking powder') || + normalizedIngredient.includes('baking soda') || + normalizedIngredient.includes('yeast')) { + // For leavening agents, scale less aggressively + const adjustedScale = Math.pow(scale, 0.7); + return originalAmount * adjustedScale; + } + return originalAmount * scale; + } + + async function scaleRecipe() { + const currentServings = parseInt(document.getElementById('currentServings').value); + const desiredServings = parseInt(document.getElementById('desiredServings').value); + const recipeInput = document.getElementById('recipeInput').value.trim(); + const convertToGrams = document.getElementById('convertToGrams').checked; + + if (!currentServings || !desiredServings || !recipeInput) { + alert('Please fill in all fields! ๐Ÿฅบ'); + return; + } + + if (currentServings <= 0 || desiredServings <= 0) { + alert('Servings must be positive numbers! ๐Ÿ˜Š'); + return; + } + + // Show loading + document.getElementById('loading').classList.add('show'); + document.getElementById('resultsContainer').classList.remove('show'); + + try { + const scale = desiredServings / currentServings; + const lines = recipeInput.split('\n').filter(line => line.trim()); + const scaledIngredients = []; + + for (const line of lines) { + const parsed = parseIngredientLine(line); + const scaledAmount = adjustLeavening(parsed.ingredient, parsed.amount, scale); + + let displayAmount, displayUnit; + + if (convertToGrams) { + const gramsConversion = convertToGrams(scaledAmount, parsed.unit, parsed.ingredient); + if (gramsConversion) { + displayAmount = gramsConversion; + displayUnit = 'g'; + } else { + displayAmount = Math.round(scaledAmount * 100) / 100; + displayUnit = parsed.unit; + } + } else { + displayAmount = Math.round(scaledAmount * 100) / 100; + displayUnit = parsed.unit; + } + + scaledIngredients.push({ + ingredient: parsed.ingredient, + original: `${parsed.amount} ${parsed.unit}`, + scaled: `${displayAmount} ${displayUnit}`, + icon: getIngredientIcon(parsed.ingredient) + }); + } + + // Display results + displayResults(scaledIngredients, currentServings, desiredServings, scale); + + // Generate suggestions + generateSuggestions(scale, desiredServings); + + } catch (error) { + console.error('Error scaling recipe:', error); + alert('Oops! Something went wrong while scaling your recipe. Please try again! ๐Ÿ™ˆ'); + } finally { + document.getElementById('loading').classList.remove('show'); + } + } + + function displayResults(ingredients, currentServings, desiredServings, scale) { + const resultsBody = document.getElementById('resultsBody'); + const scalingInfo = document.getElementById('scalingInfo'); + + // Clear previous results + resultsBody.innerHTML = ''; + + // Add scaling info + scalingInfo.innerHTML = ` +
    +

    Scaling Factor: ${scale.toFixed(2)}x

    +

    From ${currentServings} servings to ${desiredServings} servings

    +
    + `; + + // Add ingredients + ingredients.forEach(item => { + const row = document.createElement('tr'); + row.innerHTML = ` + + ${item.icon} + ${item.ingredient} + + ${item.original} + ${item.scaled} + `; + resultsBody.appendChild(row); + }); + + document.getElementById('resultsContainer').classList.add('show'); + } + + function generateSuggestions(scale, servings) { + const suggestions = document.getElementById('suggestions'); + let tips = []; + + if (scale > 2) { + tips.push('๐Ÿณ For large batches, consider using multiple pans to ensure even baking.'); + tips.push('โฐ Increase baking time by 10-15% and check doneness with a toothpick.'); + tips.push('๐Ÿ”ฅ Lower oven temperature by 25ยฐF to prevent over-browning.'); + } else if (scale < 0.5) { + tips.push('๐Ÿฅง Use a smaller pan size to maintain proper depth.'); + tips.push('โฐ Reduce baking time by 20-30% and check frequently.'); + tips.push('๐Ÿ”ฅ Increase oven temperature by 25ยฐF for better rise.'); + } else { + tips.push('โœจ This scaling factor is perfect for most recipes!'); + tips.push('๐ŸŽฏ Keep original baking time and temperature.'); + } + + if (servings > 20) { + tips.push('๐ŸŽ‰ Consider making multiple batches for better quality control.'); + } + + tips.push('๐Ÿ“ Always measure ingredients by weight for best results!'); + + suggestions.innerHTML = tips.map(tip => `

    ${tip}

    `).join(''); + } + + function clearInputs() { + document.getElementById('currentServings').value = '6'; + document.getElementById('desiredServings').value = '12'; + document.getElementById('recipeInput').value = ''; + document.getElementById('convertToGrams').checked = false; + document.getElementById('resultsContainer').classList.remove('show'); + } + + // Add some example recipes on page load + window.addEventListener('load', function() { + const examples = [ + "2 cups all-purpose flour\n1 cup sugar\n1/2 cup butter\n2 eggs\n1 tsp baking powder\n1/2 tsp salt\n1 cup milk", + "3 cups flour\n1 cup cocoa powder\n2 cups sugar\n1 tsp baking soda\n1/2 tsp salt\n2 eggs\n1 cup buttermilk", + "4 cups flour\n1/2 cup sugar\n1 packet yeast\n1 tsp salt\n1/4 cup olive oil\n1 1/2 cups warm water" + ]; + + + }); \ No newline at end of file diff --git a/BakeGenuis-AI/js/theme.js b/BakeGenuis-AI/js/theme.js new file mode 100644 index 00000000..2ec3149e --- /dev/null +++ b/BakeGenuis-AI/js/theme.js @@ -0,0 +1,14 @@ +document.addEventListener('DOMContentLoaded', () => { + const toggle = document.getElementById('theme-toggle'); + if (!toggle) return; + + const savedTheme = localStorage.getItem('theme') || 'light'; + document.documentElement.setAttribute('data-theme', savedTheme); + toggle.checked = savedTheme === 'dark'; + + toggle.addEventListener('change', () => { + const newTheme = toggle.checked ? 'dark' : 'light'; + document.documentElement.setAttribute('data-theme', newTheme); + localStorage.setItem('theme', newTheme); + }); +}); \ No newline at end of file diff --git a/BakeGenuis-AI/package-lock.json b/BakeGenuis-AI/package-lock.json new file mode 100644 index 00000000..430b48ef --- /dev/null +++ b/BakeGenuis-AI/package-lock.json @@ -0,0 +1,1058 @@ +{ + "name": "BakeGenuis-AI", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "firebase": "^12.2.1" + } + }, + "node_modules/@firebase/ai": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-2.2.1.tgz", + "integrity": "sha512-0VWlkGB18oDhwMqsgxpt/usMsyjnH3a7hTvQPcAbk7VhFg0QZMDX60mQKfLTFKrB5VwmlaIdVsSZznsTY2S0wA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/analytics": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.18.tgz", + "integrity": "sha512-iN7IgLvM06iFk8BeFoWqvVpRFW3Z70f+Qe2PfCJ7vPIgLPjHXDE774DhCT5Y2/ZU/ZbXPDPD60x/XPWEoZLNdg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.24", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.24.tgz", + "integrity": "sha512-jE+kJnPG86XSqGQGhXXYt1tpTbCTED8OQJ/PQ90SEw14CuxRxx/H+lFbWA1rlFtFSsTCptAJtgyRBwr/f00vsw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.18", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.2.tgz", + "integrity": "sha512-Ecx2ig/JLC9ayIQwZHqm41Tzlf4c1WUuFhFUZB1y+JIJqDRE579x7Uil7tKT8MwDpOPwrK5ZtpxdSsrfy/LF8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.11.0.tgz", + "integrity": "sha512-XAvALQayUMBJo58U/rxW02IhsesaxxfWVmVkauZvGEz3vOAjMEQnzFlyblqkc2iAaO82uJ2ZVyZv9XzPfxjJ6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.4.0.tgz", + "integrity": "sha512-UfK2Q8RJNjYM/8MFORltZRG9lJj11k0nW84rrffiKvcJxLf1jf6IEjCIkCamykHE73C6BwqhVfhIBs69GXQV0g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.11.0", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-compat": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.5.2.tgz", + "integrity": "sha512-cn+U27GDaBS/irsbvrfnPZdcCzeZPRGKieSlyb7vV6LSOL6mdECnB86PgYjYGxSNg8+U48L/NeevTV1odU+mOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.14.2", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.0.tgz", + "integrity": "sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.6.0.tgz", + "integrity": "sha512-J0lGSxXlG/lYVi45wbpPhcWiWUMXevY4fvLZsN1GHh+po7TZVng+figdHBVhFheaiipU8HZyc7ljw1jNojM2nw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.11.0", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", + "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.11.tgz", + "integrity": "sha512-G258eLzAD6im9Bsw+Qm1Z+P4x0PGNQ45yeUuuqe5M9B1rn0RJvvsQCRHXgE52Z+n9+WX1OJd/crcuunvOGc7Vw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/database": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", + "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", + "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/database": "1.1.0", + "@firebase/database-types": "1.0.16", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", + "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.13.0" + } + }, + "node_modules/@firebase/firestore": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.9.1.tgz", + "integrity": "sha512-PYVUTkhC9y8pydrqC3O1Oc4AMfkGSWdmuH9xgPJjiEbpUIUPQ4J8wJhyuash+o2u+axmyNRFP8ULNUKb+WzBzQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "@firebase/webchannel-wrapper": "1.0.4", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.4.1.tgz", + "integrity": "sha512-BjalPTDh/K0vmR/M/DE148dpIqbcfvtFVTietbUDWDWYIl9YH0TTVp/EwXRbZwswPxyjx4GdHW61GB2AYVz1SQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/firestore": "4.9.1", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/functions": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.13.1.tgz", + "integrity": "sha512-sUeWSb0rw5T+6wuV2o9XNmh9yHxjFI9zVGFnjFi+n7drTEWpl7ZTz1nROgGrSu472r+LAaj+2YaSicD4R8wfbw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.4.1.tgz", + "integrity": "sha512-AxxUBXKuPrWaVNQ8o1cG1GaCAtXT8a0eaTDfqgS5VsRYLAR0ALcfqDLwo/QyijZj1w8Qf8n3Qrfy/+Im245hOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/functions": "0.13.1", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/installations": { + "version": "0.6.19", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.19.tgz", + "integrity": "sha512-nGDmiwKLI1lerhwfwSHvMR9RZuIH5/8E3kgUWnVRqqL7kGVSktjLTWEMva7oh5yxQ3zXfIlIwJwMcaM5bK5j8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.19.tgz", + "integrity": "sha512-khfzIY3EI5LePePo7vT19/VEIH1E3iYsHknI/6ek9T8QCozAZshWT9CjlwOzZrKvTHMeNcbpo/VSOSIWDSjWdQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/logger": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", + "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/messaging": { + "version": "0.12.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.23.tgz", + "integrity": "sha512-cfuzv47XxqW4HH/OcR5rM+AlQd1xL/VhuaeW/wzMW1LFrsFcTn0GND/hak1vkQc2th8UisBcrkVcQAnOnKwYxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.23.tgz", + "integrity": "sha512-SN857v/kBUvlQ9X/UjAqBoQ2FEaL1ZozpnmL1ByTe57iXkmnVVFm9KqAsTfmf+OEwWI4kJJe9NObtN/w22lUgg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/messaging": "0.12.23", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.9.tgz", + "integrity": "sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.22.tgz", + "integrity": "sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/performance": "0.7.9", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.6.tgz", + "integrity": "sha512-Yelp5xd8hM4NO1G1SuWrIk4h5K42mNwC98eWZ9YLVu6Z0S6hFk1mxotAdCRmH2luH8FASlYgLLq6OQLZ4nbnCA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.19.tgz", + "integrity": "sha512-y7PZAb0l5+5oIgLJr88TNSelxuASGlXyAKj+3pUc4fDuRIdPNBoONMHaIUa9rlffBR5dErmaD2wUBJ7Z1a513Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/remote-config": "0.6.6", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/storage": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.14.0.tgz", + "integrity": "sha512-xWWbb15o6/pWEw8H01UQ1dC5U3rf8QTAzOChYyCpafV6Xki7KVp3Yaw2nSklUwHEziSWE9KoZJS7iYeyqWnYFA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.4.0.tgz", + "integrity": "sha512-vDzhgGczr1OfcOy285YAPur5pWDEvD67w4thyeCUh6Ys0izN9fNYtA1MJERmNBfqjqu0lg0FM5GLbw0Il21M+g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/storage": "0.14.0", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/util": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", + "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.4.tgz", + "integrity": "sha512-6m8+P+dE/RPl4OPzjTxcTbQ0rGeRyeTvAi9KwIffBVCiAMKrfXfLZaqD1F+m8t4B5/Q5aHsMozOgirkH1F5oMQ==", + "license": "Apache-2.0" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/firebase": { + "version": "12.2.1", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-12.2.1.tgz", + "integrity": "sha512-UkuW2ZYaq/QuOQ24bfaqmkVqoBFhkA/ptATfPuRtc5vdm+zhwc3mfZBwFe6LqH9yrCN/6rAblgxKz2/0tDvA7w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "2.2.1", + "@firebase/analytics": "0.10.18", + "@firebase/analytics-compat": "0.2.24", + "@firebase/app": "0.14.2", + "@firebase/app-check": "0.11.0", + "@firebase/app-check-compat": "0.4.0", + "@firebase/app-compat": "0.5.2", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.11.0", + "@firebase/auth-compat": "0.6.0", + "@firebase/data-connect": "0.3.11", + "@firebase/database": "1.1.0", + "@firebase/database-compat": "2.1.0", + "@firebase/firestore": "4.9.1", + "@firebase/firestore-compat": "0.4.1", + "@firebase/functions": "0.13.1", + "@firebase/functions-compat": "0.4.1", + "@firebase/installations": "0.6.19", + "@firebase/installations-compat": "0.2.19", + "@firebase/messaging": "0.12.23", + "@firebase/messaging-compat": "0.2.23", + "@firebase/performance": "0.7.9", + "@firebase/performance-compat": "0.2.22", + "@firebase/remote-config": "0.6.6", + "@firebase/remote-config-compat": "0.2.19", + "@firebase/storage": "0.14.0", + "@firebase/storage-compat": "0.4.0", + "@firebase/util": "1.13.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "license": "MIT" + }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/BakeGenuis-AI/package.json b/BakeGenuis-AI/package.json new file mode 100644 index 00000000..b6f9b758 --- /dev/null +++ b/BakeGenuis-AI/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "firebase": "^12.2.1" + } +} diff --git a/BakeGenuis-AI/scale.html b/BakeGenuis-AI/scale.html new file mode 100644 index 00000000..b98c547f --- /dev/null +++ b/BakeGenuis-AI/scale.html @@ -0,0 +1,1250 @@ + + + + + + Scale Recipes - BakeGenius.ai + + + + + + + + + + + +
    +
    ๐Ÿง
    +
    ๐Ÿฐ
    +
    ๐Ÿฅง
    +
    ๐Ÿช
    +
    + + + + + +
    + +
    +

    ๐Ÿ“ Scale Your Recipes

    +

    Perfect portions for any crowd - from intimate dinners to grand celebrations!

    +
    + + +
    + +
    +

    ๐ŸŽฏ Recipe Scaling

    + +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    + +
    + Keep Original Units + + Convert to Grams +
    + +
    + + + + + +
    +
    + + + +
    +

    ๐Ÿ“Š Scaled Results

    + +
    +
    +

    Scaling your recipe with AI magic... ๐Ÿช„

    +
    + +
    +
    + + + + + + + + + + +
    IngredientOriginalScaled
    + +
    +

    ๐Ÿ”ฎ Smart Baking Tips

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BakeGenuis-AI/server.js b/BakeGenuis-AI/server.js new file mode 100644 index 00000000..6b396e88 --- /dev/null +++ b/BakeGenuis-AI/server.js @@ -0,0 +1,75 @@ +const http = require('http'); +const fs = require('fs'); +const path = require('path'); + +const port = process.env.PORT || 8080; + +// MIME types for different file extensions +const mimeTypes = { + '.html': 'text/html', + '.css': 'text/css', + '.js': 'application/javascript', + '.png': 'image/png', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.gif': 'image/gif', + '.svg': 'image/svg+xml', + '.ico': 'image/x-icon', + '.webmanifest': 'application/manifest+json' +}; + +const server = http.createServer((req, res) => { + // Parse URL and get file path + let filePath = '.' + req.url; + + // Default to index.html if requesting root + if (filePath === './') { + filePath = './index.html'; + } + + // Get file extension for MIME type + const extname = String(path.extname(filePath)).toLowerCase(); + const mimeType = mimeTypes[extname] || 'application/octet-stream'; + + // Read and serve the file + fs.readFile(filePath, (error, content) => { + if (error) { + if (error.code === 'ENOENT') { + // File not found + res.writeHead(404, { 'Content-Type': 'text/html' }); + res.end('

    404 - File Not Found

    The requested file was not found.

    '); + } else { + // Server error + res.writeHead(500); + res.end('Sorry, there was an error: ' + error.code + '..\n'); + } + } else { + // Success - add cache headers for static assets + const headers = { 'Content-Type': mimeType }; + if (extname === '.css' || extname === '.js' || extname === '.png' || extname === '.jpg' || extname === '.ico') { + headers['Cache-Control'] = 'public, max-age=86400'; // 1 day cache + } + res.writeHead(200, headers); + res.end(content, 'utf-8'); + } + }); +}); + +server.listen(port, () => { + console.log(`๐Ÿฐ BakeGenius.AI Server running at http://localhost:${port}/`); + console.log('Available pages:'); + console.log(` โ€ข Home: http://localhost:${port}/`); + console.log(` โ€ข Customize: http://localhost:${port}/html/customize.html`); + console.log(` โ€ข Scale Recipe: http://localhost:${port}/scale.html`); + console.log(` โ€ข About Us: http://localhost:${port}/html/about.html`); + console.log(` โ€ข Convert Recipe: http://localhost:${port}/html/convert.html`); + console.log('\nPress Ctrl+C to stop the server'); + + // Try to open browser automatically (Windows) + const { exec } = require('child_process'); + exec(`start http://localhost:${port}`, (error) => { + if (error) { + console.log('\nManually open your browser and go to http://localhost:8080'); + } + }); +}); diff --git a/BakeGenuis-AI/site.webmanifest b/BakeGenuis-AI/site.webmanifest new file mode 100644 index 00000000..45dc8a20 --- /dev/null +++ b/BakeGenuis-AI/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/html/recipe_hub.html b/html/recipe_hub.html index 859ae7b8..0ffe0a37 100644 --- a/html/recipe_hub.html +++ b/html/recipe_hub.html @@ -62,7 +62,7 @@ - +
    diff --git a/index.html b/index.html index b36d0978..a11310ab 100644 --- a/index.html +++ b/index.html @@ -24,13 +24,7 @@ - -
    -
    - -

    Ready for some baking

    -
    -
    +