From 98ad79899e5dc5403b6d4d2be457c9b4d3158470 Mon Sep 17 00:00:00 2001 From: Kobe Date: Mon, 30 Jun 2025 16:19:03 +0200 Subject: [PATCH] Initial commit: Complete multilingual website with translation system --- .gitignore | 156 + Dockerfile | 12 + README.md | 160 + app.py | 94 + docker-compose.yml | 13 + example_usage.md | 167 + requirements.txt | 5 + robots.txt | 19 + static/css/main.css | 4600 +++++++++++++++++ static/images/favicon.ico | 1 + static/images/og-image.jpg | 1 + static/js/main.js | 355 ++ templates/about.html | 294 ++ templates/base.html | 192 + templates/components/cta_section.html | 16 + templates/components/hero_section.html | 27 + templates/components/stats_section.html | 14 + .../components/testimonials_section.html | 69 + templates/contact.html | 304 ++ templates/index.html | 354 ++ templates/portfolio.html | 364 ++ templates/services.html | 262 + test_translations.py | 39 + translation_manager.py | 180 + translations/de.json | 288 ++ translations/en.json | 288 ++ translations/fr.json | 288 ++ translations/nl.json | 288 ++ 28 files changed, 8850 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 app.py create mode 100644 docker-compose.yml create mode 100644 example_usage.md create mode 100644 requirements.txt create mode 100644 robots.txt create mode 100644 static/css/main.css create mode 100644 static/images/favicon.ico create mode 100644 static/images/og-image.jpg create mode 100644 static/js/main.js create mode 100644 templates/about.html create mode 100644 templates/base.html create mode 100644 templates/components/cta_section.html create mode 100644 templates/components/hero_section.html create mode 100644 templates/components/stats_section.html create mode 100644 templates/components/testimonials_section.html create mode 100644 templates/contact.html create mode 100644 templates/index.html create mode 100644 templates/portfolio.html create mode 100644 templates/services.html create mode 100644 test_translations.py create mode 100644 translation_manager.py create mode 100644 translations/de.json create mode 100644 translations/en.json create mode 100644 translations/fr.json create mode 100644 translations/nl.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..782cc31 --- /dev/null +++ b/.gitignore @@ -0,0 +1,156 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Docker +.dockerignore + +# Logs +*.log +logs/ + +# Temporary files +*.tmp +*.temp \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e79fb0d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.11-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +EXPOSE 5000 + +CMD ["python", "app.py"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..72cb958 --- /dev/null +++ b/README.md @@ -0,0 +1,160 @@ +# Kobelly Web Solutions + +A professional Flask-based website for promoting small business web development services. Features multilanguage support (English, Dutch, French, German) and is fully dockerized for easy deployment. + +## Features + +- 🌐 **Multilanguage Support**: English (EN), Dutch (NL), French (FR), German (DE) +- 📱 **Responsive Design**: Modern, mobile-friendly interface +- 🎨 **Professional UI**: Clean, modern design with Bootstrap 5 +- 🐳 **Docker Support**: Easy containerization and deployment +- ⚡ **Fast Performance**: Optimized for speed and performance +- 🔧 **No Database Required**: Simple, lightweight setup + +## Pages + +- **Home**: Hero section, features, and service overview +- **Services**: Detailed service offerings with pricing information +- **About**: Company story, team, and values +- **Contact**: Contact form and business information + +## Quick Start + +### Local Development (Recommended) + +1. **Install Python dependencies:** + ```bash + pip install -r requirements.txt + ``` + +2. **Run the application:** + ```bash + python app.py + ``` + +3. **Access the website:** + Open your browser and go to `http://localhost:5000` + +### Docker Deployment + +1. **Build and run with Docker Compose:** + ```bash + docker-compose up --build + ``` + +2. **Or build and run manually:** + ```bash + docker build -t kobelly-website . + docker run -p 5000:5000 kobelly-website + ``` + +## Project Structure + +``` +Kobelly/ +├── app.py # Main Flask application +├── requirements.txt # Python dependencies +├── Dockerfile # Docker configuration +├── docker-compose.yml # Docker Compose configuration +├── babel.cfg # Babel configuration for translations +├── templates/ # HTML templates +│ ├── base.html # Base template with navigation +│ ├── index.html # Homepage +│ ├── services.html # Services page +│ ├── about.html # About page +│ └── contact.html # Contact page +└── translations/ # Translation files + ├── en/LC_MESSAGES/messages.po + ├── nl/LC_MESSAGES/messages.po + ├── fr/LC_MESSAGES/messages.po + └── de/LC_MESSAGES/messages.po +``` + +## Multilanguage Support + +The website supports four languages: +- 🇺🇸 **English** (EN) - Default +- 🇳🇱 **Dutch** (NL) +- 🇫🇷 **French** (FR) +- 🇩🇪 **German** (DE) + +Users can switch languages using the language selector in the navigation bar. The language preference is stored in the session. + +## Customization + +### Content Updates + +1. **Text Content**: Edit the HTML templates in the `templates/` directory +2. **Translations**: Update the `.po` files in the `translations/` directory +3. **Styling**: Modify the CSS in `templates/base.html` + +### Adding New Pages + +1. Add a new route in `app.py` +2. Create a new template file in `templates/` +3. Add navigation link in `templates/base.html` + +### Updating Translations + +1. Extract translatable strings: + ```bash + pybabel extract -F babel.cfg -o messages.pot . + ``` + +2. Update translation files: + ```bash + pybabel update -i messages.pot -d translations + ``` + +3. Compile translations: + ```bash + pybabel compile -d translations + ``` + +## Configuration + +### Environment Variables + +- `SECRET_KEY`: Secret key for Flask sessions (default: 'your-secret-key-change-in-production') +- `FLASK_ENV`: Flask environment (development/production) + +### Production Deployment + +For production deployment: + +1. Set a strong `SECRET_KEY` +2. Disable debug mode +3. Use a production WSGI server (e.g., Gunicorn) +4. Set up proper SSL/TLS certificates +5. Configure a reverse proxy (e.g., Nginx) + +## Technologies Used + +- **Backend**: Flask 2.3.3 +- **Frontend**: Bootstrap 5, Font Awesome +- **Internationalization**: Flask-Babel +- **Containerization**: Docker, Docker Compose +- **Styling**: Custom CSS with CSS variables + +## Browser Support + +- Chrome (latest) +- Firefox (latest) +- Safari (latest) +- Edge (latest) +- Mobile browsers (iOS Safari, Chrome Mobile) + +## License + +This project is created for demonstration purposes. Feel free to use and modify for your own business needs. + +## Support + +For questions or support, please contact: +- Email: info@kobelly.com +- Phone: +32 486 21 07 07 +- Address: Blijkheerstraat 92, 1755 Pajottegem, Belgium + +--- + +**Kobelly Web Solutions** - Professional web development for small businesses and entrepreneurs. \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..f13028c --- /dev/null +++ b/app.py @@ -0,0 +1,94 @@ +from flask import Flask, render_template, request, session, redirect, url_for, make_response +from translation_manager import init_app, translate, get_current_language, create_language_selector, set_language +import os +from datetime import datetime +from xml.etree import ElementTree as ET + +app = Flask(__name__) +app.secret_key = os.environ.get('SECRET_KEY', 'your-secret-key-change-in-production') + +# Initialize the translation system +init_app(app) + +# Context processor to make variables available in templates +@app.context_processor +def inject_conf_var(): + return dict( + translate=translate, + get_current_language=get_current_language, + create_language_selector=create_language_selector, + t=translate, # Short alias + current_year=datetime.now().year + ) + +def generate_sitemap(): + """Generate XML sitemap for the website""" + root = ET.Element("urlset") + root.set("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9") + + # Define the main pages with their priorities and change frequencies + pages = [ + {'url': '/', 'priority': '1.0', 'changefreq': 'weekly'}, + {'url': '/services', 'priority': '0.9', 'changefreq': 'monthly'}, + {'url': '/about', 'priority': '0.8', 'changefreq': 'monthly'}, + {'url': '/contact', 'priority': '0.7', 'changefreq': 'monthly'}, + {'url': '/portfolio', 'priority': '0.8', 'changefreq': 'weekly'}, + ] + + base_url = "https://kobelly.com" # Change this to your actual domain + + for page in pages: + url_elem = ET.SubElement(root, "url") + loc = ET.SubElement(url_elem, "loc") + loc.text = base_url + page['url'] + + lastmod = ET.SubElement(url_elem, "lastmod") + lastmod.text = datetime.now().strftime("%Y-%m-%d") + + changefreq = ET.SubElement(url_elem, "changefreq") + changefreq.text = page['changefreq'] + + priority = ET.SubElement(url_elem, "priority") + priority.text = page['priority'] + + return ET.tostring(root, encoding='unicode', method='xml') + +@app.route('/sitemap.xml') +def sitemap(): + """Serve the XML sitemap""" + sitemap_xml = generate_sitemap() + response = make_response(sitemap_xml) + response.headers["Content-Type"] = "application/xml" + return response + +@app.route('/') +def index(): + print("Current language in index:", get_current_language()) + return render_template('index.html') + +@app.route('/services') +def services(): + return render_template('services.html') + +@app.route('/contact') +def contact(): + return render_template('contact.html') + +@app.route('/about') +def about(): + return render_template('about.html') + +@app.route('/portfolio') +def portfolio(): + return render_template('portfolio.html') + +@app.route('/set_language/') +def set_language_route(language): + """Set the language and redirect back to the previous page""" + if set_language(language): + # Redirect back to the referring page or home + return redirect(request.referrer or url_for('index')) + return redirect(url_for('index')) + +if __name__ == '__main__': + app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3b0fb60 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3.8' + +services: + web: + build: . + ports: + - "5000:5000" + environment: + - FLASK_ENV=development + - SECRET_KEY=your-secret-key-change-in-production + volumes: + - .:/app + restart: unless-stopped \ No newline at end of file diff --git a/example_usage.md b/example_usage.md new file mode 100644 index 0000000..e9101db --- /dev/null +++ b/example_usage.md @@ -0,0 +1,167 @@ +# JSON-Based Translation System for Kobelly + +## 🎉 Benefits of This System + +✅ **No compilation needed** - Just edit JSON files directly +✅ **Edit English without breaking translations** - Each language is independent +✅ **Simple and lightweight** - No complex dependencies +✅ **Real-time updates** - Changes appear immediately after restart +✅ **Easy to maintain** - Clear JSON structure + +## 📁 File Structure + +``` +translations/ +├── en.json # English translations +├── de.json # German translations +├── fr.json # French translations +└── nl.json # Dutch translations +``` + +## 🔧 How to Use + +### 1. In Templates + +Replace Babel syntax with the new system: + +**Old (Babel):** +```html +

{{ _('Welcome to Kobelly Web Solutions') }}

+

{{ _('We create stunning, modern websites') }}

+``` + +**New (JSON-based):** +```html +

{{ translate('Welcome to Kobelly Web Solutions') }}

+

{{ translate('We create stunning, modern websites') }}

+ + +

{{ t('Welcome to Kobelly Web Solutions') }}

+

{{ t('We create stunning, modern websites') }}

+``` + +### 2. Adding New Translations + +1. **Add the string to your template:** +```html +

{{ t('New Section Title') }}

+``` + +2. **Add it to the translation files:** +```json +// translations/en.json +{ + "New Section Title": "New Section Title" +} + +// translations/de.json +{ + "New Section Title": "Neuer Abschnittstitel" +} +``` + +3. **Restart your Flask app** - Changes appear immediately! + +### 3. Language Switching + +The system automatically detects language from: +- URL parameter: `?lang=de` +- Session storage +- Browser preferences + +**Manual language switching:** +```html +English +Deutsch +Français +Nederlands +``` + +**Or use the built-in selector:** +```html +{{ create_language_selector() | safe }} +``` + +## 🛠️ Management Scripts + +### Extract New Strings +```bash +python extract_translations.py +``` + +### Clean Translation Files +```bash +python clean_translations.py +``` + +### Add New Language +1. Add language code to `SUPPORTED_LANGUAGES` in `translation_manager.py` +2. Create `translations/[lang].json` +3. Add translations + +## 📝 Example Translation File + +```json +{ + "Home": "Home", + "Services": "Services", + "About": "About", + "Contact": "Contact", + "Welcome to Kobelly Web Solutions": "Welcome to Kobelly Web Solutions", + "We create stunning, modern websites that drive results": "We create stunning, modern websites that drive results" +} +``` + +## 🔄 Migration from Babel + +1. **Replace template syntax:** + - `{{ _('text') }}` → `{{ t('text') }}` + - `{{ gettext('text') }}` → `{{ translate('text') }}` + +2. **Remove Babel dependencies:** + - Remove `Flask-Babel` from requirements.txt + - Remove `babel.cfg` + +3. **Update app.py:** + - Remove Babel imports and configuration + - Add translation manager imports + +## 🚀 Getting Started + +1. **Start the app:** +```bash +python app.py +``` + +2. **Edit translations:** + - Open `translations/[language].json` + - Replace English text with translations + - Save and restart app + +3. **Test language switching:** + - Visit `http://localhost:5000?lang=de` + - Or use the language selector + +## 💡 Tips + +- **Keep keys descriptive** - Use full sentences as keys +- **Use consistent naming** - Follow the same pattern for similar content +- **Test all languages** - Make sure translations fit in your layout +- **Backup your translations** - JSON files are easy to version control + +## 🔧 Troubleshooting + +**Translations not showing?** +- Check that the key exists in the JSON file +- Restart the Flask application +- Check browser console for errors + +**Language not switching?** +- Clear browser cache +- Check session storage +- Verify language code is in `SUPPORTED_LANGUAGES` + +**New strings not appearing?** +- Run `python extract_translations.py` to extract new strings +- Add translations to all language files +- Restart the application \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1dd501a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Flask==2.3.3 +Werkzeug==2.3.7 +click==8.1.7 +blinker==1.6.3 +# Translation system - JSON-based, no compilation needed \ No newline at end of file diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..a0b6206 --- /dev/null +++ b/robots.txt @@ -0,0 +1,19 @@ +User-agent: * +Allow: / + +# Sitemap location +Sitemap: https://kobelly.com/sitemap.xml + +# Crawl delay (optional - be respectful to server) +Crawl-delay: 1 + +# Disallow admin areas (if any) +Disallow: /admin/ +Disallow: /private/ +Disallow: /temp/ + +# Allow important pages +Allow: /services/ +Allow: /about/ +Allow: /contact/ +Allow: /portfolio/ \ No newline at end of file diff --git a/static/css/main.css b/static/css/main.css new file mode 100644 index 0000000..99991f4 --- /dev/null +++ b/static/css/main.css @@ -0,0 +1,4600 @@ +:root { + --primary-color: #2c3e50; + --secondary-color: #3498db; + --accent-color: #e74c3c; + --light-bg: #ecf0f1; + --dark-bg: #181a1b; + --section-bg: #f7f9fa; + --text-color: #222; + --card-bg: #fff; + --footer-bg: var(--primary-color); +} +[data-theme="dark"] { + --primary-color: #181a1b; + --secondary-color: #3498db; + --accent-color: #e74c3c; + --light-bg: #23272b; + --dark-bg: #111213; + --section-bg: #23272b; + --text-color: #bdc3c7; + --card-bg: #181a1b; + --footer-bg: #111213; +} +body { + background: var(--light-bg); + color: var(--text-color); + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + line-height: 1.6; + padding-top: 63px; /* Add padding to account for fixed navbar */ +} +body > *:not(.navbar) { + opacity: 0; + transition: opacity 0.7s ease; +} +body.page-loaded > *:not(.navbar) { + opacity: 1; +} +.navbar { + position: fixed; + top: 0; + width: 100%; + z-index: 1030; + background-color: var(--footer-bg) !important; + opacity: 1 !important; /* Keep navbar always visible */ +} +.navbar, .footer { + background-color: var(--footer-bg) !important; +} +.card, .service-card { + background: var(--card-bg); + color: var(--text-color); +} +.navbar-brand { + font-weight: bold; + font-size: 1.5rem; +} +.hero-section { + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: white; + padding: 100px 0; + position: relative; + overflow: hidden; +} +.service-card { + transition: transform 0.3s ease; + border: none; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); +} +.language-selector { + position: relative; +} +.language-dropdown { + position: absolute; + top: 100%; + right: 0; + background: white; + border: 1px solid #ddd; + border-radius: 4px; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); + z-index: 1000; + min-width: 150px; +} +[data-theme="dark"] .language-dropdown { + background: var(--card-bg); + color: var(--text-color); + border: 1px solid #333; +} +.language-dropdown a { + display: block; + padding: 10px 15px; + text-decoration: none; + color: var(--primary-color); + border-bottom: 1px solid #eee; +} +[data-theme="dark"] .language-dropdown a { + color: var(--text-color); + border-bottom: 1px solid #333; +} +.language-dropdown a:hover { + background-color: var(--light-bg); +} +.footer { + color: white; + padding: 40px 0 20px; +} +.btn-primary { + background-color: var(--secondary-color); + border-color: var(--secondary-color); +} +.btn-primary:hover { + background-color: #2980b9; + border-color: #2980b9; +} +.btn-toggle-dark { + background: none; + border: none; + color: #fff; + font-size: 1.3rem; + margin-left: 1rem; + cursor: pointer; +} +[data-theme="dark"] .btn-toggle-dark { + color: #f5f6fa; +} +/* Bootstrap color utility overrides for theme support */ +.bg-light { + background-color: var(--section-bg) !important; +} +.bg-primary { + background-color: var(--secondary-color) !important; + color: #fff !important; +} +.bg-secondary { + background-color: var(--primary-color) !important; + color: #fff !important; +} +.text-primary { + color: var(--secondary-color) !important; +} +.text-secondary { + color: var(--primary-color) !important; +} +.text-muted { + color: #888 !important; +} +.fade-in-up { + opacity: 0; + transform: translateY(30px); + transition: opacity 0.7s cubic-bezier(.4,0,.2,1), transform 0.7s cubic-bezier(.4,0,.2,1); +} +.fade-in-up.visible { + opacity: 1; + transform: translateY(0); +} + +/* IT-like Hero Background Animation */ +.hero-animation-container { + position: absolute; + top: 0; + right: 0; + width: 50%; + height: 100%; + pointer-events: none; + z-index: 1; + opacity: 0; + animation: fadeInHero 2s ease-out forwards; +} + +@keyframes fadeInHero { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +.floating-element { + position: absolute; + color: rgba(255, 255, 255, 0.25); + font-size: 1.5rem; + animation: backgroundFloat 6s ease-in-out infinite; + opacity: 0; + animation-delay: 2s, 2s; + animation-fill-mode: forwards; +} + +.floating-element:nth-child(1) { + top: 20%; + left: 10%; + right: auto; + animation-delay: 2s, 2s; + font-size: 2rem; +} + +.floating-element:nth-child(2) { + top: 35%; + left: 80%; + right: auto; + animation-delay: 2.5s, 2.5s; + font-size: 1.8rem; +} + +.floating-element:nth-child(3) { + top: 50%; + left: 15%; + right: auto; + animation-delay: 3s, 3s; + font-size: 1.3rem; +} + +.floating-element:nth-child(4) { + top: 65%; + left: 85%; + right: auto; + animation-delay: 3.5s, 3.5s; + font-size: 1.6rem; +} + +.floating-element:nth-child(5) { + top: 80%; + left: 25%; + right: auto; + animation-delay: 4s, 4s; + font-size: 1.4rem; +} + +.floating-element:nth-child(6) { + top: 15%; + left: 75%; + right: auto; + animation-delay: 4.5s, 4.5s; + font-size: 1.7rem; +} + +.floating-element:nth-child(7) { + top: 70%; + left: 5%; + right: auto; + animation-delay: 5s, 5s; + font-size: 1.2rem; +} + +.floating-element:nth-child(8) { + top: 25%; + left: 90%; + right: auto; + animation-delay: 5.5s, 5.5s; + font-size: 1.9rem; +} + +@keyframes backgroundFloat { + 0% { + transform: translateY(0px) rotate(0deg); + opacity: 0; + } + 10% { + opacity: 0.25; + } + 25% { + transform: translateY(-20px) rotate(5deg); + opacity: 0.25; + } + 50% { + transform: translateY(-10px) rotate(-3deg); + opacity: 0.25; + } + 75% { + transform: translateY(-15px) rotate(2deg); + opacity: 0.25; + } + 100% { + transform: translateY(0px) rotate(0deg); + opacity: 0.25; + } +} + +.code-particle { + position: absolute; + color: rgba(52, 152, 219, 0.6); + font-family: 'Courier New', monospace; + font-size: 0.8rem; + font-weight: bold; + animation: codeFlow 8s linear infinite; + opacity: 0; + animation-delay: 2.5s, 2.5s; + animation-fill-mode: forwards; +} + +.code-particle:nth-child(9) { + top: 10%; + left: 20%; + right: auto; +} + +.code-particle:nth-child(10) { + top: 30%; + left: 70%; + right: auto; +} + +.code-particle:nth-child(11) { + top: 60%; + left: 15%; + right: auto; +} + +.code-particle:nth-child(12) { + top: 85%; + left: 80%; + right: auto; +} + +@keyframes codeFlow { + 0% { + transform: translateY(100px) translateX(0); + opacity: 0; + } + 10% { + opacity: 0.9; + } + 90% { + opacity: 0.9; + } + 100% { + transform: translateY(-100px) translateX(20px); + opacity: 0; + } +} + +.circuit-line { + position: absolute; + background: linear-gradient(90deg, transparent, rgba(52, 152, 219, 0.4), transparent); + height: 1px; + animation: circuitPulse 4s ease-in-out infinite; + opacity: 0; + animation-delay: 3s, 3s; + animation-fill-mode: forwards; +} + +.circuit-line:nth-child(13) { + top: 25%; + right: 0; + width: 60%; + animation-delay: 3s, 3s; +} + +.circuit-line:nth-child(14) { + top: 55%; + right: 0; + width: 40%; + animation-delay: 3.5s, 3.5s; +} + +.circuit-line:nth-child(15) { + top: 75%; + right: 0; + width: 70%; + animation-delay: 4s, 4s; +} + +@keyframes circuitPulse { + 0% { + opacity: 0; + transform: scaleX(0); + } + 50% { + opacity: 1; + transform: scaleX(1); + } + 100% { + opacity: 0; + transform: scaleX(0); + } +} + +.hero-content { + position: relative; + z-index: 2; +} + +/* Responsive adjustments for animation */ +@media (max-width: 768px) { + .hero-animation-container { + width: 100%; + opacity: 0.3; + } + + .floating-element { + display: none !important; + } + + .code-particle { + display: none !important; + } + + /* Ensure text content has proper spacing from floating elements */ + .hero-text-content { + position: relative; + z-index: 3; + padding-left: 1rem; + padding-right: 1rem; + } + + /* Reduce animation intensity on mobile for better performance */ + .floating-element { + animation-duration: 8s; + } + + .code-particle { + animation-duration: 10s; + } +} + +/* Process Section Styling */ +.process-step { + transition: transform 0.3s ease, opacity 0.3s ease; +} + +.process-step:hover { + /* Removed translateY(-10px) */ +} + +.process-icon { + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.process-icon::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); + transition: left 0.5s ease; +} + +.process-step:hover .process-icon { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4) !important; +} + +.process-step:hover .process-icon::before { + left: 100%; +} + +.process-content { + transition: opacity 0.3s ease; +} + +.process-step:hover .process-content { + opacity: 0.9; +} + +/* Process connecting line */ +.process-connecting-line { + position: absolute; + top: 40px; + left: 12.5%; + right: 12.5%; + height: 2px; + z-index: 1; +} + +.process-connecting-line::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 100%; + background: linear-gradient(90deg, var(--secondary-color), var(--secondary-color) 50%, rgba(52, 152, 219, 0.3) 75%, transparent); +} + +[data-theme="dark"] .process-connecting-line::before { + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); +} + +/* Process step numbers for mobile */ +@media (max-width: 767px) { + .process-icon::after { + content: attr(data-step); + position: absolute; + top: -8px; + right: -8px; + background: var(--accent-color); + color: white; + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 0.8rem; + font-weight: bold; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 2px 8px rgba(231, 76, 60, 0.3); + } +} + +/* Enhanced Service Cards Styling */ +.service-card-enhanced { + transition: all 0.3s ease; + border: none; + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + overflow: hidden; +} + +.service-card-enhanced::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--secondary-color), var(--secondary-color) 50%, rgba(52, 152, 219, 0.3) 75%, transparent); + transform: scaleX(0); + transition: transform 0.3s ease; +} + +.service-card-enhanced:hover { + /* Removed translateY(-10px) */ + box-shadow: 0 8px 30px rgba(0,0,0,0.15); +} + +.service-card-enhanced:hover::before { + transform: scaleX(1); +} + +.service-icon-wrapper { + position: relative; + display: inline-block; +} + +.service-icon { + transition: all 0.3s ease; + position: relative; + z-index: 1; +} + +.service-icon-wrapper::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(52, 152, 219, 0.1); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: all 0.3s ease; + z-index: 0; +} + +.service-card-enhanced:hover .service-icon-wrapper::after { + width: 80px; + height: 80px; +} + +.service-card-enhanced:hover .service-icon { + transform: scale(1.1); +} + +.service-badge { + display: inline-block; +} + +.service-badge .badge { + font-size: 0.8rem; + padding: 0.5rem 1rem; + border-radius: 20px; + font-weight: 600; +} + +.service-feature-list { + margin: 0; + padding: 0; +} + +.service-feature-item { + display: flex; + align-items: center; + padding: 0.5rem 0; + transition: all 0.2s ease; + border-radius: 8px; + padding-left: 0.5rem; + margin-left: -0.5rem; +} + +.service-feature-item:hover { + background: rgba(52, 152, 219, 0.05); + transform: translateX(5px); +} + +.service-feature-item i { + font-size: 1.1rem; + min-width: 20px; + transition: all 0.2s ease; +} + +.service-feature-item:hover i { + transform: scale(1.2); +} + +.service-footer { + padding-top: 1rem; + border-top: 1px solid rgba(0,0,0,0.1); +} + +[data-theme="dark"] .service-footer { + border-top: 1px solid rgba(255,255,255,0.1); +} + +.service-footer .btn { + transition: all 0.3s ease; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.service-footer .btn:hover { + /* Removed translateY(-2px) */ + box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3); +} + +/* Service card responsive adjustments */ +@media (max-width: 768px) { + .service-card-enhanced { + margin-bottom: 2rem; + } + + .service-feature-item { + padding: 0.75rem 0; + } + + .service-icon { + font-size: 3rem !important; + } +} + +/* CTA Section Background Animation */ +.cta-section { + position: relative; + overflow: hidden; +} + +.cta-bg-animation { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1; + pointer-events: none; +} + +.cta-particle { + position: absolute; + background: rgba(255, 255, 255, 0.1); + border-radius: 50%; + animation: ctaFloat 8s ease-in-out infinite; +} + +.cta-particle-1 { + width: 8px; + height: 8px; + top: 20%; + left: 10%; + animation-delay: 0s; +} + +.cta-particle-2 { + width: 12px; + height: 12px; + top: 60%; + left: 80%; + animation-delay: 2s; +} + +.cta-particle-3 { + width: 6px; + height: 6px; + top: 80%; + left: 20%; + animation-delay: 4s; +} + +.cta-particle-4 { + width: 10px; + height: 10px; + top: 30%; + left: 70%; + animation-delay: 1s; +} + +.cta-particle-5 { + width: 14px; + height: 14px; + top: 70%; + left: 60%; + animation-delay: 3s; +} + +@keyframes ctaFloat { + 0%, 100% { + transform: translateY(0px) translateX(0px); + opacity: 0.3; + } + 25% { + transform: translateY(-20px) translateX(10px); + opacity: 0.6; + } + 50% { + transform: translateY(-10px) translateX(-5px); + opacity: 0.4; + } + 75% { + transform: translateY(-15px) translateX(15px); + opacity: 0.7; + } +} + +.cta-btn { + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.cta-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); + transition: left 0.5s ease; +} + +.cta-btn:hover { + /* Removed translateY(-2px) */ + box-shadow: 0 4px 15px rgba(0,0,0,0.2); +} + +.cta-btn:hover::before { + left: 100%; +} + +/* CTA responsive adjustments */ +@media (max-width: 768px) { + .cta-particle { + display: none; + } +} + +[data-theme="dark"] .service-card-enhanced::before { + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); +} + +/* Enhanced Home Page Styling */ + +/* Hero Section Enhancements */ +.hero-text-content { + animation: fadeInUp 1s ease-out; +} + +.hero-badge .badge { + font-size: 0.9rem; + font-weight: 600; + border-radius: 25px; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); +} + +.hero-title { + font-size: 3.5rem; + line-height: 1.2; + text-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +.hero-description { + font-size: 1.25rem; + line-height: 1.6; + opacity: 0.95; +} + +.hero-stats { + background: rgba(255, 255, 255, 0.1); + border-radius: 15px; + padding: 1.5rem; + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.stat-item h3 { + font-size: 2rem; + margin-bottom: 0.25rem; +} + +.hero-buttons .btn { + border-radius: 50px; + font-weight: 600; + transition: all 0.3s ease; +} + +.hero-buttons .btn:hover { + /* Removed translateY(-2px) */ + box-shadow: 0 4px 15px rgba(0,0,0,0.2); +} + +.hero-visual { + position: relative; + animation: fadeInRight 1s ease-out 0.3s both; +} + +.hero-icon-wrapper { + position: relative; + display: inline-block; +} + +.hero-main-icon { + font-size: 8rem; + opacity: 0.9; + position: relative; + z-index: 2; + animation: heroFloat 6s ease-in-out infinite; +} + +@keyframes heroFloat { + 0%, 100% { + transform: translateY(0px); + opacity: 0.9; + } + 25% { + transform: translateY(-10px); + opacity: 0.9; + } + 50% { + transform: translateY(-5px); + opacity: 0.9; + } + 75% { + transform: translateY(-8px); + opacity: 0.9; + } +} + +.hero-icon-glow { + position: absolute; + top: 50%; + left: 50%; + width: 200px; + height: 200px; + background: radial-gradient(circle, rgba(52, 152, 219, 0.3) 0%, transparent 70%); + border-radius: 50%; + transform: translate(-50%, -50%); + animation: pulse 4s ease-in-out infinite; +} + +/* Features Section */ +.features-section { + position: relative; + background: linear-gradient(135deg, var(--section-bg) 0%, #f8f9fa 100%); +} + +[data-theme="dark"] .features-section { + background: var(--section-bg); +} + +.section-header { + position: relative; +} + +.section-header::after { + content: ''; + position: absolute; + bottom: -15px; + left: 50%; + transform: translateX(-50%); + width: 60px; + height: 3px; + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); + border-radius: 2px; +} + +.feature-card { + transition: all 0.3s ease; + border: none; + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + border-radius: 15px; + overflow: hidden; +} + +.feature-card:hover { + /* Removed translateY(-10px) */ + box-shadow: 0 8px 30px rgba(0,0,0,0.15); +} + +.feature-card .card-body { + display: flex !important; + flex-direction: column !important; + align-items: center !important; + justify-content: flex-start !important; + text-align: center !important; + padding-left: 0 !important; + padding-right: 0 !important; +} + +.feature-icon-wrapper { + margin-left: 0 !important; + margin-right: 0 !important; +} + +.feature-icon { + font-size: 3rem; + transition: all 0.3s ease; + display: inline-block; +} + +.feature-card:hover .feature-icon { + transform: scale(1.1); +} + +.feature-icon-wrapper::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(52, 152, 219, 0.1); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: all 0.3s ease; +} + +.feature-card:hover .feature-icon-wrapper::after { + width: 80px; + height: 80px; +} + +.features-section .feature-icon { + color: #fff !important; +} + +/* Services Preview Section */ +.services-preview-section { + background: var(--light-bg); +} + +/* Expertise Section */ +.expertise-section { + background: var(--light-bg); +} + +.expertise-card { + transition: all 0.3s ease; + border: none; + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + border-radius: 15px; + overflow: hidden; + position: relative; +} + +.expertise-card:hover { + /* Removed translateY(-10px) */ + box-shadow: 0 8px 30px rgba(0,0,0,0.15); +} + +.expertise-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--secondary-color), var(--secondary-color) 50%, rgba(52, 152, 219, 0.3) 75%, transparent); + transform: scaleX(0); + transition: transform 0.3s ease; +} + +.expertise-card:hover::before { + transform: scaleX(1); +} + +[data-theme="dark"] .expertise-card::before { + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); +} + +.expertise-header { + text-align: center; +} + +.expertise-icon-wrapper { + position: relative; + display: inline-block; +} + +.expertise-icon { + font-size: 3rem; + transition: all 0.3s ease; +} + +.expertise-card:hover .expertise-icon { + transform: scale(1.1); +} + +.expertise-icon-wrapper::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(52, 152, 219, 0.1); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: all 0.3s ease; +} + +.expertise-card:hover .expertise-icon-wrapper::after { + width: 80px; + height: 80px; +} + +.expertise-features { + margin: 0; + padding: 0; +} + +.expertise-feature { + display: flex; + align-items: center; + padding: 0.75rem 0; + transition: all 0.2s ease; + border-radius: 8px; + padding-left: 0.5rem; + margin-left: -0.5rem; +} + +.expertise-feature:hover { + background: rgba(52, 152, 219, 0.05); + transform: translateX(5px); +} + +.expertise-feature i { + font-size: 1.1rem; + min-width: 20px; + transition: all 0.2s ease; +} + +.expertise-feature:hover i { + transform: scale(1.2); +} + +/* Responsive adjustments for expertise section */ +@media (max-width: 768px) { + .expertise-icon { + font-size: 2.5rem; + } + + .expertise-feature { + padding: 0.5rem 0; + } +} + +/* Animations */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeInRight { + from { + opacity: 0; + transform: translateX(30px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes pulse { + 0%, 100% { + transform: translate(-50%, -50%) scale(1); + opacity: 0.5; + } + 50% { + transform: translate(-50%, -50%) scale(1.1); + opacity: 0.8; + } +} + +/* Responsive adjustments for home page */ +@media (max-width: 768px) { + .hero-title { + font-size: 2.5rem; + } + + .hero-stats { + padding: 1rem; + } + + .stat-item h3 { + font-size: 1.5rem; + } + + .hero-main-icon { + font-size: 6rem; + } + + .hero-icon-glow { + width: 150px; + height: 150px; + } + + .feature-icon { + font-size: 2.5rem; + } + + .feature-icon-wrapper { + text-align: center; + display: block; + width: 100%; + } + + .service-preview-icon { + font-size: 2rem; + } + + /* Improve mobile hero layout */ + .hero-section { + padding: 60px 0; + } + + .hero-content { + text-align: center; + } + + .hero-text-content { + margin-bottom: 2rem; + } + + .hero-buttons { + justify-content: center; + flex-wrap: wrap; + gap: 1rem !important; + } + + .hero-buttons .btn { + width: 100%; + max-width: 250px; + } + + /* Adjust hero visual positioning on mobile */ + .hero-visual { + margin-top: 2rem; + } + + .hero-icon-wrapper { + display: inline-block; + } +} + +/* About Page Enhanced Styling */ + +/* About Hero Section */ +.about-hero-section { + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: white; + position: relative; + overflow: hidden; +} + +.about-hero-content h1 { + font-size: 3.5rem; + line-height: 1.2; + text-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +.about-stats { + background: rgba(255, 255, 255, 0.1); + border-radius: 15px; + padding: 1.5rem; + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.about-stats .stat-item h3 { + font-size: 2.5rem; + margin-bottom: 0.25rem; +} + +.about-stats .stat-item small { + color: #fff !important; +} + +.about-hero-visual { + position: relative; + animation: fadeInRight 1s ease-out 0.3s both; +} + +.about-icon-wrapper { + position: relative; + display: inline-block; +} + +.about-main-icon { + font-size: 8rem; + opacity: 0.9; + position: relative; + z-index: 2; + animation: heroFloat 6s ease-in-out infinite; +} + +.about-icon-glow { + position: absolute; + top: 50%; + left: 50%; + width: 200px; + height: 200px; + background: radial-gradient(circle, rgba(255, 255, 255, 0.3) 0%, transparent 70%); + border-radius: 50%; + transform: translate(-50%, -50%); + animation: pulse 4s ease-in-out infinite; +} + +/* Story Section */ +.story-section { + background: var(--light-bg); +} + +.section-badge { + display: inline-block; +} + +.section-badge .badge { + font-size: 0.9rem; + font-weight: 600; + border-radius: 25px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.story-features { + background: rgba(52, 152, 219, 0.05); + border-radius: 15px; + padding: 2rem; + border: 1px solid rgba(52, 152, 219, 0.1); +} + +.story-feature { + display: flex; + align-items: center; + padding: 0.5rem 0; + font-weight: 500; +} + +.story-feature i { + font-size: 1.2rem; + margin-right: 0.75rem; +} + +/* Mission Card */ +.mission-card { + background: linear-gradient(135deg, var(--card-bg) 0%, rgba(52, 152, 219, 0.05) 100%); + border-radius: 20px; + padding: 3rem; + text-align: center; + border: 1px solid rgba(52, 152, 219, 0.1); + box-shadow: 0 8px 30px rgba(0,0,0,0.1); + position: relative; + overflow: hidden; +} + +.mission-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); +} + +.mission-icon-wrapper { + position: relative; + display: inline-block; +} + +.mission-icon { + font-size: 4rem; + color: var(--secondary-color); + transition: all 0.3s ease; +} + +.mission-stats { + border-top: 1px solid rgba(0,0,0,0.1); + padding-top: 2rem; +} + +.mission-stat h4 { + font-size: 2rem; + margin-bottom: 0.25rem; +} + +/* Values Section */ +.values-section { + background: var(--section-bg); +} + +.value-card { + background: var(--card-bg); + border-radius: 20px; + padding: 3rem 2rem; + text-align: center; + border: 1px solid rgba(0,0,0,0.05); + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.value-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); + transform: scaleX(0); + transition: transform 0.3s ease; +} + +.value-card:hover::before { + transform: scaleX(1); +} + +.value-card:hover { + box-shadow: 0 8px 30px rgba(0,0,0,0.15); +} + +.value-icon-wrapper { + position: relative; + display: inline-block; +} + +.value-icon { + font-size: 3rem; + color: var(--secondary-color); + transition: all 0.3s ease; +} + +.value-card:hover .value-icon { + transform: scale(1.1); +} + +.value-icon-wrapper::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(52, 152, 219, 0.1); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: all 0.3s ease; +} + +.value-card:hover .value-icon-wrapper::after { + width: 80px; + height: 80px; +} + +/* Team Section */ +.team-section { + background: var(--light-bg); +} + +.team-card { + background: var(--card-bg); + border-radius: 20px; + padding: 3rem 2rem; + text-align: center; + border: 1px solid rgba(0,0,0,0.05); + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.team-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); + transform: scaleX(0); + transition: transform 0.3s ease; +} + +.team-card:hover::before { + transform: scaleX(1); +} + +.team-card:hover { + box-shadow: 0 8px 30px rgba(0,0,0,0.15); +} + +.avatar-wrapper { + width: 120px; + height: 120px; + background: linear-gradient(135deg, var(--secondary-color), var(--primary-color)); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto; + position: relative; + overflow: hidden; +} + +.avatar-wrapper::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, transparent 30%, rgba(255,255,255,0.2) 50%, transparent 70%); + transform: translateX(-100%); + transition: transform 0.6s ease; +} + +.team-card:hover .avatar-wrapper::before { + transform: translateX(100%); +} + +.avatar-icon { + font-size: 3rem; + color: white; + position: relative; + z-index: 2; +} + +.team-social { + display: flex; + justify-content: center; + gap: 1rem; + margin-top: 1.5rem; +} + +.social-link { + display: inline-flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + background: rgba(52, 152, 219, 0.1); + color: var(--secondary-color); + border-radius: 50%; + text-decoration: none; + transition: all 0.3s ease; +} + +.social-link:hover { + background: var(--secondary-color); + color: white; + transform: scale(1.1); +} + +/* About Me Section */ +.about-me-section { + background: var(--light-bg); +} + +.about-me-card { + background: var(--card-bg); + border-radius: 20px; + padding: 3rem; + border: 1px solid rgba(0,0,0,0.05); + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.about-me-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--secondary-color), var(--primary-color)); + transform: scaleX(0); + transition: transform 0.3s ease; +} + +.about-me-card:hover::before { + transform: scaleX(1); +} + +.about-me-card:hover { + box-shadow: 0 8px 30px rgba(0,0,0,0.15); +} + +.about-me-avatar { + position: relative; +} + +.about-me-avatar .avatar-wrapper { + width: 150px; + height: 150px; + background: linear-gradient(135deg, var(--secondary-color), var(--primary-color)); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto; + position: relative; + overflow: hidden; + box-shadow: 0 8px 25px rgba(52, 152, 219, 0.3); +} + +.about-me-avatar .avatar-wrapper::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, transparent 30%, rgba(255,255,255,0.2) 50%, transparent 70%); + transform: translateX(-100%); + transition: transform 0.6s ease; +} + +.about-me-card:hover .about-me-avatar .avatar-wrapper::before { + transform: translateX(100%); +} + +.about-me-avatar .avatar-icon { + font-size: 4rem; + color: white; + position: relative; + z-index: 2; +} + +.about-me-skills { + background: rgba(52, 152, 219, 0.05); + border-radius: 15px; + padding: 1.5rem; + border: 1px solid rgba(52, 152, 219, 0.1); +} + +.skill-item { + display: flex; + align-items: center; + padding: 0.5rem 0; + font-weight: 500; +} + +.skill-item i { + font-size: 1.1rem; + margin-right: 0.75rem; +} + +.about-me-contact { + border-top: 1px solid rgba(0,0,0,0.1); + padding-top: 1.5rem; +} + +.about-me-contact .social-link { + display: inline-flex; + align-items: center; + justify-content: center; + width: 45px; + height: 45px; + background: rgba(52, 152, 219, 0.1); + color: var(--secondary-color); + border-radius: 50%; + text-decoration: none; + transition: all 0.3s ease; + font-size: 1.2rem; +} + +.about-me-contact .social-link:hover { + background: var(--secondary-color); + color: white; + transform: scale(1.1); +} + +/* Why Choose Section */ +.why-choose-section { + background: var(--section-bg); +} + +.feature-item { + display: flex; + align-items: flex-start; + padding: 2rem; + background: var(--card-bg); + border-radius: 15px; + border: 1px solid rgba(0,0,0,0.05); + box-shadow: 0 4px 20px rgba(0,0,0,0.08); + transition: all 0.3s ease; +} + +.feature-item:hover { + box-shadow: 0 8px 30px rgba(0,0,0,0.15); +} + +.feature-icon-wrapper { + flex-shrink: 0; + width: 60px; + height: 60px; + background: linear-gradient(135deg, var(--secondary-color), var(--primary-color)); + border-radius: 15px; + display: flex; + align-items: center; + justify-content: center; + margin-right: 1.5rem; + position: relative; + overflow: hidden; +} + +.feature-icon-wrapper::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(45deg, transparent 30%, rgba(255,255,255,0.2) 50%, transparent 70%); + transform: translateX(-100%); + transition: transform 0.6s ease; +} + +.feature-item:hover .feature-icon-wrapper::before { + transform: translateX(100%); +} + +.feature-icon { + font-size: 1.5rem; + color: white; + position: relative; + z-index: 2; +} + +.feature-content { + flex-grow: 1; +} + +/* Counter Animation */ +.counter { + transition: all 0.3s ease; +} + +/* Responsive adjustments for about page */ +@media (max-width: 768px) { + .about-hero-content h1 { + font-size: 2.5rem; + } + + .about-stats { + padding: 1rem; + } + + .about-stats .stat-item h3 { + font-size: 1.8rem; + } + + .about-main-icon { + font-size: 6rem; + } + + .about-icon-glow { + width: 150px; + height: 150px; + } + + .mission-card { + padding: 2rem; + } + + .value-card, + .team-card, + .about-me-card { + padding: 2rem 1.5rem; + } + + .feature-item { + padding: 1.5rem; + } + + .feature-icon-wrapper { + width: 50px; + height: 50px; + margin-right: 1rem; + } + + .feature-icon { + font-size: 1.2rem; + } + + .about-me-avatar .avatar-wrapper { + width: 120px; + height: 120px; + } + + .about-me-avatar .avatar-icon { + font-size: 3rem; + } +} + +/* Contact Page Styles */ +.contact-hero-section { + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: white; + padding: 100px 0; + position: relative; + overflow: hidden; +} + +.services-hero-section { + background: linear-gradient(135deg, var(--secondary-color), var(--primary-color)); + color: white; + padding: 100px 0; + position: relative; + overflow: hidden; +} + +.contact-hero-content { + position: relative; + z-index: 2; +} + +.services-hero-content { + position: relative; + z-index: 2; +} + +.contact-hero-visual { + position: relative; + z-index: 2; +} + +.services-hero-visual { + position: relative; + z-index: 2; +} + +.contact-icon-wrapper { + position: relative; + display: inline-block; +} + +.services-icon-wrapper { + position: relative; + display: inline-block; +} + +.contact-main-icon { + font-size: 8rem; + color: rgba(255, 255, 255, 0.9); + animation: heroFloat 3s ease-in-out infinite; +} + +.services-main-icon { + font-size: 8rem; + color: rgba(255, 255, 255, 0.9); + animation: heroFloat 3s ease-in-out infinite; +} + +.contact-icon-glow { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 200px; + height: 200px; + background: radial-gradient(circle, rgba(52, 152, 219, 0.3) 0%, transparent 70%); + border-radius: 50%; + animation: pulse 2s ease-in-out infinite; +} + +.services-icon-glow { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 200px; + height: 200px; + background: radial-gradient(circle, rgba(52, 152, 219, 0.3) 0%, transparent 70%); + border-radius: 50%; + animation: pulse 2s ease-in-out infinite; +} + +.contact-stats .stat-item { + padding: 1rem; + border-radius: 10px; + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); +} + +.contact-form-card { + border: none; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + border-radius: 15px; +} + +.contact-form-header { + border-bottom: 2px solid var(--light-bg); + padding-bottom: 2rem; +} + +.contact-form-icon-wrapper { + width: 80px; + height: 80px; + background: linear-gradient(135deg, var(--secondary-color), #2980b9); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto; +} + +.contact-form-icon { + font-size: 2rem; + color: white; +} + +.contact-form .form-floating { + margin-bottom: 1rem; +} + +.contact-form .form-control, +.contact-form .form-select { + border: 2px solid #e9ecef; + border-radius: 10px; + transition: all 0.3s ease; +} + +.contact-form .form-control:focus, +.contact-form .form-select:focus { + border-color: var(--secondary-color); + box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25); +} + +.contact-form .form-floating label { + color: #6c757d; +} + +.contact-form .form-floating .form-control:focus ~ label, +.contact-form .form-floating .form-control:not(:placeholder-shown) ~ label, +.contact-form .form-floating .form-select:focus ~ label, +.contact-form .form-floating .form-select:not([value=""]) ~ label { + color: #181a1b; +} + +.contact-submit-btn { + background: linear-gradient(135deg, var(--secondary-color), #2980b9); + border: none; + border-radius: 10px; + transition: all 0.3s ease; +} + +.contact-submit-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(52, 152, 219, 0.4); +} + +.contact-info-card { + border: none; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + border-radius: 15px; +} + +.contact-info-header { + border-bottom: 2px solid var(--light-bg); + padding-bottom: 2rem; +} + +.contact-info-icon-wrapper { + width: 80px; + height: 80px; + background: linear-gradient(135deg, var(--secondary-color), #2980b9); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto; +} + +.contact-info-icon { + font-size: 2rem; + color: white; +} + +.contact-info-icon-small { + width: 40px; + height: 40px; + background: var(--light-bg); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.contact-info-icon-small i { + font-size: 1rem; +} + +.business-hours { + background: var(--light-bg); + padding: 1rem; + border-radius: 10px; +} + +.social-links .social-link { + width: 40px; + height: 40px; + background: var(--light-bg); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: var(--secondary-color); + text-decoration: none; + transition: all 0.3s ease; +} + +.social-links .social-link:hover { + background: var(--secondary-color); + color: white; + transform: translateY(-2px); +} + +.contact-alert { + border: none; + border-radius: 10px; + background: linear-gradient(135deg, #d1ecf1, #bee5eb); +} + +/* Testimonials Section */ +.testimonial-card { + border: none; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); + border-radius: 15px; + transition: all 0.3s ease; +} + +.testimonial-card:hover { + transform: translateY(-5px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); +} + +.testimonial-rating { + font-size: 1.2rem; +} + +.testimonial-author { + border-top: 1px solid var(--light-bg); + padding-top: 1rem; +} + +/* Map Section */ +.map-container { + border-radius: 15px; + overflow: hidden; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); +} + +.map-placeholder { + background: linear-gradient(135deg, var(--light-bg), #e9ecef); + height: 300px; + display: flex; + align-items: center; + justify-content: center; + position: relative; +} + +.map-content { + background: white; + padding: 2rem; + border-radius: 15px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); +} + +.map-icon { + font-size: 3rem; + color: var(--secondary-color); +} + +/* FAQ Section */ +.faq-card { + border: none; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); + border-radius: 15px; + transition: all 0.3s ease; +} + +.faq-card:hover { + transform: translateY(-3px); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); +} + +.faq-icon-wrapper { + width: 60px; + height: 60px; + background: var(--light-bg); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.faq-icon { + font-size: 1.5rem; +} + +/* Responsive adjustments for contact page */ +@media (max-width: 768px) { + .contact-hero-section { + text-align: center; + } + + .services-hero-section { + text-align: center; + } + + .contact-main-icon { + font-size: 5rem; + } + + .services-main-icon { + font-size: 5rem; + } + + .contact-icon-glow { + width: 150px; + height: 150px; + } + + .services-icon-glow { + width: 150px; + height: 150px; + } + + .contact-form-card, + .contact-info-card { + margin-bottom: 2rem; + } + + .contact-form-icon-wrapper, + .contact-info-icon-wrapper { + width: 60px; + height: 60px; + } + + .contact-form-icon, + .contact-info-icon { + font-size: 1.5rem; + } + + .map-placeholder { + height: 250px; + } + + .map-content { + padding: 1.5rem; + } + + .map-icon { + font-size: 2rem; + } +} + +/* Dark theme adjustments for contact page */ +[data-theme="dark"] .contact-form .form-control, +[data-theme="dark"] .contact-form .form-select { + background-color: var(--card-bg); + border-color: #444; + color: var(--text-color); +} + +[data-theme="dark"] .contact-form .form-control:focus, +[data-theme="dark"] .contact-form .form-select:focus { + background-color: var(--card-bg); +} + +[data-theme="dark"] .business-hours { + background-color: var(--section-bg); +} + +[data-theme="dark"] .social-links .social-link { + background-color: var(--section-bg); +} + +[data-theme="dark"] .contact-alert { + background: linear-gradient(135deg, #1a3c42, #2c5a63); + color: var(--text-color); +} + +[data-theme="dark"] .map-placeholder { + background: linear-gradient(135deg, var(--section-bg), var(--card-bg)); +} + +[data-theme="dark"] .map-content { + background-color: var(--card-bg); + color: var(--text-color); +} + +[data-theme="dark"] .faq-icon-wrapper { + background-color: var(--section-bg); +} + +/* Responsive adjustments for mobile devices */ +.contact-form .form-floating > label::after { + background-color: var(--card-bg); +} +[data-theme="dark"] .contact-form .form-floating > label::after { + background-color: var(--card-bg); +} + +[data-theme="dark"] .contact-form .form-floating label { + color: #f5f6fa; +} +[data-theme="dark"] .contact-form .form-floating .form-control:focus ~ label, +[data-theme="dark"] .contact-form .form-floating .form-control:not(:placeholder-shown) ~ label, +[data-theme="dark"] .contact-form .form-floating .form-select:focus ~ label, +[data-theme="dark"] .contact-form .form-floating .form-select:not([value=""]) ~ label { + color: #f5f6fa; +} + +.about-stats .stat-item .plus { + color: inherit; + font-size: inherit; + font-weight: inherit; + margin-left: 2px; +} + +@media (max-width: 768px) { + .footer { + text-align: center !important; + } + .footer .container, + .footer .row, + .footer .col, + .footer .col-12 { + justify-content: center !important; + align-items: center !important; + text-align: center !important; + display: flex !important; + flex-direction: column !important; + } +} + +@media (max-width: 768px) { + .feature-item { + flex-direction: column; + align-items: center; + text-align: center; + } + .feature-icon-wrapper { + margin-right: 0 !important; + margin-bottom: 1rem !important; + } + .feature-content { + width: 100%; + } +} + +@media (min-width: 769px) { + .feature-icon-wrapper { + margin-right: 2.5rem !important; + } +} + +@media (max-width: 991.98px) { + .btn-toggle-dark { + display: inline-flex !important; + align-items: center; + justify-content: center; + font-size: 1.5rem; + margin-left: 1rem; + background: none; + border: none; + color: #fff; + box-shadow: none; + } + .language-selector { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } +} + +/* Design Showcase Styles */ +.design-showcase { + background: linear-gradient(135deg, var(--section-bg) 0%, var(--light-bg) 100%); +} + +.design-card { + background: white; + border-radius: 15px; + overflow: hidden; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + transition: all 0.3s ease; + cursor: pointer; + border: 3px solid transparent; +} + +.design-card:hover { + transform: translateY(-5px); + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15); +} + +.design-card.active { + border-color: var(--bs-primary); + box-shadow: 0 20px 40px rgba(var(--bs-primary-rgb), 0.2); +} + +.design-preview { + height: 200px; + background: #f8f9fa; + position: relative; + overflow: hidden; +} + +.design-header { + height: 30px; + background: #e9ecef; + display: flex; + align-items: center; + padding: 0 10px; +} + +.design-nav { + display: flex; + gap: 6px; +} + +.nav-dot { + width: 12px; + height: 12px; + border-radius: 50%; + background: #dee2e6; +} + +.design-content { + padding: 20px; +} + +.design-hero { + margin-bottom: 20px; +} + +.design-title { + height: 20px; + background: #dee2e6; + border-radius: 4px; + margin-bottom: 10px; + width: 80%; +} + +.design-subtitle { + height: 16px; + background: #e9ecef; + border-radius: 4px; + width: 60%; +} + +.design-features { + display: flex; + flex-direction: column; + gap: 8px; +} + +.feature-line { + height: 12px; + background: #f8f9fa; + border-radius: 4px; + width: 100%; +} + +.design-info { + padding: 20px; +} + +.design-name { + font-size: 1.25rem; + font-weight: 600; + margin-bottom: 10px; + color: #212529; +} + +.design-description { + color: #6c757d; + font-size: 0.9rem; + margin-bottom: 15px; + line-height: 1.5; +} + +.design-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.tag { + background: #e9ecef; + color: #495057; + padding: 4px 8px; + border-radius: 12px; + font-size: 0.75rem; + font-weight: 500; +} + +/* Theme-specific colors for design preview elements */ +.design-card[data-theme="modern-minimal"] .nav-dot, +.design-card[data-theme="modern-minimal"] .design-title, +.design-card[data-theme="modern-minimal"] .design-subtitle { + background-color: #2c3e50; +} + +.design-card[data-theme="bold-vibrant"] .nav-dot, +.design-card[data-theme="bold-vibrant"] .design-title, +.design-card[data-theme="bold-vibrant"] .design-subtitle { + background-color: #ff6b6b; +} + +.design-card[data-theme="elegant-professional"] .nav-dot, +.design-card[data-theme="elegant-professional"] .design-title, +.design-card[data-theme="elegant-professional"] .design-subtitle { + background-color: #2c3e50; +} + +.design-card[data-theme="tech-startup"] .nav-dot, +.design-card[data-theme="tech-startup"] .design-title, +.design-card[data-theme="tech-startup"] .design-subtitle { + background-color: #3498db; +} + +.design-card[data-theme="creative-agency"] .nav-dot, +.design-card[data-theme="creative-agency"] .design-title, +.design-card[data-theme="creative-agency"] .design-subtitle { + background-color: #9b59b6; +} + +.design-card[data-theme="ecommerce"] .nav-dot, +.design-card[data-theme="ecommerce"] .design-title, +.design-card[data-theme="ecommerce"] .design-subtitle { + background-color: #e67e22; +} + +/* Theme Preview Container */ +.theme-preview-container { + background: white; + border-radius: 15px; + padding: 30px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + border: 2px dashed #dee2e6; + transition: all 0.3s ease; +} + +.theme-preview-container.active { + border-color: var(--bs-primary); + border-style: solid; +} + +.preview-placeholder { + color: #6c757d; +} + +/* Theme-specific styles */ +.theme-modern-minimal { + --primary-color: #6c757d; + --secondary-color: #f8f9fa; + --accent-color: #e9ecef; + --text-color: #212529; + --bg-color: #ffffff; +} + +.theme-bold-vibrant { + --primary-color: #ff6b6b; + --secondary-color: #4ecdc4; + --accent-color: #45b7d1; + --text-color: #2c3e50; + --bg-color: #ffffff; +} + +.theme-elegant-professional { + --primary-color: #2c3e50; + --secondary-color: #34495e; + --accent-color: #95a5a6; + --text-color: #2c3e50; + --bg-color: #ffffff; +} + +.theme-tech-startup { + --primary-color: #3498db; + --secondary-color: #2ecc71; + --accent-color: #f39c12; + --text-color: #2c3e50; + --bg-color: #ffffff; +} + +.theme-creative-agency { + --primary-color: #9b59b6; + --secondary-color: #e74c3c; + --accent-color: #f1c40f; + --text-color: #2c3e50; + --bg-color: #ffffff; +} + +.theme-ecommerce { + --primary-color: #e67e22; + --secondary-color: #27ae60; + --accent-color: #8e44ad; + --text-color: #2c3e50; + --bg-color: #ffffff; +} + +/* Apply theme styles when active */ +/* DISABLED: Body theme styles - only mini website changes now */ +body.theme-modern-minimal { + /* --bs-primary: var(--primary-color); + --bs-primary-rgb: 108, 117, 125; */ +} + +body.theme-bold-vibrant { + /* --bs-primary: var(--primary-color); + --bs-primary-rgb: 255, 107, 107; */ +} + +body.theme-elegant-professional { + /* --bs-primary: var(--primary-color); + --bs-primary-rgb: 44, 62, 80; */ +} + +body.theme-tech-startup { + /* --bs-primary: var(--primary-color); + --bs-primary-rgb: 52, 152, 219; */ +} + +body.theme-creative-agency { + /* --bs-primary: var(--primary-color); + --bs-primary-rgb: 155, 89, 182; */ +} + +body.theme-ecommerce { + /* --bs-primary: var(--primary-color); + --bs-primary-rgb: 230, 126, 34; */ +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .design-card { + margin-bottom: 20px; + } + + .design-preview { + height: 150px; + } + + .design-info { + padding: 15px; + } +} + +/* Mini Website Styles */ +.mini-website { + max-width: 95%; + width: 100%; + margin: 0 auto; + background: white; + border-radius: 15px; + overflow: hidden; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + line-height: 1.6; + color: #333; + transition: all 0.3s ease; +} + +/* Mini Header */ +.mini-header { + background: var(--bs-primary, #007bff); + color: white; + padding: 1rem 2rem; +} + +.mini-nav { + display: flex; + justify-content: space-between; + align-items: center; +} + +.mini-brand { + font-size: 1.25rem; + font-weight: 600; + display: flex; + align-items: center; +} + +.mini-menu { + display: flex; + list-style: none; + margin: 0; + padding: 0; + gap: 2rem; +} + +.mini-nav-link { + color: white; + text-decoration: none; + font-weight: 500; + transition: opacity 0.3s ease; + pointer-events: none; + opacity: 0.7; +} + +.mini-nav-link:hover { + opacity: 0.7; + color: white; + cursor: default; +} + +/* Mini Hero */ +.mini-hero { + background: linear-gradient(135deg, var(--bs-primary, #007bff) 0%, rgba(var(--bs-primary-rgb, 0, 123, 255), 0.8) 100%); + color: white; + padding: 4rem 2rem; + text-align: center; +} + +.mini-hero-title { + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 1rem; + line-height: 1.2; +} + +.mini-hero-subtitle { + font-size: 1.25rem; + margin-bottom: 2rem; + opacity: 0.9; +} + +.mini-hero-buttons { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; +} + +/* Mini Buttons */ +.mini-btn { + padding: 0.75rem 1.5rem; + border: none; + border-radius: 8px; + font-weight: 600; + text-decoration: none; + cursor: default; + transition: all 0.3s ease; + font-size: 0.9rem; +} + +.mini-btn-primary { + background: white; + color: var(--bs-primary, #007bff); + opacity: 0.8; +} + +.mini-btn-primary:hover { + background: #f8f9fa; + color: var(--bs-primary, #007bff); + opacity: 0.9; + transform: translateY(-2px); +} + +.mini-btn-secondary { + background: transparent; + color: white; + border: 2px solid white; + opacity: 0.8; +} + +.mini-btn-secondary:hover { + background: white; + color: var(--bs-primary, #007bff); + opacity: 0.9; + transform: translateY(-2px); +} + +/* Mini Features */ +.mini-features { + padding: 4rem 2rem; + background: #f8f9fa; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; +} + +.mini-feature { + text-align: center; + padding: 2rem; + background: white; + border-radius: 12px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08); + transition: transform 0.3s ease; +} + +.mini-feature:hover { + transform: translateY(-5px); +} + +.mini-feature-icon { + width: 60px; + height: 60px; + background: var(--bs-primary, #007bff); + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 1.5rem; + font-size: 1.5rem; +} + +.mini-feature-title { + font-size: 1.25rem; + font-weight: 600; + margin-bottom: 1rem; + color: #333; +} + +.mini-feature-text { + color: #666; + line-height: 1.6; +} + +/* Mini CTA */ +.mini-cta { + background: var(--bs-primary, #007bff); + color: white; + padding: 4rem 2rem; + text-align: center; +} + +.mini-cta-title { + font-size: 2rem; + font-weight: 700; + margin-bottom: 1rem; +} + +.mini-cta-text { + font-size: 1.1rem; + margin-bottom: 2rem; + opacity: 0.9; +} + +/* Mini Footer */ +.mini-footer { + background: #333; + color: white; + padding: 2rem; +} + +.mini-footer-content { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 1rem; +} + +.mini-footer-brand { + font-size: 1.1rem; + font-weight: 600; + display: flex; + align-items: center; +} + +.mini-footer-links { + display: flex; + gap: 1.5rem; +} + +.mini-footer-link { + color: #ccc; + text-decoration: none; + transition: color 0.3s ease; + pointer-events: none; + cursor: default; +} + +.mini-footer-link:hover { + color: #ccc; +} + +/* Theme-specific mini website styles */ +.theme-modern-minimal .mini-website { + /* --mini-primary: #6c757d; + --mini-secondary: #f8f9fa; + --mini-accent: #e9ecef; */ +} + +.theme-bold-vibrant .mini-website { + /* --mini-primary: #ff6b6b; + --mini-secondary: #4ecdc4; + --mini-accent: #45b7d1; */ +} + +.theme-elegant-professional .mini-website { + /* --mini-primary: #2c3e50; + --mini-secondary: #34495e; + --mini-accent: #95a5a6; */ +} + +.theme-tech-startup .mini-website { + /* --mini-primary: #3498db; + --mini-secondary: #2ecc71; + --mini-accent: #f39c12; */ +} + +.theme-creative-agency .mini-website { + /* --mini-primary: #9b59b6; + --mini-secondary: #e74c3c; + --mini-accent: #f1c40f; */ +} + +.theme-ecommerce .mini-website { + /* --mini-primary: #e67e22; + --mini-secondary: #27ae60; + --mini-accent: #8e44ad; */ +} + +/* Responsive adjustments for mini website */ +@media (max-width: 768px) { + .mini-website { + max-width: 98%; + margin: 0 0.5rem; + } + + .mini-hero-title { + font-size: 2rem; + } + + .mini-hero-subtitle { + font-size: 1.1rem; + } + + .mini-features { + grid-template-columns: 1fr; + padding: 2rem 1rem; + } + + .mini-nav { + flex-direction: column; + gap: 1rem; + } + + .mini-menu { + gap: 1rem; + } + + .mini-footer-content { + flex-direction: column; + text-align: center; + } +} + +/* Hide mini website initially */ +.mini-website { + display: none; +} + +.theme-preview-container.active .mini-website { + display: block; +} + +/* Apply theme styles to mini website only */ +.mini-website.theme-modern-minimal { + --bs-primary: #2c3e50; + --bs-primary-rgb: 44, 62, 80; +} + +.mini-website.theme-modern-minimal .mini-header { + background: #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-hero { + background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); +} + +.mini-website.theme-modern-minimal .mini-feature-icon { + background: #ecf0f1; + color: #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-cta { + background: #ecf0f1; + color: #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-btn-primary { + background: #2c3e50; + color: white; +} + +.mini-website.theme-modern-minimal .mini-btn-primary:hover { + background: #34495e; + color: white; +} + +.mini-website.theme-modern-minimal .mini-btn-secondary { + background: transparent; + color: #2c3e50; + border: 2px solid #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-btn-secondary:hover { + background: #2c3e50; + color: white; +} + +.mini-website.theme-bold-vibrant { + --bs-primary: #ff6b6b; + --bs-primary-rgb: 255, 107, 107; +} + +.mini-website.theme-elegant-professional { + --bs-primary: #2c3e50; + --bs-primary-rgb: 44, 62, 80; +} + +.mini-website.theme-tech-startup { + --bs-primary: #3498db; + --bs-primary-rgb: 52, 152, 219; +} + +.mini-website.theme-creative-agency { + --bs-primary: #6366f1; + --bs-primary-rgb: 99, 102, 241; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; +} + +.mini-website.theme-ecommerce { + --bs-primary: #f59e0b; + --bs-primary-rgb: 245, 158, 11; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; +} + +/* Design card active states with theme-specific borders */ +.design-card.active[data-theme="modern-minimal"] { + border-color: #2c3e50; + box-shadow: 0 0 0 2px rgba(44, 62, 80, 0.3); +} + +.design-card.active[data-theme="bold-vibrant"] { + border-color: #ff6b6b; + box-shadow: 0 0 0 2px rgba(255, 107, 107, 0.3); +} + +.design-card.active[data-theme="elegant-professional"] { + border-color: #2c3e50; + box-shadow: 0 0 0 2px rgba(44, 62, 80, 0.3); +} + +.design-card.active[data-theme="tech-startup"] { + border-color: #3498db; + box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.3); +} + +.design-card.active[data-theme="creative-agency"] { + border-color: #6366f1; + box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.3); +} + +.design-card.active[data-theme="ecommerce"] { + border-color: #f59e0b; + box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.3); +} + +/* Live preview container with theme-specific borders */ +.theme-preview-container.active[data-theme="modern-minimal"] { + border-color: #2c3e50; + box-shadow: 0 0 0 2px rgba(44, 62, 80, 0.3); +} + +.theme-preview-container.active[data-theme="bold-vibrant"] { + border-color: #ff6b6b; + box-shadow: 0 0 0 2px rgba(255, 107, 107, 0.3); +} + +.theme-preview-container.active[data-theme="elegant-professional"] { + border-color: #2c3e50; + box-shadow: 0 0 0 2px rgba(44, 62, 80, 0.3); +} + +.theme-preview-container.active[data-theme="tech-startup"] { + border-color: #3498db; + box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.3); +} + +.theme-preview-container.active[data-theme="creative-agency"] { + border-color: #6366f1; + box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.3); +} + +.theme-preview-container.active[data-theme="ecommerce"] { + border-color: #f59e0b; + box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.3); +} + +/* Modern Minimal - Distinctive Style */ +.mini-website.theme-modern-minimal { + --bs-primary: #2c3e50; + --bs-primary-rgb: 44, 62, 80; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + letter-spacing: -0.02em; +} + +.mini-website.theme-modern-minimal .mini-header { + background: #f8fafc; + border-bottom: 1px solid #e2e8f0; + padding: 1.5rem 2rem; +} + +.mini-website.theme-modern-minimal .mini-nav-link { + color: #475569; + font-weight: 500; + font-size: 0.875rem; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.mini-website.theme-modern-minimal .mini-nav-link:hover { + color: #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-brand { + font-weight: 700; + font-size: 1.125rem; + color: #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-hero { + background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); + color: #1f2937; + padding: 6rem 2rem; + text-align: left; + border-bottom: 1px solid #e2e8f0; +} + +.mini-website.theme-modern-minimal .mini-hero-title { + font-size: 3.5rem; + font-weight: 800; + line-height: 1.1; + margin-bottom: 1.5rem; + color: #111827; +} + +.mini-website.theme-modern-minimal .mini-hero-subtitle { + font-size: 1.25rem; + font-weight: 400; + color: #64748b; + margin-bottom: 3rem; + max-width: 600px; +} + +.mini-website.theme-modern-minimal .mini-hero-buttons { + justify-content: flex-start; + gap: 1.5rem; +} + +.mini-website.theme-modern-minimal .mini-btn { + padding: 0.875rem 2rem; + font-weight: 600; + font-size: 0.875rem; + text-transform: uppercase; + letter-spacing: 0.05em; + border-radius: 0; +} + +.mini-website.theme-modern-minimal .mini-btn-primary { + background: #2c3e50; + color: white; + border: 2px solid #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-btn-primary:hover { + background: #1e293b; + border-color: #1e293b; +} + +.mini-website.theme-modern-minimal .mini-btn-secondary { + background: transparent; + color: #2c3e50; + border: 2px solid #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-btn-secondary:hover { + background: #2c3e50; + color: white; +} + +.mini-website.theme-modern-minimal .mini-features { + background: white; + padding: 6rem 2rem; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 3rem; +} + +.mini-website.theme-modern-minimal .mini-feature { + background: #f8fafc; + border: 1px solid #e2e8f0; + border-radius: 0; + padding: 3rem 2rem; + text-align: left; + box-shadow: none; +} + +.mini-website.theme-modern-minimal .mini-feature:hover { + transform: none; + border-color: #2c3e50; + background: #f1f5f9; +} + +.mini-website.theme-modern-minimal .mini-feature-icon { + width: 48px; + height: 48px; + background: #2c3e50; + color: white; + border-radius: 0; + margin: 0 0 1.5rem 0; + font-size: 1.25rem; +} + +.mini-website.theme-modern-minimal .mini-feature-title { + font-size: 1.125rem; + font-weight: 700; + color: #111827; + margin-bottom: 0.75rem; +} + +.mini-website.theme-modern-minimal .mini-feature-text { + color: #64748b; + font-size: 0.875rem; + line-height: 1.6; +} + +.mini-website.theme-modern-minimal .mini-cta { + background: #2c3e50; + color: white; + padding: 6rem 2rem; + text-align: left; + border-bottom: 1px solid #1e293b; +} + +.mini-website.theme-modern-minimal .mini-cta-title { + font-size: 2.5rem; + font-weight: 800; + color: white; + margin-bottom: 1rem; +} + +.mini-website.theme-modern-minimal .mini-cta-text { + font-size: 1.125rem; + color: #cbd5e1; + margin-bottom: 2rem; + max-width: 500px; +} + +.mini-website.theme-modern-minimal .mini-cta .mini-btn-primary { + background: white; + color: #2c3e50; + border: 2px solid white; +} + +.mini-website.theme-modern-minimal .mini-cta .mini-btn-primary:hover { + background: #f8fafc; + color: #2c3e50; + border-color: #f8fafc; +} + +.mini-website.theme-modern-minimal .mini-cta .mini-btn-secondary { + background: transparent; + color: white; + border: 2px solid white; +} + +.mini-website.theme-modern-minimal .mini-cta .mini-btn-secondary:hover { + background: white; + color: #2c3e50; +} + +.mini-website.theme-modern-minimal .mini-footer { + background: #1e293b; + color: #f8fafc; + padding: 3rem 2rem; +} + +.mini-website.theme-modern-minimal .mini-footer-brand { + font-weight: 700; + color: white; +} + +.mini-website.theme-modern-minimal .mini-footer-link { + color: #94a3b8; + font-size: 0.875rem; +} + +.mini-website.theme-modern-minimal .mini-footer-link:hover { + color: white; +} + +/* Bold and Vibrant - Distinctive Style */ +.mini-website.theme-bold-vibrant { + --bs-primary: #ff6b6b; + --bs-primary-rgb: 255, 107, 107; + font-family: 'Poppins', -apple-system, BlinkMacSystemFont, sans-serif; + font-weight: 600; +} + +.mini-website.theme-bold-vibrant .mini-header { + background: linear-gradient(135deg, #ff6b6b 0%, #ff8e8e 100%); + border-bottom: none; + padding: 1.5rem 2rem; + box-shadow: 0 4px 20px rgba(255, 107, 107, 0.3); +} + +.mini-website.theme-bold-vibrant .mini-nav-link { + color: white; + font-weight: 700; + font-size: 0.9rem; + text-transform: uppercase; + letter-spacing: 0.1em; + position: relative; +} + +.mini-website.theme-bold-vibrant .mini-nav-link:hover { + color: #ffeaa7; +} + +.mini-website.theme-bold-vibrant .mini-nav-link::after { + content: ''; + position: absolute; + bottom: -5px; + left: 0; + width: 0; + height: 3px; + background: #ffeaa7; + transition: width 0.3s ease; +} + +.mini-website.theme-bold-vibrant .mini-nav-link:hover::after { + width: 100%; +} + +.mini-website.theme-bold-vibrant .mini-brand { + font-weight: 900; + font-size: 1.5rem; + color: white; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); +} + +.mini-website.theme-bold-vibrant .mini-hero { + background: linear-gradient(135deg, #ff6b6b 0%, #ff8e8e 50%, #ffa726 100%); + color: white; + padding: 8rem 2rem; + text-align: center; + position: relative; + overflow: hidden; +} + +.mini-website.theme-bold-vibrant .mini-hero::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: url('data:image/svg+xml,'); + animation: float 6s ease-in-out infinite; +} + +@keyframes float { + 0%, 100% { transform: translateY(0px); } + 50% { transform: translateY(-10px); } +} + +.mini-website.theme-bold-vibrant .mini-hero-title { + font-size: 4rem; + font-weight: 900; + line-height: 1.1; + margin-bottom: 1.5rem; + color: white; + text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); + position: relative; + z-index: 1; +} + +.mini-website.theme-bold-vibrant .mini-hero-subtitle { + font-size: 1.5rem; + font-weight: 600; + color: #ffeaa7; + margin-bottom: 3rem; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); + position: relative; + z-index: 1; +} + +.mini-website.theme-bold-vibrant .mini-hero-buttons { + justify-content: center; + gap: 2rem; + position: relative; + z-index: 1; +} + +.mini-website.theme-bold-vibrant .mini-btn { + padding: 1rem 2.5rem; + font-weight: 800; + font-size: 1rem; + text-transform: uppercase; + letter-spacing: 0.1em; + border-radius: 50px; + position: relative; + overflow: hidden; + transition: all 0.3s ease; +} + +.mini-website.theme-bold-vibrant .mini-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); + transition: left 0.5s ease; +} + +.mini-website.theme-bold-vibrant .mini-btn:hover::before { + left: 100%; +} + +.mini-website.theme-bold-vibrant .mini-btn-primary { + background: #ffeaa7; + color: #2d3436; + border: 3px solid #ffeaa7; + box-shadow: 0 8px 25px rgba(255, 234, 167, 0.4); +} + +.mini-website.theme-bold-vibrant .mini-btn-primary:hover { + background: #fdcb6e; + border-color: #fdcb6e; + transform: translateY(-3px); + box-shadow: 0 12px 35px rgba(255, 234, 167, 0.6); +} + +.mini-website.theme-bold-vibrant .mini-btn-secondary { + background: transparent; + color: white; + border: 3px solid white; + box-shadow: 0 8px 25px rgba(255, 255, 255, 0.3); +} + +.mini-website.theme-bold-vibrant .mini-btn-secondary:hover { + background: white; + color: #ff6b6b; + transform: translateY(-3px); + box-shadow: 0 12px 35px rgba(255, 255, 255, 0.5); +} + +.mini-website.theme-bold-vibrant .mini-features { + background: #f8f9fa; + padding: 6rem 2rem; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; +} + +.mini-website.theme-bold-vibrant .mini-feature { + background: white; + border: none; + border-radius: 20px; + padding: 3rem 2rem; + text-align: center; + box-shadow: 0 10px 30px rgba(255, 107, 107, 0.1); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.mini-website.theme-bold-vibrant .mini-feature::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 5px; + background: linear-gradient(90deg, #ff6b6b, #ffa726, #00cec9); +} + +.mini-website.theme-bold-vibrant .mini-feature:hover { + transform: translateY(-10px); + box-shadow: 0 20px 40px rgba(255, 107, 107, 0.2); +} + +.mini-website.theme-bold-vibrant .mini-feature-icon { + width: 80px; + height: 80px; + background: linear-gradient(135deg, #ff6b6b, #ffa726); + color: white; + border-radius: 50%; + margin: 0 auto 2rem; + font-size: 2rem; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 8px 25px rgba(255, 107, 107, 0.3); +} + +.mini-website.theme-bold-vibrant .mini-feature-title { + font-size: 1.5rem; + font-weight: 800; + color: #2d3436; + margin-bottom: 1rem; +} + +.mini-website.theme-bold-vibrant .mini-feature-text { + color: #636e72; + font-size: 1rem; + line-height: 1.7; +} + +.mini-website.theme-bold-vibrant .mini-cta { + background: linear-gradient(135deg, #00cec9 0%, #55a3ff 100%); + color: white; + padding: 6rem 2rem; + text-align: center; + position: relative; + overflow: hidden; +} + +.mini-website.theme-bold-vibrant .mini-cta::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); + animation: pulse 4s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); opacity: 0.5; } + 50% { transform: scale(1.1); opacity: 0.8; } +} + +.mini-website.theme-bold-vibrant .mini-cta-title { + font-size: 3rem; + font-weight: 900; + color: white; + margin-bottom: 1rem; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); + position: relative; + z-index: 1; +} + +.mini-website.theme-bold-vibrant .mini-cta-text { + font-size: 1.25rem; + color: #ffeaa7; + margin-bottom: 2rem; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); + position: relative; + z-index: 1; +} + +.mini-website.theme-bold-vibrant .mini-cta .mini-btn-primary { + background: #ffeaa7; + color: #2d3436; + border: 3px solid #ffeaa7; + box-shadow: 0 8px 25px rgba(255, 234, 167, 0.4); +} + +.mini-website.theme-bold-vibrant .mini-cta .mini-btn-primary:hover { + background: #fdcb6e; + border-color: #fdcb6e; + transform: translateY(-3px); + box-shadow: 0 12px 35px rgba(255, 234, 167, 0.6); +} + +.mini-website.theme-bold-vibrant .mini-footer { + background: #2d3436; + color: white; + padding: 3rem 2rem; + position: relative; +} + +.mini-website.theme-bold-vibrant .mini-footer::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, #ff6b6b, #ffa726, #00cec9); +} + +.mini-website.theme-bold-vibrant .mini-footer-brand { + font-weight: 900; + color: #ffeaa7; + font-size: 1.25rem; +} + +.mini-website.theme-bold-vibrant .mini-footer-link { + color: #b2bec3; + font-size: 0.9rem; + font-weight: 600; + transition: color 0.3s ease; +} + +.mini-website.theme-bold-vibrant .mini-footer-link:hover { + color: #ffeaa7; +} + +/* Tech Startup - Distinctive Style */ +.mini-website.theme-tech-startup { + --bs-primary: #3498db; + --bs-primary-rgb: 52, 152, 219; + font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif; + font-weight: 400; +} + +.mini-website.theme-tech-startup .mini-header { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(20px); + border-bottom: 1px solid rgba(52, 152, 219, 0.1); + padding: 1.25rem 2rem; + position: sticky; + top: 0; + z-index: 100; +} + +.mini-website.theme-tech-startup .mini-nav-link { + color: #2c3e50; + font-weight: 500; + font-size: 0.875rem; + position: relative; + transition: color 0.3s ease; +} + +.mini-website.theme-tech-startup .mini-nav-link:hover { + color: #3498db; +} + +.mini-website.theme-tech-startup .mini-nav-link::before { + content: ''; + position: absolute; + bottom: -2px; + left: 50%; + width: 0; + height: 2px; + background: #3498db; + transition: all 0.3s ease; + transform: translateX(-50%); +} + +.mini-website.theme-tech-startup .mini-nav-link:hover::before { + width: 100%; +} + +.mini-website.theme-tech-startup .mini-brand { + font-weight: 700; + font-size: 1.25rem; + color: #2c3e50; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.mini-website.theme-tech-startup .mini-brand::before { + content: ''; + font-size: 1.5rem; + font-weight: bold; + font-family: 'Courier New', monospace; +} + +.mini-website.theme-tech-startup .mini-hero { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 8rem 2rem; + text-align: center; + position: relative; + overflow: hidden; +} + +.mini-website.theme-tech-startup .mini-hero::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), + radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); + animation: techGlow 8s ease-in-out infinite; +} + +@keyframes techGlow { + 0%, 100% { opacity: 0.5; } + 50% { opacity: 0.8; } +} + +.mini-website.theme-tech-startup .mini-hero-title { + font-size: 3.5rem; + font-weight: 700; + line-height: 1.1; + margin-bottom: 1.5rem; + color: white; + position: relative; + z-index: 1; +} + +.mini-website.theme-tech-startup .mini-hero-subtitle { + font-size: 1.25rem; + font-weight: 400; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 3rem; + max-width: 600px; + margin-left: auto; + margin-right: auto; + position: relative; + z-index: 1; +} + +.mini-website.theme-tech-startup .mini-hero-buttons { + justify-content: center; + gap: 1.5rem; + position: relative; + z-index: 1; +} + +.mini-website.theme-tech-startup .mini-btn { + padding: 0.875rem 2rem; + font-weight: 600; + font-size: 0.875rem; + border-radius: 8px; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.mini-website.theme-tech-startup .mini-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); + transition: left 0.5s ease; +} + +.mini-website.theme-tech-startup .mini-btn:hover::before { + left: 100%; +} + +.mini-website.theme-tech-startup .mini-btn-primary { + background: #3498db; + color: white; + border: 2px solid #3498db; + box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3); +} + +.mini-website.theme-tech-startup .mini-btn-primary:hover { + background: #2980b9; + border-color: #2980b9; + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(52, 152, 219, 0.4); +} + +.mini-website.theme-tech-startup .mini-btn-secondary { + background: transparent; + color: white; + border: 2px solid rgba(255, 255, 255, 0.3); + backdrop-filter: blur(10px); +} + +.mini-website.theme-tech-startup .mini-btn-secondary:hover { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.5); + transform: translateY(-2px); +} + +.mini-website.theme-tech-startup .mini-features { + background: #f8fafc; + padding: 6rem 2rem; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 2rem; +} + +.mini-website.theme-tech-startup .mini-feature { + background: white; + border: 1px solid #e2e8f0; + border-radius: 12px; + padding: 2.5rem 2rem; + text-align: left; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); + transition: all 0.3s ease; + position: relative; +} + +.mini-website.theme-tech-startup .mini-feature::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, #3498db, #9b59b6); + border-radius: 12px 12px 0 0; +} + +.mini-website.theme-tech-startup .mini-feature:hover { + transform: translateY(-5px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); + border-color: #3498db; +} + +.mini-website.theme-tech-startup .mini-feature-icon { + width: 60px; + height: 60px; + background: linear-gradient(135deg, #3498db, #9b59b6); + color: white; + border-radius: 12px; + margin: 0 0 1.5rem 0; + font-size: 1.5rem; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3); +} + +.mini-website.theme-tech-startup .mini-feature-title { + font-size: 1.25rem; + font-weight: 600; + color: #2c3e50; + margin-bottom: 0.75rem; +} + +.mini-website.theme-tech-startup .mini-feature-text { + color: #64748b; + font-size: 0.875rem; + line-height: 1.6; +} + +.mini-website.theme-tech-startup .mini-cta { + background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); + color: white; + padding: 6rem 2rem; + text-align: center; + position: relative; + overflow: hidden; +} + +.mini-website.theme-tech-startup .mini-cta::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 30% 70%, rgba(52, 152, 219, 0.1) 0%, transparent 50%), + radial-gradient(circle at 70% 30%, rgba(155, 89, 182, 0.1) 0%, transparent 50%); +} + +.mini-website.theme-tech-startup .mini-cta-title { + font-size: 2.5rem; + font-weight: 700; + color: white; + margin-bottom: 1rem; + position: relative; + z-index: 1; +} + +.mini-website.theme-tech-startup .mini-cta-text { + font-size: 1.125rem; + color: rgba(255, 255, 255, 0.8); + margin-bottom: 2rem; + max-width: 500px; + margin-left: auto; + margin-right: auto; + position: relative; + z-index: 1; +} + +.mini-website.theme-tech-startup .mini-cta .mini-btn-primary { + background: #3498db; + color: white; + border: 2px solid #3498db; + box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3); +} + +.mini-website.theme-tech-startup .mini-cta .mini-btn-primary:hover { + background: #2980b9; + border-color: #2980b9; + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(52, 152, 219, 0.4); +} + +.mini-website.theme-tech-startup .mini-footer { + background: #1a202c; + color: #e2e8f0; + padding: 3rem 2rem; + position: relative; +} + +.mini-website.theme-tech-startup .mini-footer::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, #3498db, #9b59b6); +} + +.mini-website.theme-tech-startup .mini-footer-brand { + font-weight: 700; + color: #3498db; + font-size: 1.125rem; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.mini-website.theme-tech-startup .mini-footer-brand::before { + content: ''; + font-size: 1.25rem; +} + +.mini-website.theme-tech-startup .mini-footer-link { + color: #a0aec0; + font-size: 0.875rem; + transition: color 0.3s ease; +} + +.mini-website.theme-tech-startup .mini-footer-link:hover { + color: #3498db; +} + +.mini-website.theme-creative-agency { + --bs-primary: #6366f1; + --bs-primary-rgb: 99, 102, 241; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; +} + +.mini-website.theme-creative-agency .mini-header { + background: rgba(255, 255, 255, 0.98); + backdrop-filter: blur(10px); + border-bottom: 2px solid #f1f5f9; + padding: 1.5rem 2rem; + position: relative; +} + +.mini-website.theme-creative-agency .mini-header::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, #6366f1, #8b5cf6, #ec4899); + background-size: 200% 100%; + animation: subtleShift 8s ease-in-out infinite; +} + +@keyframes subtleShift { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } +} + +.mini-website.theme-creative-agency .mini-nav-link { + color: #64748b; + font-weight: 500; + font-size: 0.875rem; + transition: all 0.3s ease; + position: relative; +} + +.mini-website.theme-creative-agency .mini-nav-link::after { + content: ''; + position: absolute; + bottom: -8px; + left: 50%; + width: 0; + height: 2px; + background: #6366f1; + transition: all 0.3s ease; + transform: translateX(-50%); +} + +.mini-website.theme-creative-agency .mini-nav-link:hover::after { + width: 100%; +} + +.mini-website.theme-creative-agency .mini-nav-link:hover { + color: #6366f1; +} + +.mini-website.theme-creative-agency .mini-brand { + font-weight: 800; + font-size: 1.25rem; + background: linear-gradient(135deg, #6366f1, #8b5cf6); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.mini-website.theme-creative-agency .mini-hero { + background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #ec4899 100%); + color: white; + padding: 7rem 2rem; + text-align: center; + position: relative; + overflow: hidden; +} + +.mini-website.theme-creative-agency .mini-hero::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 20% 80%, rgba(255, 255, 255, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%); + animation: gentleFloat 15s ease-in-out infinite; +} + +@keyframes gentleFloat { + 0%, 100% { opacity: 0.3; transform: translateY(0px); } + 50% { opacity: 0.6; transform: translateY(-10px); } +} + +.mini-website.theme-creative-agency .mini-hero-title { + font-size: 3.5rem; + font-weight: 800; + line-height: 1.1; + margin-bottom: 1.5rem; + color: white; + position: relative; + z-index: 1; + letter-spacing: -0.02em; +} + +.mini-website.theme-creative-agency .mini-hero-subtitle { + font-size: 1.25rem; + font-weight: 400; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 3rem; + max-width: 600px; + margin-left: auto; + margin-right: auto; + position: relative; + z-index: 1; +} + +.mini-website.theme-creative-agency .mini-hero-buttons { + justify-content: center; + gap: 1.5rem; + position: relative; + z-index: 1; +} + +.mini-website.theme-creative-agency .mini-btn { + padding: 0.875rem 2rem; + font-weight: 600; + font-size: 0.875rem; + border-radius: 12px; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.mini-website.theme-creative-agency .mini-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); + transition: left 0.5s ease; +} + +.mini-website.theme-creative-agency .mini-btn:hover::before { + left: 100%; +} + +.mini-website.theme-creative-agency .mini-btn-primary { + background: white; + color: #6366f1; + border: 2px solid white; +} + +.mini-website.theme-creative-agency .mini-btn-primary:hover { + background: transparent; + color: white; + border-color: white; + transform: translateY(-2px); +} + +.mini-website.theme-creative-agency .mini-btn-secondary { + background: transparent; + color: white; + border: 2px solid rgba(255, 255, 255, 0.3); + backdrop-filter: blur(10px); +} + +.mini-website.theme-creative-agency .mini-btn-secondary:hover { + background: rgba(255, 255, 255, 0.1); + border-color: white; + transform: translateY(-2px); +} + +.mini-website.theme-creative-agency .mini-features { + background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); + padding: 7rem 2rem; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2.5rem; + position: relative; +} + +.mini-website.theme-creative-agency .mini-features::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, #6366f1, #8b5cf6, #ec4899); + background-size: 200% 100%; + animation: subtleShift 10s ease-in-out infinite; +} + +.mini-website.theme-creative-agency .mini-feature { + background: white; + border: 1px solid #e2e8f0; + border-radius: 16px; + padding: 3rem 2rem; + text-align: center; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); + transition: all 0.4s ease; + position: relative; + overflow: hidden; +} + +.mini-website.theme-creative-agency .mini-feature::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, #6366f1, #8b5cf6); +} + +.mini-website.theme-creative-agency .mini-feature:hover { + transform: translateY(-8px); + box-shadow: 0 20px 40px rgba(99, 102, 241, 0.15); + border-color: #6366f1; +} + +.mini-website.theme-creative-agency .mini-feature-icon { + width: 70px; + height: 70px; + background: linear-gradient(135deg, #6366f1, #8b5cf6); + color: white; + border-radius: 16px; + margin: 0 auto 2rem auto; + font-size: 1.75rem; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 8px 20px rgba(99, 102, 241, 0.2); + transition: all 0.4s ease; +} + +.mini-website.theme-creative-agency .mini-feature:hover .mini-feature-icon { + transform: scale(1.1) rotate(5deg); + box-shadow: 0 12px 30px rgba(99, 102, 241, 0.3); +} + +.mini-website.theme-creative-agency .mini-feature-title { + font-size: 1.375rem; + font-weight: 700; + color: #1e293b; + margin-bottom: 1rem; + background: linear-gradient(135deg, #6366f1, #8b5cf6); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.mini-website.theme-creative-agency .mini-feature-text { + color: #64748b; + font-size: 0.95rem; + line-height: 1.6; + font-weight: 400; +} + +.mini-website.theme-creative-agency .mini-cta { + background: linear-gradient(135deg, #1e293b 0%, #334155 100%); + color: white; + padding: 7rem 2rem; + text-align: center; + position: relative; + overflow: hidden; +} + +.mini-website.theme-creative-agency .mini-cta::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 30% 70%, rgba(99, 102, 241, 0.1) 0%, transparent 50%), + radial-gradient(circle at 70% 30%, rgba(139, 92, 246, 0.1) 0%, transparent 50%); + animation: gentlePulse 12s ease-in-out infinite; +} + +@keyframes gentlePulse { + 0%, 100% { opacity: 0.2; transform: scale(1); } + 50% { opacity: 0.4; transform: scale(1.02); } +} + +.mini-website.theme-creative-agency .mini-cta-title { + font-size: 3rem; + font-weight: 800; + color: white; + margin-bottom: 1.5rem; + position: relative; + z-index: 1; +} + +.mini-website.theme-creative-agency .mini-cta-text { + font-size: 1.25rem; + color: rgba(255, 255, 255, 0.9); + margin-bottom: 3rem; + max-width: 600px; + margin-left: auto; + margin-right: auto; + position: relative; + z-index: 1; +} + +.mini-website.theme-creative-agency .mini-cta .mini-btn-primary { + background: linear-gradient(135deg, #6366f1, #8b5cf6); + color: white; + border: none; + padding: 1rem 2.5rem; + font-size: 1rem; + border-radius: 12px; + box-shadow: 0 8px 25px rgba(99, 102, 241, 0.3); +} + +.mini-website.theme-creative-agency .mini-cta .mini-btn-primary:hover { + background: linear-gradient(135deg, #8b5cf6, #6366f1); + transform: translateY(-3px); + box-shadow: 0 15px 35px rgba(99, 102, 241, 0.4); +} + +.mini-website.theme-creative-agency .mini-footer { + background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); + color: #e2e8f0; + padding: 4rem 2rem; + position: relative; +} + +.mini-website.theme-creative-agency .mini-footer::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, #6366f1, #8b5cf6, #ec4899); + background-size: 200% 100%; + animation: subtleShift 12s ease-in-out infinite; +} + +.mini-website.theme-creative-agency .mini-footer-brand { + font-weight: 800; + background: linear-gradient(135deg, #6366f1, #8b5cf6); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + font-size: 1.25rem; +} + +.mini-website.theme-creative-agency .mini-footer-link { + color: #94a3b8; + font-size: 0.9rem; + font-weight: 500; + transition: all 0.3s ease; +} + +.mini-website.theme-creative-agency .mini-footer-link:hover { + color: #6366f1; + transform: translateX(3px); +} + +.mini-website.theme-ecommerce { + --bs-primary: #f59e0b; + --bs-primary-rgb: 245, 158, 11; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; +} + +.mini-website.theme-ecommerce .mini-header { + background: white; + border-bottom: 1px solid #e5e7eb; + padding: 1rem 2rem; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.mini-website.theme-ecommerce .mini-nav-link { + color: #374151; + font-weight: 500; + font-size: 0.875rem; + transition: color 0.3s ease; + position: relative; +} + +.mini-website.theme-ecommerce .mini-nav-link::before { + content: ''; + position: absolute; + bottom: -4px; + left: 0; + width: 0; + height: 2px; + background: #f59e0b; + transition: width 0.3s ease; +} + +.mini-website.theme-ecommerce .mini-nav-link:hover::before { + width: 100%; +} + +.mini-website.theme-ecommerce .mini-nav-link:hover { + color: #f59e0b; +} + +.mini-website.theme-ecommerce .mini-brand { + font-weight: 700; + font-size: 1.25rem; + color: #111827; +} + +.mini-website.theme-ecommerce .mini-brand::before { + content: ''; + font-size: 1.5rem; +} + +.mini-website.theme-ecommerce .mini-hero { + background: linear-gradient(135deg, #fef3c7 0%, #fde68a 50%, #fbbf24 100%); + color: #1f2937; + padding: 5rem 2rem; + text-align: center; + position: relative; +} + +.mini-website.theme-ecommerce .mini-hero::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 20% 80%, rgba(245, 158, 11, 0.1) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(251, 191, 36, 0.1) 0%, transparent 50%); +} + +.mini-website.theme-ecommerce .mini-hero-title { + font-size: 3rem; + font-weight: 800; + line-height: 1.1; + margin-bottom: 1rem; + color: #111827; + position: relative; + z-index: 1; +} + +.mini-website.theme-ecommerce .mini-hero-subtitle { + font-size: 1.125rem; + font-weight: 500; + color: #4b5563; + margin-bottom: 2rem; + max-width: 500px; + margin-left: auto; + margin-right: auto; + position: relative; + z-index: 1; +} + +.mini-website.theme-ecommerce .mini-hero-buttons { + justify-content: center; + gap: 1rem; + position: relative; + z-index: 1; +} + +.mini-website.theme-ecommerce .mini-btn { + padding: 0.75rem 1.5rem; + font-weight: 600; + font-size: 0.875rem; + border-radius: 6px; + transition: all 0.3s ease; + position: relative; +} + +.mini-website.theme-ecommerce .mini-btn-primary { + background: #f59e0b; + color: white; + border: 2px solid #f59e0b; + box-shadow: 0 4px 6px rgba(245, 158, 11, 0.2); +} + +.mini-website.theme-ecommerce .mini-btn-primary:hover { + background: #d97706; + border-color: #d97706; + transform: translateY(-1px); + box-shadow: 0 6px 12px rgba(245, 158, 11, 0.3); +} + +.mini-website.theme-ecommerce .mini-btn-secondary { + background: white; + color: #374151; + border: 2px solid #d1d5db; +} + +.mini-website.theme-ecommerce .mini-btn-secondary:hover { + background: #f9fafb; + border-color: #9ca3af; + transform: translateY(-1px); +} + +.mini-website.theme-ecommerce .mini-features { + background: white; + padding: 4rem 2rem; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; + border-bottom: 1px solid #e5e7eb; +} + +.mini-website.theme-ecommerce .mini-feature { + background: #f9fafb; + border: 1px solid #e5e7eb; + border-radius: 8px; + padding: 2rem 1.5rem; + text-align: center; + transition: all 0.3s ease; + position: relative; +} + +.mini-website.theme-ecommerce .mini-feature::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: #f59e0b; + border-radius: 8px 8px 0 0; +} + +.mini-website.theme-ecommerce .mini-feature:hover { + transform: translateY(-3px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); + border-color: #f59e0b; +} + +.mini-website.theme-ecommerce .mini-feature-icon { + width: 50px; + height: 50px; + background: #f59e0b; + color: white; + border-radius: 8px; + margin: 0 auto 1rem auto; + font-size: 1.25rem; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 2px 4px rgba(245, 158, 11, 0.2); +} + +.mini-website.theme-ecommerce .mini-feature-title { + font-size: 1.125rem; + font-weight: 600; + color: #111827; + margin-bottom: 0.5rem; +} + +.mini-website.theme-ecommerce .mini-feature-text { + color: #6b7280; + font-size: 0.875rem; + line-height: 1.5; +} + +.mini-website.theme-ecommerce .mini-cta { + background: linear-gradient(135deg, #1f2937 0%, #374151 100%); + color: white; + padding: 4rem 2rem; + text-align: center; + position: relative; +} + +.mini-website.theme-ecommerce .mini-cta::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 30% 70%, rgba(245, 158, 11, 0.1) 0%, transparent 50%); +} + +.mini-website.theme-ecommerce .mini-cta-title { + font-size: 2.25rem; + font-weight: 700; + color: white; + margin-bottom: 1rem; + position: relative; + z-index: 1; +} + +.mini-website.theme-ecommerce .mini-cta-text { + font-size: 1rem; + color: rgba(255, 255, 255, 0.8); + margin-bottom: 2rem; + max-width: 500px; + margin-left: auto; + margin-right: auto; + position: relative; + z-index: 1; +} + +.mini-website.theme-ecommerce .mini-cta .mini-btn-primary { + background: #f59e0b; + color: white; + border: 2px solid #f59e0b; + padding: 0.875rem 2rem; + font-size: 0.875rem; + border-radius: 6px; + box-shadow: 0 4px 6px rgba(245, 158, 11, 0.2); +} + +.mini-website.theme-ecommerce .mini-cta .mini-btn-primary:hover { + background: #d97706; + border-color: #d97706; + transform: translateY(-1px); + box-shadow: 0 6px 12px rgba(245, 158, 11, 0.3); +} + +.mini-website.theme-ecommerce .mini-footer { + background: #111827; + color: #d1d5db; + padding: 3rem 2rem; + border-top: 3px solid #f59e0b; +} + +.mini-website.theme-ecommerce .mini-footer-brand { + font-weight: 700; + color: #f59e0b; + font-size: 1.125rem; +} + +.mini-website.theme-ecommerce .mini-footer-brand::before { + content: ''; + font-size: 1.25rem; +} + +.mini-website.theme-ecommerce .mini-footer-link { + color: #9ca3af; + font-size: 0.875rem; + transition: color 0.3s ease; +} + +.mini-website.theme-ecommerce .mini-footer-link:hover { + color: #f59e0b; +} + +.design-card.active[data-theme="ecommerce"] { + border-color: #f59e0b; + box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.3); +} + +/* Footer Contact Links Styling */ +.footer a { + color: #fff; + text-decoration: none; + transition: all 0.3s ease; + position: relative; + display: inline-block; +} + +.footer a:hover { + color: var(--secondary-color); + transform: translateY(-2px); + text-shadow: 0 2px 4px rgba(52, 152, 219, 0.3); +} + +.footer a::before { + content: ''; + position: absolute; + bottom: -2px; + left: 0; + width: 0; + height: 2px; + background: linear-gradient(90deg, var(--secondary-color), #3498db); + transition: width 0.3s ease; + border-radius: 1px; +} + +.footer a:hover::before { + width: 100%; +} + +/* Contact link icons styling */ +.footer .fas { + transition: all 0.3s ease; + margin-right: 8px; +} + +.footer a:hover .fas { + transform: scale(1.1); + color: var(--secondary-color); +} + +/* Specific styling for different contact types */ +.footer a[href^="mailto:"] { + color: #fff; +} + +.footer a[href^="mailto:"]:hover { + color: #e74c3c; +} + +.footer a[href^="tel:"] { + color: #fff; +} + +.footer a[href^="tel:"]:hover { + color: #27ae60; +} + +.footer a[href*="maps.google.com"] { + color: #fff; +} + +.footer a[href*="maps.google.com"]:hover { + color: #f39c12; +} + +/* Contact link container styling */ +.footer .col-md-4:last-child p { + line-height: 1.8; +} + +.footer .col-md-4:last-child p a { + padding: 2px 0; + border-radius: 4px; + transition: all 0.3s ease; +} + +.footer .col-md-4:last-child p a:hover { + background: rgba(255, 255, 255, 0.1); + padding: 2px 8px; + border-radius: 4px; +} + +/* Dark theme adjustments */ +[data-theme="dark"] .footer a { + color: #bdc3c7; +} + +[data-theme="dark"] .footer a:hover { + color: var(--secondary-color); + background: rgba(52, 152, 219, 0.1); +} + +/* Mobile responsiveness */ +@media (max-width: 768px) { + .footer a:hover { + transform: none; + } + + .footer .col-md-4:last-child p a:hover { + padding: 2px 0; + background: none; + } +} + +/* Contact Page Links Styling */ +.contact-info-card a { + color: var(--text-color); + text-decoration: none; + transition: all 0.3s ease; + position: relative; + display: inline-block; + padding: 4px 0; + border-radius: 4px; +} + +.contact-info-card a:hover { + color: var(--secondary-color); + transform: translateY(-1px); + background: rgba(52, 152, 219, 0.1); + padding: 4px 8px; + border-radius: 4px; +} + +.contact-info-card a::before { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 0; + height: 2px; + background: linear-gradient(90deg, var(--secondary-color), #3498db); + transition: width 0.3s ease; + border-radius: 1px; +} + +.contact-info-card a:hover::before { + width: 100%; +} + +/* Contact page specific link colors */ +.contact-info-card a[href^="mailto:"]:hover { + color: #e74c3c; + background: rgba(231, 76, 60, 0.1); +} + +.contact-info-card a[href^="tel:"]:hover { + color: #27ae60; + background: rgba(39, 174, 96, 0.1); +} + +.contact-info-card a[href*="maps.google.com"]:hover { + color: #f39c12; + background: rgba(243, 156, 18, 0.1); +} + +/* Contact page icons styling */ +.contact-info-card .fas { + transition: all 0.3s ease; +} + +.contact-info-card a:hover .fas { + transform: scale(1.1); +} + +/* Dark theme adjustments for contact page */ +[data-theme="dark"] .contact-info-card a { + color: var(--text-color); +} + +[data-theme="dark"] .contact-info-card a:hover { + color: var(--secondary-color); + background: rgba(52, 152, 219, 0.15); +} diff --git a/static/images/favicon.ico b/static/images/favicon.ico new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/static/images/favicon.ico @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/images/og-image.jpg b/static/images/og-image.jpg new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/static/images/og-image.jpg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/js/main.js b/static/js/main.js new file mode 100644 index 0000000..6f15c16 --- /dev/null +++ b/static/js/main.js @@ -0,0 +1,355 @@ +// Theme toggle logic +function setTheme(theme) { + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + var icon = document.getElementById('theme-icon'); + var iconDesktop = document.getElementById('theme-icon-desktop'); + if (icon) icon.className = theme === 'dark' ? 'fas fa-sun' : 'fas fa-moon'; + if (iconDesktop) iconDesktop.className = theme === 'dark' ? 'fas fa-sun' : 'fas fa-moon'; +} +function toggleTheme() { + const current = document.documentElement.getAttribute('data-theme') || 'light'; + setTheme(current === 'light' ? 'dark' : 'light'); +} +var themeToggle = document.getElementById('theme-toggle'); +if (themeToggle) themeToggle.addEventListener('click', toggleTheme); +var themeToggleDesktop = document.getElementById('theme-toggle-desktop'); +if (themeToggleDesktop) themeToggleDesktop.addEventListener('click', toggleTheme); +// On load: set theme from localStorage or system +(function() { + let theme = localStorage.getItem('theme'); + if (!theme) { + theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + } + setTheme(theme); +})(); +// Page fade-in effect +window.addEventListener('DOMContentLoaded', function() { + document.body.classList.add('page-loaded'); + // Staggered fade-in for .fade-in-up elements + var fadeEls = document.querySelectorAll('.fade-in-up'); + fadeEls.forEach(function(el, i) { + setTimeout(function() { + el.classList.add('visible'); + }, 200 + i * 180); + }); + + // Counter animation for about page + const counters = document.querySelectorAll('.counter'); + const animateCounters = () => { + counters.forEach(counter => { + const target = parseInt(counter.getAttribute('data-target')); + const count = parseInt(counter.innerText); + const increment = target / 100; + + if (count < target) { + counter.innerText = Math.ceil(count + increment) + '+'; + setTimeout(animateCounters, 20); + } else { + counter.innerText = target; + } + }); + }; + + // Intersection Observer for counter animation + const observerOptions = { + threshold: 0.5, + rootMargin: '0px 0px -100px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + animateCounters(); + observer.unobserve(entry.target); + } + }); + }, observerOptions); + + const aboutStats = document.querySelector('.about-stats'); + if (aboutStats) { + observer.observe(aboutStats); + } +}); +// MapTiler + Leaflet integration for contact page map +document.addEventListener('DOMContentLoaded', function() { + var mapDiv = document.getElementById('map'); + if (mapDiv) { + var map = L.map('map', { + center: [50.77989716345206, 4.048368809494087], // Blijkheerstraat 92, 1755 Pajottegem + zoom: 13, + zoomControl: true, + attributionControl: false + }); + var maptilerKey = 'fyG4fxsIMwJnhJ9hQ1wj'; + var light = L.tileLayer('https://api.maptiler.com/maps/streets-v2-pastel/{z}/{x}/{y}.png?key=' + maptilerKey, { + attribution: '© OpenStreetMap contributors © MapTiler', + tileSize: 512, + zoomOffset: -1 + }); + var dark = L.tileLayer('https://api.maptiler.com/maps/streets-v2-dark/{z}/{x}/{y}.png?key=' + maptilerKey, { + attribution: '© OpenStreetMap contributors © MapTiler', + tileSize: 512, + zoomOffset: -1 + }); + // Initial theme + var isDark = document.documentElement.getAttribute('data-theme') === 'dark'; + var currentLayer = isDark ? dark : light; + currentLayer.addTo(map); + // Marker + L.marker([50.77989716345206, 4.048368809494087]).addTo(map) + .bindPopup('Kobelly Web Solutions
Blijkheerstraat 92, 1755 Pajottegem') + .openPopup(); + // Listen for theme changes + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') { + var newTheme = document.documentElement.getAttribute('data-theme'); + if (newTheme === 'dark') { + map.removeLayer(light); + dark.addTo(map); + } else { + map.removeLayer(dark); + light.addTo(map); + } + } + }); + }); + observer.observe(document.documentElement, { attributes: true }); + } +}); +// Dynamic Stats Calculation +document.addEventListener('DOMContentLoaded', function() { + // Calculate stats since January 2016 + var startDate = new Date('2014-01-01'); + var now = new Date(); + + // Calculate years of experience + var years = now.getFullYear() - startDate.getFullYear(); + // If before Jan 1 this year, subtract 1 + if ( + now.getMonth() < startDate.getMonth() || + (now.getMonth() === startDate.getMonth() && now.getDate() < startDate.getDate()) + ) { + years--; + } + + // Calculate hours coded (assuming ~2000 hours per year) + var hoursCoded = years * 2000; + + // Update all stats sections across the website + var statItems = document.querySelectorAll('.stat-item h3'); + statItems.forEach(function(statEl) { + var statText = statEl.textContent; + + // Update years experience + if (statText.includes('Years Experience') || statText.includes('8+') || statText.includes('5+') || statText.includes('10+')) { + statEl.textContent = years + '+'; + } + + // Update hours coded + if (statText.includes('Hours Coded') || statText.includes('15,000+') || statText.includes('1000+')) { + statEl.textContent = hoursCoded.toLocaleString() + '+'; + } + }); + + // Also update any elements with specific IDs (for backward compatibility) + var yearsEl = document.getElementById('years-experience'); + var hoursEl = document.getElementById('hours-coded'); + if (yearsEl) yearsEl.textContent = years + '+'; + if (hoursEl) hoursEl.textContent = hoursCoded.toLocaleString() + '+'; +}); +// Interactive Design Showcase +document.addEventListener('DOMContentLoaded', function() { + const designCards = document.querySelectorAll('.design-card'); + const resetButton = document.getElementById('reset-theme'); + const previewContainer = document.getElementById('theme-preview'); + const previewContent = document.querySelector('.theme-preview-content'); + + // Theme configurations + const themes = { + 'modern-minimal': { + name: 'Modern Minimal', + description: 'Clean, spacious design with subtle animations and modern typography.', + colors: { + primary: '#6c757d', + secondary: '#f8f9fa', + accent: '#e9ecef' + }, + features: ['Clean Typography', 'Subtle Animations', 'Minimal Layout'] + }, + 'bold-vibrant': { + name: 'Bold & Vibrant', + description: 'Eye-catching design with bold colors and dynamic elements.', + colors: { + primary: '#ff6b6b', + secondary: '#4ecdc4', + accent: '#45b7d1' + }, + features: ['Bold Colors', 'Dynamic Elements', 'High Contrast'] + }, + 'elegant-professional': { + name: 'Elegant Professional', + description: 'Sophisticated design with premium styling and professional appeal.', + colors: { + primary: '#2c3e50', + secondary: '#34495e', + accent: '#95a5a6' + }, + features: ['Premium Styling', 'Professional Appeal', 'Sophisticated Layout'] + }, + 'tech-startup': { + name: 'Tech Startup', + description: 'Modern tech-focused design with innovative layouts and animations.', + colors: { + primary: '#3498db', + secondary: '#2ecc71', + accent: '#f39c12' + }, + features: ['Innovative Layout', 'Tech-focused', 'Modern Animations'] + }, + 'creative-agency': { + name: 'Creative Agency', + description: 'Artistic design with creative layouts and expressive visual elements.', + colors: { + primary: '#9b59b6', + secondary: '#e74c3c', + accent: '#f1c40f' + }, + features: ['Creative Layout', 'Artistic Elements', 'Expressive Design'] + }, + 'ecommerce': { + name: 'E-commerce', + description: 'Optimized design for online stores with product-focused layouts.', + colors: { + primary: '#e67e22', + secondary: '#27ae60', + accent: '#8e44ad' + }, + features: ['Product-focused', 'Shopping Optimized', 'Conversion-driven'] + } + }; + + // Apply theme to the mini website only + function applyTheme(themeName) { + const theme = themes[themeName]; + if (!theme) return; + + const miniWebsite = document.getElementById('mini-website'); + const previewContainer = document.querySelector('.theme-preview-container'); + if (!miniWebsite) return; + + // Remove all existing theme classes from mini website + miniWebsite.classList.remove('theme-modern-minimal', 'theme-bold-vibrant', 'theme-elegant-professional', 'theme-tech-startup', 'theme-creative-agency', 'theme-ecommerce'); + + // Add new theme class to mini website + miniWebsite.classList.add(`theme-${themeName}`); + + // Update CSS custom properties for mini website only + miniWebsite.style.setProperty('--bs-primary', theme.colors.primary); + miniWebsite.style.setProperty('--bs-primary-rgb', hexToRgb(theme.colors.primary)); + + // Update preview container data-theme attribute for border styling + if (previewContainer) { + previewContainer.setAttribute('data-theme', themeName); + } + + // Update active card + designCards.forEach(card => card.classList.remove('active')); + const activeCard = document.querySelector(`[data-theme="${themeName}"]`); + if (activeCard) activeCard.classList.add('active'); + + // Activate preview container + previewContainer.classList.add('active'); + + // Scroll to preview container with smooth animation + if (previewContainer) { + const previewTop = previewContainer.offsetTop; + window.scrollTo({ + top: previewTop - 100, + behavior: 'smooth' + }); + } + } + + // Reset to default theme + function resetTheme() { + const miniWebsite = document.getElementById('mini-website'); + const previewContainer = document.querySelector('.theme-preview-container'); + if (miniWebsite) { + miniWebsite.classList.remove('theme-modern-minimal', 'theme-bold-vibrant', 'theme-elegant-professional', 'theme-tech-startup', 'theme-creative-agency', 'theme-ecommerce'); + miniWebsite.style.removeProperty('--bs-primary'); + miniWebsite.style.removeProperty('--bs-primary-rgb'); + } + + // Remove data-theme attribute from preview container + if (previewContainer) { + previewContainer.removeAttribute('data-theme'); + } + + designCards.forEach(card => card.classList.remove('active')); + previewContainer.classList.remove('active'); + } + + // Helper function to convert hex to RGB + function hexToRgb(hex) { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}` : '0, 0, 0'; + } + + // Event listeners + designCards.forEach(card => { + card.addEventListener('click', function() { + const themeName = this.getAttribute('data-theme'); + applyTheme(themeName); + }); + }); + + if (resetButton) { + resetButton.addEventListener('click', resetTheme); + } + + // Add color swatch styles + const style = document.createElement('style'); + style.textContent = ` + .color-swatch { + width: 30px; + height: 30px; + border-radius: 50%; + border: 2px solid #fff; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + } + .preview-mockup { + width: 200px; + height: 150px; + border-radius: 10px; + overflow: hidden; + box-shadow: 0 10px 30px rgba(0,0,0,0.2); + margin: 0 auto; + } + .mockup-header { + height: 30px; + } + .mockup-content { + padding: 20px; + height: 120px; + } + .mockup-title { + height: 20px; + border-radius: 4px; + margin-bottom: 15px; + width: 80%; + } + .mockup-text { + height: 12px; + background: rgba(255,255,255,0.3); + border-radius: 4px; + margin-bottom: 8px; + width: 100%; + } + .mockup-text:last-child { + width: 60%; + } + `; + document.head.appendChild(style); +}); diff --git a/templates/about.html b/templates/about.html new file mode 100644 index 0000000..5c82c77 --- /dev/null +++ b/templates/about.html @@ -0,0 +1,294 @@ +{% extends "base.html" %} + +{% block title %}{{ t('About Kobe Amerijckx | Web Designer Brussels') }}{% endblock %} + +{% block description %}{{ t('Meet Kobe Amerijckx, professional web designer in Brussels. 10+ years experience creating stunning websites for small businesses. Free consultation available.') }}{% endblock %} + +{% block keywords %}{{ t('website design, web development, small business, Belgium, Brussels, professional websites, affordable web design') }}{% endblock %} + +{% block og_title %}{{ t('About Kobe Amerijckx | Web Designer Brussels') }}{% endblock %} + +{% block og_description %}{{ t('Meet Kobe Amerijckx, professional web designer in Brussels. 10+ years experience creating stunning websites for small businesses. Free consultation available.') }}{% endblock %} + +{% block twitter_title %}{{ t('About Kobe Amerijckx | Web Designer Brussels') }}{% endblock %} + +{% block twitter_description %}{{ t('Meet Kobe Amerijckx, professional web designer in Brussels. 10+ years experience creating stunning websites for small businesses. Free consultation available.') }}{% endblock %} + +{% block content %} + +{{ hero.hero_section( + title="About Kobelly", + subtitle="Hi, I'm Kobe Amerijckx, the founder and developer behind Kobelly Web Solutions. I'm passionate about helping small businesses succeed online with professional, affordable web solutions.", + icon_class="fas fa-user-tie", + stats=[ + {"value": "8+", "label": "Years Experience"}, + {"value": "15,000+", "label": "Hours Coded"}, + {"value": "100%", "label": "Committed"} + ], + t=t +) }} + + +
+
+
+
+
+
+ {{ t('My Story') }} +
+

{{ t('Building Digital Success Stories') }}

+

{{ t('Founded with a mission to democratize professional web development, Kobelly was born from my belief that every business deserves a stunning online presence.') }}

+

{{ t("I understand the challenges that small businesses face in today's digital landscape. High costs, complex processes, and lack of ongoing support often prevent entrepreneurs from getting the website they need to grow their business.") }}

+

{{ t("That's why I've created a service that combines professional quality with affordable pricing, transparent communication, and ongoing support. I don't just build websites – I build partnerships that help your business thrive.") }}

+ +
+
+
+
+ + {{ t('Professional Quality') }} +
+
+
+
+ + {{ t('Affordable Pricing') }} +
+
+
+
+ + {{ t('Transparent Communication') }} +
+
+
+
+ + {{ t('Ongoing Support') }} +
+
+
+
+
+
+
+
+
+ +
+

{{ t('My Mission') }}

+

{{ t('To empower small businesses with professional, affordable web solutions that drive growth and success in the digital world.') }}

+
+
+
+
+

100%

+ {{ t('Client Satisfaction') }} +
+
+
+
+

48h

+ {{ t('Response Time') }} +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+ {{ t('My Values') }} +
+

{{ t('The Principles That Guide Me') }}

+

{{ t('These core values shape everything I do and every decision I make.') }}

+
+
+ +
+
+
+
+ +
+

{{ t('Passion') }}

+

{{ t("I'm passionate about web design and helping businesses succeed. Every project is approached with enthusiasm and dedication.") }}

+
+
+
+
+
+ +
+

{{ t('Integrity') }}

+

{{ t('I believe in honest, transparent communication and always deliver what I promise. Your success is my success.') }}

+
+
+
+
+
+ +
+

{{ t('Innovation') }}

+

{{ t('I stay current with the latest web technologies and design trends to ensure your website stands out from the competition.') }}

+
+
+
+
+
+ + +
+
+
+
+
+ {{ t('About Me') }} +
+

{{ t("Meet Kobe Amerijckx") }}

+

{{ t("I'm the sole developer behind Kobelly, dedicated to creating exceptional websites for small businesses.") }}

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

{{ t('Your Dedicated Web Developer') }}

+

{{ t('With over 10 years of experience in web development, I specialize in creating fast, responsive, and user-friendly websites that help small businesses grow online.') }}

+

{{ t('I handle every aspect of your project personally - from initial consultation to design, development, and ongoing support. This ensures consistent quality and direct communication throughout the entire process.') }}

+ +
+
{{ t('My Expertise:') }}
+
+
+
+ + {{ t('Responsive Web Design') }} +
+
+
+
+ + {{ t('E-commerce Development') }} +
+
+
+
+ + {{ t('SEO Optimization') }} +
+
+
+
+ + {{ t('Website Maintenance') }} +
+
+
+
+ +
+
{{ t("Let's Connect:") }}
+
+ + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+ {{ t('Why Choose Me') }} +
+

{{ t('What Makes Me Different') }}

+

{{ t("I'm not just another web developer. Here's what sets me apart.") }}

+
+
+ +
+
+
+
+ +
+
+
{{ t('Affordable Pricing') }}
+

{{ t('I offer competitive pricing without compromising on quality. My packages are designed to fit small business budgets.') }}

+
+
+
+
+
+
+ +
+
+
{{ t('Fast Turnaround') }}
+

{{ t('I understand that time is money. I deliver projects on time and keep you updated throughout the process.') }}

+
+
+
+
+
+
+ +
+
+
{{ t('Direct Communication') }}
+

{{ t('You work directly with me - no account managers or middlemen. I believe in transparent communication.') }}

+
+
+
+
+
+
+ +
+
+
{{ t('Personal Support') }}
+

{{ t("Our relationship doesn't end when your website launches. I provide ongoing support and maintenance.") }}

+
+
+
+
+
+
+ + +{{ components.cta_section( + title="Ready to Work Together?", + description="Let's discuss your project and see how I can help your business grow online.", + button_text="Get Started Today", + button_url="contact", + t=t +) }} +{% endblock %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..da439e4 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,192 @@ + + + + + + + + {% block title %}{{ t('Kobelly Web Solutions') }}{% endblock %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {# Import components macros #} + {% import 'components/cta_section.html' as components %} + {% import 'components/testimonials_section.html' as testimonials %} + {% import 'components/hero_section.html' as hero %} + {% import 'components/stats_section.html' as stats %} + + + + + + +
+ {% block content %}{% endblock %} +
+ + +
+
+
+
+
{{ t('Kobelly Web Solutions') }}
+

{{ t('Creating professional websites for small businesses and entrepreneurs.') }}

+
+
+
{{ t('Services') }}
+
    +
  • {{ t('Website Design') }}
  • +
  • {{ t('E-commerce Solutions') }}
  • +
  • {{ t('Maintenance & Support') }}
  • +
+
+ +
+
+
+

© {{ current_year }} {{ t('Kobelly Web Solutions. All rights reserved.') }}

+
+
+
+ + + + + + \ No newline at end of file diff --git a/templates/components/cta_section.html b/templates/components/cta_section.html new file mode 100644 index 0000000..60801c0 --- /dev/null +++ b/templates/components/cta_section.html @@ -0,0 +1,16 @@ +{% macro cta_section(title, description, button_text, button_url, t) %} +
+
+
+
+
+
+
+
+
+

{{ t(title) }}

+

{{ t(description) }}

+ {{ t(button_text) }} +
+
+{% endmacro %} \ No newline at end of file diff --git a/templates/components/hero_section.html b/templates/components/hero_section.html new file mode 100644 index 0000000..897ae1e --- /dev/null +++ b/templates/components/hero_section.html @@ -0,0 +1,27 @@ +{% import 'components/stats_section.html' as stats_component %} + +{% macro hero_section(title, subtitle, icon_class="fas fa-star", stats=None, t=t) %} +
+
+
+
+
+

{{ t(title) }}

+

{{ t(subtitle) }}

+ {% if stats %} + {{ stats_component.stats_section(stats, t) }} + {% endif %} +
+
+
+
+
+ +
+
+
+
+
+
+
+{% endmacro %} \ No newline at end of file diff --git a/templates/components/stats_section.html b/templates/components/stats_section.html new file mode 100644 index 0000000..ae6b4d4 --- /dev/null +++ b/templates/components/stats_section.html @@ -0,0 +1,14 @@ +{% macro stats_section(stats, t=t) %} +
+
+ {% for stat in stats %} +
+
+

{{ stat.value }}

+ {{ t(stat.label) }} +
+
+ {% endfor %} +
+
+{% endmacro %} \ No newline at end of file diff --git a/templates/components/testimonials_section.html b/templates/components/testimonials_section.html new file mode 100644 index 0000000..635362e --- /dev/null +++ b/templates/components/testimonials_section.html @@ -0,0 +1,69 @@ +{% macro testimonials_section(title="What My Clients Say", subtitle="Don't just take my word for it - hear from some of my satisfied clients.", t=t) %} +
+
+
+
+

{{ title }}

+

{{ subtitle }}

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

{{ t('"Got my website in 2 days! Now I get 15 new customers every week from online orders. Best €299 I ever spent for my bakery."') }}

+
+ {{ t('Maria Van Damme') }}
+ {{ t('Bakery Owner') }} +
+
+
+
+
+
+
+
+ + + + + +
+

{{ t('"My perfume shop website brings in 30% more customers. People find me on Google and call to ask about my products. Website paid for itself in the first month!"') }}

+
+ {{ t('Anna De Vries') }}
+ {{ t('Perfume Shop Owner') }} +
+
+
+
+
+
+
+
+ + + + + +
+

{{ t('"Kobe made everything so simple. One phone call, told him about my restaurant, and 48 hours later I had a beautiful website. Now customers can see my menu and call to make reservations."') }}

+
+ {{ t('Piet Janssens') }}
+ {{ t('Restaurant Owner') }} +
+
+
+
+
+
+
+{% endmacro %} \ No newline at end of file diff --git a/templates/contact.html b/templates/contact.html new file mode 100644 index 0000000..71d6a6f --- /dev/null +++ b/templates/contact.html @@ -0,0 +1,304 @@ +{% extends "base.html" %} + +{% block title %}{{ t('Contact Kobelly | Web Design Brussels') }}{% endblock %} + +{% block description %}{{ t('Contact Kobelly for professional website design in Brussels. Free consultation, transparent pricing, and ongoing support. Get your business online in 48 hours.') }}{% endblock %} + +{% block keywords %}{{ t('website design, web development, small business, Belgium, Brussels, professional websites, affordable web design') }}{% endblock %} + +{% block og_title %}{{ t('Contact Kobelly | Web Design Brussels') }}{% endblock %} + +{% block og_description %}{{ t('Contact Kobelly for professional website design in Brussels. Free consultation, transparent pricing, and ongoing support. Get your business online in 48 hours.') }}{% endblock %} + +{% block twitter_title %}{{ t('Contact Kobelly | Web Design Brussels') }}{% endblock %} + +{% block twitter_description %}{{ t('Contact Kobelly for professional website design in Brussels. Free consultation, transparent pricing, and ongoing support. Get your business online in 48 hours.') }}{% endblock %} + +{% block content %} + +
+
+
+
+
+

{{ t('Ready to Start Your Project?') }}

+

{{ t('Let\'s discuss how I can help your business grow online. I offer a free consultation to understand your needs and provide a customized solution.') }}

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

{{ t('Send Me a Message') }}

+

{{ t('Fill out the form below and I\'ll get back to you within 48 hours.') }}

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

{{ t('Get in Touch') }}

+
+ +
+
+
+ +
+
+
{{ t('Email') }}
+ info@kobelly.com +
+
+
+ +
+
+
+ +
+
+
{{ t('Phone') }}
+ {{ t('+32 486 21 07 07') }} +
+
+
+ + + +
+
{{ t('Follow Us') }}
+ +
+ +
+ + {{ t('Free Consultation') }}
+ {{ t('We offer a free 30-minute consultation to discuss your project requirements and provide a customized quote.') }} +
+
+
+
+
+
+
+ + +{{ testimonials.testimonials_section( + title=t('What My Clients Say'), + subtitle=t('Don\'t just take my word for it - hear from some of my satisfied clients.'), + t=t +) }} + + +
+
+
+
+

{{ t('Find Us') }}

+

{{ t('Located in the heart of Brussels, serving clients across Belgium and Europe.') }}

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

{{ t('Frequently Asked Questions') }}

+

{{ t('Find answers to common questions about our services and process.') }}

+
+
+ +
+
+
+
+
+ +
+
{{ t('How long does it take to build a website?') }}
+

{{ t('The timeline depends on the complexity of your project. A simple business website typically takes 2-4 weeks, while more complex e-commerce sites may take 6-8 weeks.') }}

+
+
+
+
+
+
+
+ +
+
{{ t('Do you provide ongoing support?') }}
+

{{ t('Yes! We offer various maintenance packages to keep your website secure, updated, and running smoothly. We also provide technical support and content updates.') }}

+
+
+
+
+
+
+
+ +
+
{{ t('What is your pricing structure?') }}
+

{{ t('Our pricing is transparent and project-based. We provide detailed quotes after understanding your requirements. We offer flexible payment plans and competitive rates for small businesses.') }}

+
+
+
+
+
+
+
+ +
+
{{ t('Do you work with small businesses?') }}
+

{{ t('Yes, we specialize in working with small businesses and entrepreneurs. We understand your unique needs and budget constraints.') }}

+
+
+
+
+
+
+ + +{{ components.cta_section( + title="Ready to Start Your Project?", + description="Let's discuss how I can help your business grow online.", + button_text="Get Free Consultation", + button_url="contact", + t=t +) }} +{% endblock %} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..ca759e8 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,354 @@ +{% extends "base.html" %} + +{% block title %}{{ t('Professional Website Design Brussels | Kobelly Web Solutions') }}{% endblock %} + +{% block description %}{{ t('Professional website design for small businesses in Belgium. Fast, affordable websites that help you get found online.') }}{% endblock %} + +{% block keywords %}{{ t('website design, web development, small business, Belgium, Brussels, professional websites, affordable web design') }}{% endblock %} + +{% block og_title %}{{ t('Professional Website Design Brussels | Kobelly Web Solutions') }}{% endblock %} + +{% block og_description %}{{ t('Professional website design for small businesses in Belgium. Fast, affordable websites that help you get found online.') }}{% endblock %} + +{% block twitter_title %}{{ t('Professional Website Design Brussels | Kobelly Web Solutions') }}{% endblock %} + +{% block twitter_description %}{{ t('Professional website design for small businesses in Belgium. Fast, affordable websites that help you get found online.') }}{% endblock %} + +{% block content %} + +
+
+ +
+
+
+
+
+
+
+
+ + +
</>
+
{ }
+
[ ]
+
</>
+
+ +
+
+
+
+

{{ t('Get Your Business Online in 48 Hours') }}

+

{{ t('Professional websites for small businesses. Fast, affordable, and designed to bring you customers. No technical knowledge needed - I handle everything.') }}

+ {{ stats.stats_section([ + {"value": "48h", "label": "Delivery Time"}, + {"value": "€299", "label": "Starting Price"}, + {"value": "100%", "label": "Satisfaction"} + ], t) }} + +
+
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + {{ t('75% of customers research businesses online before visiting') }} +
+
+ + {{ t('Your competitors are already online') }} +
+
+
+
+
+
+ + +
+
+
+
+
+

{{ t('Why Choose Kobelly?') }}

+

{{ t('I make getting online simple and affordable for small businesses like yours.') }}

+
+
+
+ +
+
+
+
+
+ +
+
{{ t('Fast Delivery') }}
+

{{ t('Your website ready in 48 hours. No waiting weeks or months - get online fast and start getting customers.') }}

+
+
+
+
+
+
+
+ +
+
{{ t('Affordable Pricing') }}
+

{{ t('Starting at €299. Small monthly hosting fee keeps your website online. No hidden costs or surprises.') }}

+
+
+
+
+
+
+
+ +
+
{{ t('Personal Service') }}
+

{{ t('Work directly with me - no account managers or middlemen. I understand your business and your needs.') }}

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

{{ t('What I Do for Your Business') }}

+

{{ t('I help small businesses get online and start getting customers.') }}

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

{{ t('Business Websites') }}

+
+

{{ t('Professional websites that showcase your business and help customers find you online.') }}

+
    +
  • {{ t('Show your products/services') }}
  • +
  • {{ t('Contact information & location') }}
  • +
  • {{ t('Customer testimonials') }}
  • +
+
+
+
+
+
+
+
+
+ +
+

{{ t('Online Stores') }}

+
+

{{ t('Sell your products online 24/7. Accept payments, manage orders, and grow your sales.') }}

+
    +
  • {{ t('Secure payment processing') }}
  • +
  • {{ t('Product catalog management') }}
  • +
  • {{ t('Order tracking system') }}
  • +
+
+
+
+
+ + +
+
+ + +
+
+
+
+

{{ t('Get Found by Local Customers') }}

+

{{ t('Your website helps customers in your area find and choose your business.') }}

+
+
+ +
+
+
+
+
+
+ +
+
+
{{ t('Show Up in Google Maps') }}
+

{{ t('When people search for businesses like yours in your area, your website helps you appear in local search results.') }}

+
+
+
+
+
+
+
+
+
+
+ +
+
+
{{ t('Get Reviews & Ratings') }}
+

{{ t('Customers can leave reviews on your website and Google, helping other customers choose your business.') }}

+
+
+
+
+
+
+
+
+
+
+ +
+
+
{{ t('Open 24/7 Online') }}
+

{{ t('Your website works for you even when you\'re closed. Customers can see your products, prices, and contact info anytime.') }}

+
+
+
+
+
+
+
+
+
+
+ +
+
+
{{ t('Easy Contact & Directions') }}
+

{{ t('Customers can easily find your phone number, address, and get directions to your business.') }}

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

{{ t('What Happens Without a Website?') }}

+

{{ t('See the difference a website makes for your business.') }}

+
+
+ +
+
+
+
+

{{ t('Without a Website') }}

+
+
+
    +
  • + + {{ t('Customer calls, you\'re closed, they call your competitor') }} +
  • +
  • + + {{ t('People can\'t find your business on Google') }} +
  • +
  • + + {{ t('No way to show your products or services online') }} +
  • +
  • + + {{ t('Customers can\'t leave reviews or recommendations') }} +
  • +
  • + + {{ t('Your competitors get all the online customers') }} +
  • +
+
+
+
+
+
+
+

{{ t('With a Website') }}

+
+
+
    +
  • + + {{ t('Customers can see your business even when you\'re closed') }} +
  • +
  • + + {{ t('Show up in Google search results and Maps') }} +
  • +
  • + + {{ t('Display your products, services, and prices 24/7') }} +
  • +
  • + + {{ t('Customers can leave reviews and recommend you') }} +
  • +
  • + + {{ t('Get customers that would have gone to competitors') }} +
  • +
+
+
+
+
+
+
+ + +{{ components.cta_section( + title="Ready to Get Your Business Online?", + description="Let's talk about your website. Free consultation, no obligation.", + button_text="Get Started Today", + button_url="contact", + t=t +) }} +{% endblock %} \ No newline at end of file diff --git a/templates/portfolio.html b/templates/portfolio.html new file mode 100644 index 0000000..76a9622 --- /dev/null +++ b/templates/portfolio.html @@ -0,0 +1,364 @@ +{% extends "base.html" %} + +{% block title %}{{ t('Portfolio | Web Design Projects Brussels') }}{% endblock %} + +{% block description %}{{ t('View my web design portfolio featuring business websites, e-commerce sites, and custom web solutions. Professional web design projects completed in Brussels.') }}{% endblock %} + +{% block keywords %}{{ t('website design, web development, small business, Belgium, Brussels, professional websites, affordable web design') }}{% endblock %} + +{% block og_title %}{{ t('Portfolio | Web Design Projects Brussels') }}{% endblock %} + +{% block og_description %}{{ t('View my web design portfolio featuring business websites, e-commerce sites, and custom web solutions. Professional web design projects completed in Brussels.') }}{% endblock %} + +{% block twitter_title %}{{ t('Portfolio | Web Design Projects Brussels') }}{% endblock %} + +{% block twitter_description %}{{ t('View my web design portfolio featuring business websites, e-commerce sites, and custom web solutions. Professional web design projects completed in Brussels.') }}{% endblock %} + +{% block content %} + +{{ hero.hero_section( + title="Design Showcase", + subtitle="Explore different design styles and themes. Click on any design to see how your website could look with these modern, professional styles.", + icon_class="fas fa-palette", + stats=[ + {"value": "8+", "label": "Years Experience"}, + {"value": "15,000+", "label": "Hours Coded"}, + {"value": "100%", "label": "Committed"} + ], + t=t +) }} + + +
+
+
+
+

{{ t('Interactive Design Themes') }}

+

{{ t('Click on any design below to preview how your website could look. Each theme demonstrates different styles, colors, and layouts.') }}

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

{{ t('Modern Minimal') }}

+

{{ t('Clean, spacious design with subtle animations and modern typography.') }}

+
+ Clean + Modern + Minimal +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

{{ t('Bold & Vibrant') }}

+

{{ t('Eye-catching design with bold colors and dynamic elements.') }}

+
+ Bold + Colorful + Dynamic +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

{{ t('Elegant Professional') }}

+

{{ t('Sophisticated design with premium styling and professional appeal.') }}

+
+ Elegant + Professional + Premium +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

{{ t('Tech Startup') }}

+

{{ t('Modern tech-focused design with innovative layouts and animations.') }}

+
+ Tech + Innovative + Modern +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

{{ t('Creative Agency') }}

+

{{ t('Artistic design with creative layouts and expressive visual elements.') }}

+
+ Creative + Artistic + Expressive +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

{{ t('E-commerce') }}

+

{{ t('Optimized design for online stores with product-focused layouts.') }}

+
+ E-commerce + Product-focused + Optimized +
+
+
+
+
+ + +
+
+
+
+

{{ t('Live Preview') }}

+

{{ t('Click on any design above to see a live preview of how your website could look.') }}

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

Welcome to Your Business

+

Professional solutions for your success

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

Fast & Reliable

+

Lightning-fast performance and reliable service.

+
+
+
+ +
+

Secure & Safe

+

Your data is protected with industry-leading security.

+
+
+
+ +
+

24/7 Support

+

Round-the-clock support when you need it most.

+
+
+ + +
+
+

Ready to Get Started?

+

Join thousands of satisfied customers today.

+ +
+
+ + + +
+
+
+
+
+
+
+ + +{{ testimonials.testimonials_section( + title=t('What My Clients Say'), + subtitle=t('Don\'t just take my word for it - hear from some of the businesses I\'ve helped.'), + t=t +) }} + + +{{ components.cta_section( + title="Ready to Start Your Project?", + description="Let's discuss your project and create something amazing together. I offer a free consultation to understand your needs and provide a customized solution.", + button_text="Get Started", + button_url="contact", + t=t +) }} +{% endblock %} \ No newline at end of file diff --git a/templates/services.html b/templates/services.html new file mode 100644 index 0000000..8ae258e --- /dev/null +++ b/templates/services.html @@ -0,0 +1,262 @@ +{% extends "base.html" %} + +{% block title %}{{ t('Website Design Services Brussels | Kobelly') }}{% endblock %} + +{% block description %}{{ t('Professional website design services in Brussels. Custom websites for small businesses starting at €299. Fast delivery, ongoing support, and proven results.') }}{% endblock %} + +{% block keywords %}{{ t('website design, web development, small business, Belgium, Brussels, professional websites, affordable web design') }}{% endblock %} + +{% block og_title %}{{ t('Website Design Services Brussels | Kobelly') }}{% endblock %} + +{% block og_description %}{{ t('Professional website design services in Brussels. Custom websites for small businesses starting at €299. Fast delivery, ongoing support, and proven results.') }}{% endblock %} + +{% block twitter_title %}{{ t('Website Design Services Brussels | Kobelly') }}{% endblock %} + +{% block twitter_description %}{{ t('Professional website design services in Brussels. Custom websites for small businesses starting at €299. Fast delivery, ongoing support, and proven results.') }}{% endblock %} + +{% block content %} + +
+
+
+
+
+

{{ t('Professional Web Solutions') }}

+

{{ t('Comprehensive web services designed to help your business succeed online. From custom design to e-commerce solutions, I provide everything you need to establish a strong digital presence.') }}

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

{{ t('Website Design') }}

+
+ +

{{ t('Custom, professional website design that perfectly represents your brand and engages your target audience.') }}

+ +
+
{{ t('What\'s Included:') }}
+
    +
  • + + {{ t('Responsive design') }} +
  • +
  • + + {{ t('Modern UI/UX') }} +
  • +
  • + + {{ t('Optimized structure') }} +
  • +
  • + + {{ t('Fast loading times') }} +
  • +
  • + + {{ t('Cross-browser compatibility') }} +
  • +
+
+ + +
+
+
+ + +
+
+
+
+
+ +
+

{{ t('E-commerce Solutions') }}

+
+ +

{{ t('Complete online store setup with secure payment processing, inventory management, and customer tracking.') }}

+ +
+
{{ t('What\'s Included:') }}
+
    +
  • + + {{ t('Online store setup') }} +
  • +
  • + + {{ t('Payment integration') }} +
  • +
  • + + {{ t('Inventory management') }} +
  • +
  • + + {{ t('Order processing') }} +
  • +
  • + + {{ t('Customer accounts') }} +
  • +
+
+ + +
+
+
+ + +
+
+
+
+
+ +
+

{{ t('Maintenance & Support') }}

+
+ +

{{ t('Ongoing website maintenance, updates, and technical support to keep your site running smoothly.') }}

+ +
+
{{ t('What\'s Included:') }}
+
    +
  • + + {{ t('Regular security updates') }} +
  • +
  • + + {{ t('Performance monitoring') }} +
  • +
  • + + {{ t('Backup management') }} +
  • +
  • + + {{ t('Content updates') }} +
  • +
  • + + {{ t('Technical support') }} +
  • +
  • + + {{ t('Monthly reports') }} +
  • +
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+

{{ t('How It Works') }}

+

{{ t('Getting your business online is easier than you think.') }}

+
+
+ +
+ +
+ +
+
+
+
+ +
+
+
+
{{ t('Tell Me About Your Business') }}
+

{{ t('One 15-minute call. I ask about your business, you tell me what you need.') }}

+
+
+
+ +
+
+
+
+ +
+
+
+
{{ t('I Build Your Website') }}
+

{{ t('I create your website quickly. Simple sites in 48 hours, more complex ones take a bit longer.') }}

+
+
+
+ +
+
+
+
+ +
+
+
+
{{ t('Start Getting Customers') }}
+

{{ t('Your website goes live. Customers find you online and start calling or visiting.') }}

+
+
+
+
+
+
+ + +{{ components.cta_section( + title="Ready to Start Your Project?", + description="Let's discuss how I can help your business grow online.", + button_text="Get Free Consultation", + button_url="contact", + t=t +) }} +{% endblock %} \ No newline at end of file diff --git a/test_translations.py b/test_translations.py new file mode 100644 index 0000000..230d244 --- /dev/null +++ b/test_translations.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +""" +Test script to debug translation issues +""" + +from translation_manager import load_translations, translate, get_current_language, set_language +from flask import Flask, request, session +import os + +# Create a minimal Flask app for testing +app = Flask(__name__) +app.secret_key = 'test-key' + +# Load translations +print("Loading translations...") +load_translations() + +# Test translations +print("\nTesting translations:") +print("Home in EN:", translate('Home', 'en')) +print("Home in DE:", translate('Home', 'de')) +print("Home in FR:", translate('Home', 'fr')) +print("Home in NL:", translate('Home', 'nl')) + +print("\nTesting with Flask context:") +with app.test_request_context(): + print("Current language (default):", get_current_language()) + print("Home translation (default):", translate('Home')) + + # Test setting language + set_language('de') + print("Current language (after setting DE):", get_current_language()) + print("Home translation (DE):", translate('Home')) + + set_language('fr') + print("Current language (after setting FR):", get_current_language()) + print("Home translation (FR):", translate('Home')) + +print("\nTranslation system test completed!") \ No newline at end of file diff --git a/translation_manager.py b/translation_manager.py new file mode 100644 index 0000000..05d5829 --- /dev/null +++ b/translation_manager.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +""" +Simple JSON-based Translation Manager for Kobelly Web Solutions +No compilation needed - just edit JSON files directly! +""" + +import os +import json +import glob +from flask import request, session, url_for +from functools import wraps + +# Supported languages +SUPPORTED_LANGUAGES = ['en', 'de', 'fr', 'nl'] + +# Default language +DEFAULT_LANGUAGE = 'en' + +# Translation cache +_translations = {} + +def load_translations(): + """Load all translation files into memory.""" + global _translations + + if not os.path.exists('translations'): + os.makedirs('translations') + + for lang in SUPPORTED_LANGUAGES: + lang_file = f'translations/{lang}.json' + + if os.path.exists(lang_file): + try: + with open(lang_file, 'r', encoding='utf-8') as f: + _translations[lang] = json.load(f) + print(f"✓ Loaded {lang} translations ({len(_translations[lang])} keys)") + except Exception as e: + print(f"✗ Error loading {lang} translations: {e}") + _translations[lang] = {} + else: + print(f"⚠ {lang} translation file not found, creating empty one") + _translations[lang] = {} + save_translations(lang, {}) + +def save_translations(lang, translations): + """Save translations for a specific language.""" + if not os.path.exists('translations'): + os.makedirs('translations') + + lang_file = f'translations/{lang}.json' + try: + with open(lang_file, 'w', encoding='utf-8') as f: + json.dump(translations, f, indent=2, ensure_ascii=False) + _translations[lang] = translations + print(f"✓ Saved {lang} translations") + return True + except Exception as e: + print(f"✗ Error saving {lang} translations: {e}") + return False + +def get_current_language(): + """Get the current language from session or request.""" + # Check session first + if 'language' in session: + return session['language'] + + # Check request parameter + if request.args.get('lang') in SUPPORTED_LANGUAGES: + return request.args.get('lang') + + # Check Accept-Language header + if request.accept_languages: + for lang in request.accept_languages: + if lang[0] in SUPPORTED_LANGUAGES: + return lang[0] + + return DEFAULT_LANGUAGE + +def set_language(lang): + """Set the current language in session.""" + if lang in SUPPORTED_LANGUAGES: + session['language'] = lang + print(f"✓ Language set to {lang}") + return True + print(f"✗ Invalid language: {lang}") + return False + +def translate(key, lang=None, **kwargs): + """Translate a key to the specified language.""" + if lang is None: + lang = get_current_language() + + # Get translation + translation = _translations.get(lang, {}).get(key, key) + + # Format with kwargs if provided + if kwargs: + try: + translation = translation.format(**kwargs) + except (KeyError, ValueError): + # If formatting fails, return the key + translation = key + + return translation + +def extract_strings(): + """Extract all translatable strings from templates and create translation files.""" + print("📤 Extracting translatable strings...") + + # Find all template files + template_files = glob.glob('templates/**/*.html', recursive=True) + + # Extract strings (this is a simplified version) + # In practice, you'd want to parse the templates more thoroughly + extracted_strings = set() + + for template_file in template_files: + try: + with open(template_file, 'r', encoding='utf-8') as f: + content = f.read() + # Look for common patterns (this is simplified) + # You might want to use a proper template parser + lines = content.split('\n') + for line in lines: + line = line.strip() + if line and not line.startswith('{') and not line.startswith('