From 1f6a679557c47b79a272c3591b828cc4956b7ea9 Mon Sep 17 00:00:00 2001 From: Urtzi Alfaro Date: Wed, 19 Nov 2025 07:46:40 +0100 Subject: [PATCH] Improve frontend traslations 2 --- docs/pilot-launch-cost-effective-plan.md | 305 ++++++++++++++++++ .../subscription/SubscriptionPricingCards.tsx | 10 +- frontend/src/locales/en/about.json | 94 ++++++ frontend/src/locales/en/demo.json | 65 ++++ frontend/src/locales/es/about.json | 94 ++++++ frontend/src/locales/es/demo.json | 65 ++++ frontend/src/locales/eu/about.json | 94 ++++++ frontend/src/locales/eu/demo.json | 65 ++++ frontend/src/locales/eu/features.json | 8 + frontend/src/locales/index.ts | 22 +- frontend/src/pages/public/AboutPage.tsx | 117 +++---- frontend/src/pages/public/DemoPage.tsx | 88 ++--- frontend/src/pages/public/FeaturesPage.tsx | 296 ++++++++--------- frontend/src/styles/components.css | 7 + 14 files changed, 1068 insertions(+), 262 deletions(-) create mode 100644 docs/pilot-launch-cost-effective-plan.md create mode 100644 frontend/src/locales/en/about.json create mode 100644 frontend/src/locales/en/demo.json create mode 100644 frontend/src/locales/es/about.json create mode 100644 frontend/src/locales/es/demo.json create mode 100644 frontend/src/locales/eu/about.json create mode 100644 frontend/src/locales/eu/demo.json diff --git a/docs/pilot-launch-cost-effective-plan.md b/docs/pilot-launch-cost-effective-plan.md new file mode 100644 index 00000000..22035323 --- /dev/null +++ b/docs/pilot-launch-cost-effective-plan.md @@ -0,0 +1,305 @@ +# Cost-Effective Pilot Launch Plan for Bakery-IA + +## Executive Summary +Total estimated cost: **€50-80/month** (€300-480 for 6-month pilot) + +## 1. Server Setup (clouding.io) + +**Recommended VPS Configuration:** +- **RAM**: 20 GB +- **CPU**: 8 vCPU +- **Storage**: 200 GB NVMe SSD +- **Cost**: €40-80/month +- **Setup**: Install k3s (lightweight Kubernetes) + +**Why clouding.io:** +- Cost-effective European VPS provider +- Good performance/price ratio +- Supports custom ISO and Kubernetes +- Barcelona-based (good latency for Spain) + +## 2. Domain & DNS + +**Domain Registration:** +- Register domain at **Namecheap** or **Cloudflare Registrar** (~€10-15/year) +- Suggested: `bakeryforecast.es` or `bakery-ia.com` + +**DNS Configuration (FREE):** +- Use **Cloudflare DNS** (free tier) +- Benefits: Fast DNS, free SSL proxy option, DDoS protection +- Point A record to your clouding.io VPS IP + +## 3. Email Solution (Professional Domain Email) + +**RECOMMENDED: Gmail + Google Workspace Trial + Free Forwarding** + +### Option A - Gmail SMTP (FREE, best for pilot): +1. Use existing Gmail account with App Password +2. Configure `DEFAULT_FROM_EMAIL: "noreply@bakeryforecast.es"` +3. Set up **email forwarding** at domain registrar: + - `info@bakeryforecast.es` → your personal Gmail + - `noreply@bakeryforecast.es` → your personal Gmail +4. Send via Gmail SMTP, receive via forwarding +5. **Limit**: 500 emails/day (sufficient for 10 tenants) +6. **Cost**: FREE + +### Option B - Google Workspace (if you need professional inbox): +- First 14 days FREE trial +- After trial: €5.75/user/month for Business Starter +- Includes: Professional email, 30GB storage, Meet +- Can cancel after pilot if needed + +### Option C - Zoho Mail (FREE permanent option): +- FREE tier: 1 domain, 5 users, 5GB/user +- Professional email addresses with your domain +- Send/receive from `info@bakeryforecast.es` +- Web interface + SMTP/IMAP +- **Cost**: FREE forever + +### Option D - Cloudflare Email Routing (FREE forwarding only): +- FREE email forwarding from your domain to personal Gmail +- Can receive at `info@bakeryforecast.es` → forwards to Gmail +- Cannot send FROM domain (receive only) +- **Cost**: FREE + +**RECOMMENDATION**: Start with **Zoho Mail FREE** for full send/receive capability, or **Gmail SMTP + domain forwarding** if you just need to send notifications. + +## 4. WhatsApp Business API (FREE for pilot) + +**Setup Meta WhatsApp Business Cloud API:** +1. Create Meta Business Account (FREE) +2. Register WhatsApp Business phone number + - **Use your personal phone number** (must be non-VoIP) + - Can test with personal number initially + - Later: Get dedicated number (~€5-10/month from Twilio or similar) +3. Create app in Meta Developer Portal +4. Configure webhook for delivery status +5. Create message templates and submit for approval (15 min - 24 hours) + +**Cost Breakdown:** +- First **1,000 conversations/month**: FREE +- Beyond free tier: €0.01-0.10 per conversation +- For 10 bakeries with ~50 notifications/month each = 500 total = **FREE** + +**Personal Phone Testing:** +- You can use your personal WhatsApp number for testing +- Meta allows switching numbers during development +- Later migrate to dedicated business number + +## 5. Email Notifications Testing + +**Testing Strategy (FREE):** +1. Use **Mailtrap.io** (FREE tier) for development testing + - Catches all emails in fake inbox + - Test templates without sending real emails + - 100 emails/month free +2. Use **Gmail + filters** for real testing + - Create Gmail filter to label test emails + - Send to your own email addresses +3. Use **temp-mail.org** for disposable test addresses + +**Production Email Testing:** +- Send test emails to your personal Gmail +- Verify deliverability, template rendering, links +- Check spam score with **mail-tester.com** (FREE) + +## 6. SSL Certificates (FREE) + +**Let's Encrypt (already configured in your setup):** +- FREE SSL certificates +- Auto-renewal with cert-manager +- Wildcard certificates supported +- **Cost**: FREE + +## 7. Additional Cost Optimizations + +**What to SKIP in pilot phase:** +- ❌ Managed databases (use containerized PostgreSQL) +- ❌ CDN (not needed for <50 users) +- ❌ Premium monitoring tools (use included Prometheus/Grafana) +- ❌ Paid backup services (use VPS snapshot feature) +- ❌ Multiple replicas (single instance sufficient) + +**What to USE (FREE/included):** +- ✅ Let's Encrypt SSL +- ✅ Cloudflare DNS + DDoS protection +- ✅ Gmail SMTP or Zoho Mail +- ✅ Meta WhatsApp Business API (1k free conversations) +- ✅ Self-hosted monitoring (Prometheus/Grafana) +- ✅ VPS snapshots for backups + +## 8. Total Cost Breakdown + +### Monthly Recurring Costs +| Service | Provider | Monthly Cost | +|---------|----------|-------------| +| VPS Server | clouding.io | €40-80 | +| Domain | Namecheap | €1.25 (€15/year) | +| Email | Zoho/Gmail | €0 (FREE tier) | +| WhatsApp | Meta Business API | €0 (FREE tier) | +| DNS | Cloudflare | €0 (FREE tier) | +| SSL | Let's Encrypt | €0 (FREE) | +| **TOTAL** | | **€41-81/month** | + +### 6-Month Pilot Total: €246-486 + +### Optional Add-ons +- Dedicated WhatsApp number: +€5-10/month +- Google Workspace: +€5.75/user/month +- VPS backups: +€8-15/month +- External geocoding API: +€5-10/month + +## 9. Implementation Steps + +### Week 1: Infrastructure Setup +1. Register domain at Namecheap/Cloudflare +2. Set up clouding.io VPS with Ubuntu 22.04 +3. Install k3s (lightweight Kubernetes) +4. Configure Cloudflare DNS pointing to VPS + +### Week 2: Email & Communication +1. Set up Zoho Mail FREE account with domain +2. Configure SMTP credentials in Kubernetes secrets +3. Create Meta Business Account for WhatsApp +4. Register your personal phone with WhatsApp Business API +5. Create and submit WhatsApp message templates + +### Week 3: Deployment +1. Update Kubernetes secrets with production values +2. Deploy application using Skaffold +3. Configure SSL with Let's Encrypt +4. Test email notifications +5. Test WhatsApp notifications to your personal number + +### Week 4: Testing & Launch +1. Send test emails to verify deliverability +2. Send test WhatsApp messages +3. Invite first pilot bakery +4. Monitor costs and usage + +## 10. Migration Path (Post-Pilot) + +When ready to scale beyond pilot: +- **25-50 tenants**: Upgrade VPS to 32GB RAM (€80-120/month) +- **Email**: Upgrade to paid tier or switch to AWS SES +- **WhatsApp**: Start paying per conversation beyond 1k/month +- **Database**: Consider managed PostgreSQL for HA +- **Monitoring**: Add external monitoring (UptimeRobot, etc.) + +## Key Recommendations Summary + +1. **VPS**: Use clouding.io (€40-80/month) with k3s +2. **Domain**: Register at Namecheap + use Cloudflare DNS (FREE) +3. **Email**: Zoho Mail FREE tier for professional domain email +4. **WhatsApp**: Meta Business API with personal phone for testing (FREE 1k conversations) +5. **SSL**: Let's Encrypt (FREE, auto-renewal) +6. **Testing**: Use personal email addresses and your WhatsApp number +7. **Skip**: Managed services, CDN, premium monitoring for now + +**Total pilot cost: €41-81/month** or **€246-486 for 6 months** + +--- + +## Current Infrastructure Status + +### What's Already Configured ✅ + +1. **Email Notifications**: SMTP with Gmail (FREE tier ready) +2. **WhatsApp Notifications**: Meta Business API integration (1,000 FREE conversations/month) +3. **Kubernetes Deployment**: Complete manifests for all services +4. **Docker Compose**: Local development environment +5. **Monitoring**: Prometheus + Grafana configured +6. **Database Migrations**: Alembic for all 18 services +7. **Service Mesh**: RabbitMQ for event-driven architecture +8. **Caching**: Redis configured +9. **SSL/TLS**: cert-manager for automatic certificates +10. **Frontend**: React application with Vite build + +### What Needs Setup ❌ + +1. **Domain Registration**: Buy domain (e.g., bakeryforecast.es) +2. **DNS Configuration**: Point domain to VPS IP +3. **Production Secrets**: Replace placeholder secrets with real values +4. **WhatsApp Business Account**: Register with Meta (1-3 days) +5. **Email SMTP Credentials**: Get Gmail app password or Zoho account +6. **VPS Provisioning**: Set up server at clouding.io +7. **Kubernetes Cluster**: Install k3s on VPS +8. **CI/CD Pipeline**: GitHub Actions for automated deployment (optional) +9. **Backup Strategy**: Configure VPS snapshots +10. **Monitoring Alerts**: Configure Prometheus alerting rules + +## Technical Requirements + +### VPS Specifications (Minimum for 10 tenants) +- **RAM**: 20 GB +- **CPU**: 8 vCPU +- **Storage**: 200 GB NVMe SSD +- **Network**: 1 Gbps connection +- **OS**: Ubuntu 22.04 LTS + +### Storage Breakdown +- **Databases**: 36 GB (18 x 2GB PostgreSQL instances) +- **ML Models**: 10 GB (training/forecasting models) +- **Redis Cache**: 1 GB +- **RabbitMQ**: 2 GB +- **Prometheus Metrics**: 20 GB +- **Container Images**: ~30 GB +- **Growth Buffer**: ~100 GB +- **TOTAL**: 200 GB recommended + +### Memory Requirements +- **Application Services**: 14.1 GB requests / 34.5 GB limits +- **Databases**: 4.6 GB requests / 9.2 GB limits +- **Infrastructure (Redis, RabbitMQ)**: 0.8 GB +- **Gateway/Frontend**: 1.8 GB +- **Monitoring**: 1.5 GB +- **TOTAL**: ~20 GB RAM minimum + +## Configuration Files to Update + +### Email Configuration +**File**: `infrastructure/kubernetes/base/secrets.yaml` +```yaml +SMTP_HOST: "smtp.gmail.com" # or smtp.zoho.com +SMTP_PORT: "587" +SMTP_USERNAME: +SMTP_PASSWORD: +DEFAULT_FROM_EMAIL: "noreply@bakeryforecast.es" +``` + +### WhatsApp Configuration +**File**: `infrastructure/kubernetes/base/secrets.yaml` +```yaml +WHATSAPP_ACCESS_TOKEN: +WHATSAPP_PHONE_NUMBER_ID: +WHATSAPP_BUSINESS_ACCOUNT_ID: +WHATSAPP_WEBHOOK_VERIFY_TOKEN: +``` + +### Domain Configuration +**File**: `infrastructure/kubernetes/base/configmap.yaml` +```yaml +DOMAIN: "bakeryforecast.es" +CORS_ORIGINS: "https://bakeryforecast.es,https://www.bakeryforecast.es" +``` + +## Useful Links + +- **WhatsApp Setup Guide**: `services/notification/WHATSAPP_SETUP_GUIDE.md` +- **Multi-tenant WhatsApp**: `services/notification/MULTI_TENANT_WHATSAPP_IMPLEMENTATION.md` +- **VPS Sizing Guide**: `docs/05-deployment/vps-sizing-production.md` +- **K8s Production Readiness**: `docs/05-deployment/k8s-production-readiness.md` +- **Kubernetes README**: `infrastructure/kubernetes/README.md` + +## Next Steps + +1. **Register domain** at Namecheap or Cloudflare +2. **Sign up for clouding.io VPS** (20GB RAM, 8 vCPU, 200GB SSD) +3. **Set up Zoho Mail** with your domain (FREE) +4. **Create Meta Business Account** for WhatsApp +5. **Follow Week 1-4 implementation plan** above + +--- + +*Last Updated: 2025-11-19* +*Estimated Total Pilot Cost: €246-486 for 6 months* diff --git a/frontend/src/components/subscription/SubscriptionPricingCards.tsx b/frontend/src/components/subscription/SubscriptionPricingCards.tsx index 9ac0042b..fe683e35 100644 --- a/frontend/src/components/subscription/SubscriptionPricingCards.tsx +++ b/frontend/src/components/subscription/SubscriptionPricingCards.tsx @@ -194,7 +194,7 @@ export const SubscriptionPricingCards: React.FC = )} {/* Billing Cycle Toggle */} -
+
@@ -128,12 +127,8 @@ const AboutPage: React.FC = () => {
-

Nuestra Misión

-

- Ayudar a panaderías a reducir desperdicios, aumentar rentabilidad y ahorrar tiempo - mediante inteligencia artificial accesible y fácil de usar. Ya sea que produzcas localmente o gestiones un obrador central - con múltiples puntos de venta, queremos que puedas enfocarte en tu pasión: crear productos de calidad excepcional. -

+

{t('mission.title')}

+

{/* Vision */} @@ -141,12 +136,8 @@ const AboutPage: React.FC = () => {
-

Nuestra Visión

-

- Un mundo donde ninguna panadería cierre por problemas de gestión, sin importar su tamaño o modelo de negocio. - Donde la tecnología democratiza el acceso a herramientas avanzadas y permite que la calidad y el talento florezcan - sin las cargas administrativas que agobian a los negocios. -

+

{t('vision.title')}

+

@@ -157,10 +148,10 @@ const AboutPage: React.FC = () => {

- Nuestros Valores + {t('values.title')}

- Principios que guían cada decisión que tomamos + {t('values.subtitle')}

@@ -186,10 +177,10 @@ const AboutPage: React.FC = () => {

- El Fundador + {t('founder.title')}

- Un emprendedor en solitario con una visión clara: democratizar la tecnología de IA para panaderías de todos los tamaños + {t('founder.subtitle')}

@@ -201,18 +192,13 @@ const AboutPage: React.FC = () => { UA
-

Urtzi Alfaro

-

Fundador & CEO

+

{t('founder.name')}

+

{t('founder.position')}

- Catalizador de transformación, arquitecto estratégico y visionario en tecnología avanzada. - Con más de una década de experiencia internacional liderando proyectos de alta tecnología e innovación, - mi misión es crear impacto sostenible en empresas y sociedad a escala global. + {t('founder.intro')}

- Natural de Donostia-San Sebastián (País Vasco), he trabajado en Londres y Cambridge durante 7 años, - liderando proyectos globales con clientes en EE.UU., Europa y China. Ahora desde Madrid, - aplico mi experiencia en IA, transformación digital y desarrollo de productos para ayudar - a las panaderías a prosperar en la era digital. + {t('founder.bio')}

@@ -242,10 +228,10 @@ const AboutPage: React.FC = () => {

- Nuestro Camino + {t('timeline.title')}

- De la idea al impacto real + {t('timeline.subtitle')}

@@ -276,25 +262,24 @@ const AboutPage: React.FC = () => {

- Sé Parte de Nuestra Historia + {t('cta.title')}

- Estamos buscando 20 panaderías pioneras para nuestro programa piloto. - 3 meses gratis, 20% descuento de por vida, y la oportunidad de moldear el producto. + {t('cta.subtitle')}

- Solicitar Plaza en el Piloto + {t('cta.primary')} - Ver Demo + {t('cta.secondary')}
diff --git a/frontend/src/pages/public/DemoPage.tsx b/frontend/src/pages/public/DemoPage.tsx index 7ce46d8c..64a2b794 100644 --- a/frontend/src/pages/public/DemoPage.tsx +++ b/frontend/src/pages/public/DemoPage.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect, useCallback } from 'react'; import { Link } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; import { PublicLayout } from '../../components/layout'; import { Button } from '../../components/ui'; import { getDemoAccounts, createDemoSession, DemoAccount, demoSessionAPI } from '../../api/services/demo'; @@ -10,6 +11,7 @@ import { markTourAsStartPending } from '../../features/demo-onboarding'; const POLL_INTERVAL_MS = 1500; // Poll every 1.5 seconds export const DemoPage: React.FC = () => { + const { t } = useTranslation(); const [demoAccounts, setDemoAccounts] = useState([]); const [loading, setLoading] = useState(true); const [creatingSession, setCreatingSession] = useState(false); @@ -23,7 +25,7 @@ export const DemoPage: React.FC = () => { const accounts = await getDemoAccounts(); setDemoAccounts(accounts); } catch (err) { - setError('Error al cargar las cuentas demo'); + setError(t('demo:errors.loading_accounts', 'Error al cargar las cuentas demo')); console.error('Error fetching demo accounts:', err); } finally { setLoading(false); @@ -152,7 +154,7 @@ export const DemoPage: React.FC = () => { clearInterval(pollInterval); } } catch (err: any) { - setError(err?.message || 'Error al crear sesión demo'); + setError(err?.message || t('demo:errors.creating_session', 'Error al crear sesión demo')); console.error('Error creating demo session:', err); setCreatingSession(false); } @@ -176,7 +178,7 @@ export const DemoPage: React.FC = () => {
-

Cargando cuentas demo...

+

{t('demo:loading.initial', 'Cargando cuentas demo...')}

@@ -200,31 +202,31 @@ export const DemoPage: React.FC = () => {
- Demo Interactiva + {t('demo:hero.badge', 'Demo Interactiva')}

- Prueba El Panadero Digital - sin compromiso + {t('demo:hero.title', 'Prueba El Panadero Digital')} + {t('demo:hero.subtitle', 'sin compromiso')}

- Elige el tipo de panadería que se ajuste a tu negocio + {t('demo:hero.description', 'Elige el tipo de panadería que se ajuste a tu negocio')}

- Sin tarjeta de crédito + {t('demo:hero.benefits.no_credit_card', 'Sin tarjeta de crédito')}
- 30 minutos de acceso + {t('demo:hero.benefits.access_time', '30 minutos de acceso')}
- Datos reales en español + {t('demo:hero.benefits.real_data', 'Datos reales en español')}
@@ -258,18 +260,18 @@ export const DemoPage: React.FC = () => {

{account.account_type === 'individual_bakery' - ? 'Panadería Individual con Producción local' - : 'Panadería Franquiciada con Obrador Central'} + ? t('demo:accounts.individual_bakery.title', 'Panadería Individual con Producción local') + : t('demo:accounts.central_baker.title', 'Panadería Franquiciada con Obrador Central')}

{account.account_type === 'individual_bakery' - ? account.business_model - : 'Punto de Venta + Obrador Central'} + ? t('demo:accounts.individual_bakery.subtitle', account.business_model) + : t('demo:accounts.central_baker.subtitle', 'Punto de Venta + Obrador Central')}

- DEMO + {t('demo:accounts.demo_badge', 'DEMO')} @@ -281,45 +283,47 @@ export const DemoPage: React.FC = () => { {/* Key Characteristics */}

- Características del negocio + {account.account_type === 'individual_bakery' + ? t('demo:accounts.individual_bakery.characteristics.title', 'Características del negocio') + : t('demo:accounts.central_baker.characteristics.title', 'Características del negocio')}

{account.account_type === 'individual_bakery' ? ( <>
- Empleados: - ~8 + {t('demo:accounts.individual_bakery.characteristics.employees', 'Empleados')}: + {t('demo:accounts.individual_bakery.characteristics.employees_value', '~8')}
- Turnos: - 1/día + {t('demo:accounts.individual_bakery.characteristics.shifts', 'Turnos')}: + {t('demo:accounts.individual_bakery.characteristics.shifts_value', '1/día')}
- Ventas: - Directas + {t('demo:accounts.individual_bakery.characteristics.sales', 'Ventas')}: + {t('demo:accounts.individual_bakery.characteristics.sales_value', 'Directas')}
- Productos: - Local + {t('demo:accounts.individual_bakery.characteristics.products', 'Productos')}: + {t('demo:accounts.individual_bakery.characteristics.products_value', 'Local')}
) : ( <>
- Empleados: - ~5-6 + {t('demo:accounts.central_baker.characteristics.employees', 'Empleados')}: + {t('demo:accounts.central_baker.characteristics.employees_value', '~5-6')}
- Turnos: - 2/día + {t('demo:accounts.central_baker.characteristics.shifts', 'Turnos')}: + {t('demo:accounts.central_baker.characteristics.shifts_value', '2/día')}
- Modelo: - Franquicia + {t('demo:accounts.central_baker.characteristics.model', 'Modelo')}: + {t('demo:accounts.central_baker.characteristics.model_value', 'Franquicia')}
- Productos: - De obrador + {t('demo:accounts.central_baker.characteristics.products', 'Productos')}: + {t('demo:accounts.central_baker.characteristics.products_value', 'De obrador')}
)} @@ -330,7 +334,7 @@ export const DemoPage: React.FC = () => { {account.features && account.features.length > 0 && (

- Funcionalidades incluidas: + {t('demo:accounts.features_title', 'Funcionalidades incluidas:')}

{account.features.map((feature, idx) => (
@@ -349,7 +353,7 @@ export const DemoPage: React.FC = () => { className="w-full bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] hover:from-[var(--color-primary-dark)] hover:to-[var(--color-primary)] text-white shadow-lg hover:shadow-2xl transform hover:scale-[1.02] transition-all duration-200 font-semibold text-base py-4" > - Iniciar Demo + {t('demo:accounts.start_demo', 'Iniciar Demo')}
@@ -361,13 +365,13 @@ export const DemoPage: React.FC = () => { {/* Footer CTA */}

- ¿Ya tienes una cuenta? + {t('demo:footer.have_account', '¿Ya tienes una cuenta?')}

- Inicia sesión aquí + {t('demo:footer.login_link', 'Inicia sesión aquí')}
@@ -392,12 +396,14 @@ export const DemoPage: React.FC = () => {

- {progressPercentage >= 100 ? '¡Listo! Redirigiendo...' : 'Preparando tu Demo'} + {progressPercentage >= 100 + ? t('demo:loading.ready_title', '¡Listo! Redirigiendo...') + : t('demo:loading.preparing_title', 'Preparando tu Demo')}

{progressPercentage >= 100 - ? 'Tu entorno está listo. Accediendo al dashboard...' - : 'Configurando tu entorno personalizado con datos de muestra...'} + ? t('demo:loading.ready_description', 'Tu entorno está listo. Accediendo al dashboard...') + : t('demo:loading.preparing_description', 'Configurando tu entorno personalizado con datos de muestra...')}

{/* Progress bar */} @@ -412,7 +418,7 @@ export const DemoPage: React.FC = () => { {progressPercentage < 100 && (
- Tiempo estimado: ~{estimatedTime}s + {t('demo:loading.estimated_time', 'Tiempo estimado: ~{{seconds}}s', { seconds: estimatedTime })}
)} @@ -420,7 +426,7 @@ export const DemoPage: React.FC = () => { {progressPercentage < 100 && (

- 💡 Tip: La demo incluye datos reales de panaderías españolas para que puedas explorar todas las funcionalidades + {t('demo:loading.tip', '💡 Tip: La demo incluye datos reales de panaderías españolas para que puedas explorar todas las funcionalidades')}

)} diff --git a/frontend/src/pages/public/FeaturesPage.tsx b/frontend/src/pages/public/FeaturesPage.tsx index dc70127a..fb2950d0 100644 --- a/frontend/src/pages/public/FeaturesPage.tsx +++ b/frontend/src/pages/public/FeaturesPage.tsx @@ -45,7 +45,7 @@ import { } from 'lucide-react'; const FeaturesPage: React.FC = () => { - const { t } = useTranslation(); + const { t } = useTranslation('features'); const navigate = useNavigate(); // Automatic System Timeline Steps @@ -53,66 +53,66 @@ const FeaturesPage: React.FC = () => { { id: 'step1', number: 1, - title: t('features:automatic.step1.title', 'Revisa Todo Tu Inventario'), + title: t('automatic.step1.title', 'Revisa Todo Tu Inventario'), color: 'blue', items: [ - t('features:automatic.step1.item1', 'Cuenta cada kilo de harina, cada litro de leche'), - t('features:automatic.step1.item2', 'Comprueba fechas de caducidad'), - t('features:automatic.step1.item3', 'Ve qué llega hoy de proveedores'), + t('automatic.step1.item1', 'Cuenta cada kilo de harina, cada litro de leche'), + t('automatic.step1.item2', 'Comprueba fechas de caducidad'), + t('automatic.step1.item3', 'Ve qué llega hoy de proveedores'), ], }, { id: 'step2', number: 2, - title: t('features:automatic.step2.title', 'Predice Ventas de Hoy'), + title: t('automatic.step2.title', 'Predice Ventas de Hoy'), color: 'purple', items: [ - t('features:automatic.step2.item1', 'Analiza el día (lunes lluvioso, fiesta local, colegio cerrado)'), - t('features:automatic.step2.item2', 'Compara con días similares del pasado'), - t('features:automatic.step2.item3', 'Te dice: "Hoy venderás 80 croissants, 120 barras, 50 magdalenas"'), + t('automatic.step2.item1', 'Analiza el día (lunes lluvioso, fiesta local, colegio cerrado)'), + t('automatic.step2.item2', 'Compara con días similares del pasado'), + t('automatic.step2.item3', 'Te dice: "Hoy venderás 80 croissants, 120 barras, 50 magdalenas"'), ], }, { id: 'step3', number: 3, - title: t('features:automatic.step3.title', 'Planifica Qué Hacer'), + title: t('automatic.step3.title', 'Planifica Qué Hacer'), color: 'green', items: [ - t('features:automatic.step3.item1', 'Calcula exactamente cuánto hornear'), - t('features:automatic.step3.item2', 'Te da una lista lista para ejecutar'), - t('features:automatic.step3.item3', '"Haz 80 croissants (no 100), usa 5kg mantequilla, 3kg harina..."'), + t('automatic.step3.item1', 'Calcula exactamente cuánto hornear'), + t('automatic.step3.item2', 'Te da una lista lista para ejecutar'), + t('automatic.step3.item3', '"Haz 80 croissants (no 100), usa 5kg mantequilla, 3kg harina..."'), ], }, { id: 'step4', number: 4, - title: t('features:automatic.step4.title', 'Gestiona Inventario Inteligentemente'), + title: t('automatic.step4.title', 'Gestiona Inventario Inteligentemente'), color: 'amber', items: [ - t('features:automatic.step4.projection_title', 'Proyecta 7 días hacia adelante:'), - t('features:automatic.step4.solution', '"Pide 50kg hoy, llega en 3 días, problema resuelto"'), + t('automatic.step4.projection_title', 'Proyecta 7 días hacia adelante:'), + t('automatic.step4.solution', '"Pide 50kg hoy, llega en 3 días, problema resuelto"'), ], }, { id: 'step5', number: 5, - title: t('features:automatic.step5.title', 'Crea Pedidos a Proveedores'), + title: t('automatic.step5.title', 'Crea Pedidos a Proveedores'), color: 'red', items: [ - t('features:automatic.step5.item1', 'Sabe que Proveedor A tarda 3 días, Proveedor B tarda 5'), - t('features:automatic.step5.item2', 'Calcula cuándo pedir para que llegue justo a tiempo'), - t('features:automatic.step5.item3', 'Prepara pedidos listos para aprobar con 1 clic'), + t('automatic.step5.item1', 'Sabe que Proveedor A tarda 3 días, Proveedor B tarda 5'), + t('automatic.step5.item2', 'Calcula cuándo pedir para que llegue justo a tiempo'), + t('automatic.step5.item3', 'Prepara pedidos listos para aprobar con 1 clic'), ], }, { id: 'step6', number: 6, - title: t('features:automatic.step6.title', 'Previene Desperdicios'), + title: t('automatic.step6.title', 'Previene Desperdicios'), color: 'teal', items: [ - t('features:automatic.step6.item1', '"Tienes leche que caduca en 5 días"'), - t('features:automatic.step6.item2', '"Solo usarás 15L en 5 días"'), - t('features:automatic.step6.item3', '"No pidas más de 15L, se desperdiciará"'), + t('automatic.step6.item1', '"Tienes leche que caduca en 5 días"'), + t('automatic.step6.item2', '"Solo usarás 15L en 5 días"'), + t('automatic.step6.item3', '"No pidas más de 15L, se desperdiciará"'), ], }, ]; @@ -121,32 +121,32 @@ const FeaturesPage: React.FC = () => { const tocSections: TOCSection[] = [ { id: 'automatic-system', - label: t('features:toc.automatic', 'Sistema Automático'), + label: t('toc.automatic', 'Sistema Automático'), icon: }, { id: 'local-intelligence', - label: t('features:toc.local', 'Inteligencia Local'), + label: t('toc.local', 'Inteligencia Local'), icon: }, { id: 'demand-forecasting', - label: t('features:toc.forecasting', 'Predicción de Demanda'), + label: t('toc.forecasting', 'Predicción de Demanda'), icon: }, { id: 'waste-reduction', - label: t('features:toc.waste', 'Reducción de Desperdicios'), + label: t('toc.waste', 'Reducción de Desperdicios'), icon: }, { id: 'sustainability', - label: t('features:toc.sustainability', 'Sostenibilidad'), + label: t('toc.sustainability', 'Sostenibilidad'), icon: }, { id: 'business-models', - label: t('features:toc.business', 'Modelos de Negocio'), + label: t('toc.business', 'Modelos de Negocio'), icon: }, ]; @@ -167,7 +167,7 @@ const FeaturesPage: React.FC = () => { {/* Floating CTA */} navigate(getDemoUrl())} icon={} position="bottom-right" @@ -190,10 +190,10 @@ const FeaturesPage: React.FC = () => {

- {t('features:hero.title', 'Cómo Bakery-IA Trabaja Para Ti Cada Día')} + {t('hero.title', 'Cómo Bakery-IA Trabaja Para Ti Cada Día')}

- {t('features:hero.subtitle', 'Todas las funcionalidades explicadas en lenguaje sencillo para dueños de panaderías')} + {t('hero.subtitle', 'Todas las funcionalidades explicadas en lenguaje sencillo para dueños de panaderías')}

@@ -207,13 +207,13 @@ const FeaturesPage: React.FC = () => {
- {t('features:automatic.badge', 'La Funcionalidad Estrella')} + {t('automatic.badge', 'La Funcionalidad Estrella')}

- {t('features:automatic.title', 'Tu Asistente Personal Que Nunca Duerme')} + {t('automatic.title', 'Tu Asistente Personal Que Nunca Duerme')}

- {t('features:automatic.intro', 'Imagina contratar un ayudante súper organizado que llega a las 5:30 AM (antes que tú) y hace todo esto AUTOMÁTICAMENTE:')} + {t('automatic.intro', 'Imagina contratar un ayudante súper organizado que llega a las 5:30 AM (antes que tú) y hace todo esto AUTOMÁTICAMENTE:')}

@@ -233,24 +233,24 @@ const FeaturesPage: React.FC = () => {

- {t('features:automatic.result.title', 'A las 6:00 AM recibes un email:')} + {t('automatic.result.title', 'A las 6:00 AM recibes un email:')}

- {t('features:automatic.result.item1', 'Predicción del día hecha')} + {t('automatic.result.item1', 'Predicción del día hecha')}
- {t('features:automatic.result.item2', 'Plan de producción listo')} + {t('automatic.result.item2', 'Plan de producción listo')}
- {t('features:automatic.result.item3', '3 pedidos creados (aprobar con 1 clic)')} + {t('automatic.result.item3', '3 pedidos creados (aprobar con 1 clic)')}
- {t('features:automatic.result.item4', 'Alerta: "Leche caduca en 2 días, úsala primero"')} + {t('automatic.result.item4', 'Alerta: "Leche caduca en 2 días, úsala primero"')}
@@ -259,32 +259,32 @@ const FeaturesPage: React.FC = () => { {/* What it eliminates */}

- {t('features:automatic.eliminates.title', 'Lo que ELIMINA de tu rutina:')} + {t('automatic.eliminates.title', 'Lo que ELIMINA de tu rutina:')}

- {t('features:automatic.eliminates.item1', 'Adivinar cuánto hacer')} + {t('automatic.eliminates.item1', 'Adivinar cuánto hacer')}
- {t('features:automatic.eliminates.item2', 'Contar inventario manualmente')} + {t('automatic.eliminates.item2', 'Contar inventario manualmente')}
- {t('features:automatic.eliminates.item3', 'Calcular cuándo pedir a proveedores')} + {t('automatic.eliminates.item3', 'Calcular cuándo pedir a proveedores')}
- {t('features:automatic.eliminates.item4', 'Recordar fechas de caducidad')} + {t('automatic.eliminates.item4', 'Recordar fechas de caducidad')}
- {t('features:automatic.eliminates.item5', 'Preocuparte por quedarte sin stock')} + {t('automatic.eliminates.item5', 'Preocuparte por quedarte sin stock')}
- {t('features:automatic.eliminates.item6', 'Desperdiciar ingredientes caducados')} + {t('automatic.eliminates.item6', 'Desperdiciar ingredientes caducados')}
@@ -300,13 +300,13 @@ const FeaturesPage: React.FC = () => {
- {t('features:local.badge', 'Tu Ventaja Competitiva')} + {t('local.badge', 'Tu Ventaja Competitiva')}

- {t('features:local.title', 'Tu Panadería Es Única. La IA También.')} + {t('local.title', 'Tu Panadería Es Única. La IA También.')}

- {t('features:local.intro', 'Las IA genéricas saben que es lunes. La TUYA sabe que:')} + {t('local.intro', 'Las IA genéricas saben que es lunes. La TUYA sabe que:')}

@@ -319,20 +319,20 @@ const FeaturesPage: React.FC = () => {

- {t('features:local.schools.title', 'Colegios Cerca')} + {t('local.schools.title', 'Colegios Cerca')}

  • - {t('features:local.schools.item1', '"El CEIP San José está a 200m"')} + {t('local.schools.item1', '"El CEIP San José está a 200m"')}
  • - {t('features:local.schools.item2', '"En agosto venden 40% menos (vacaciones escolares)"')} + {t('local.schools.item2', '"En agosto venden 40% menos (vacaciones escolares)"')}
  • - {t('features:local.schools.item3', '"Los lunes a las 8:30 hay pico (padres tras dejar niños)"')} + {t('local.schools.item3', '"Los lunes a las 8:30 hay pico (padres tras dejar niños)"')}
@@ -345,20 +345,20 @@ const FeaturesPage: React.FC = () => {

- {t('features:local.offices.title', 'Oficinas y Empresas')} + {t('local.offices.title', 'Oficinas y Empresas')}

  • - {t('features:local.offices.item1', '"Edificio de oficinas a 150m (250 trabajadores)"')} + {t('local.offices.item1', '"Edificio de oficinas a 150m (250 trabajadores)"')}
  • - {t('features:local.offices.item2', '"Viernes venden menos al mediodía (teletrabajo)"')} + {t('local.offices.item2', '"Viernes venden menos al mediodía (teletrabajo)"')}
  • - {t('features:local.offices.item3', '"Hora punta: 13:00-14:00 (bocadillos)"')} + {t('local.offices.item3', '"Hora punta: 13:00-14:00 (bocadillos)"')}
@@ -371,20 +371,20 @@ const FeaturesPage: React.FC = () => {

- {t('features:local.gyms.title', 'Centros Deportivos')} + {t('local.gyms.title', 'Centros Deportivos')}

  • - {t('features:local.gyms.item1', '"Gimnasio a 300m"')} + {t('local.gyms.item1', '"Gimnasio a 300m"')}
  • - {t('features:local.gyms.item2', '"Mayor venta de productos saludables (pan integral, barritas)"')} + {t('local.gyms.item2', '"Mayor venta de productos saludables (pan integral, barritas)"')}
  • - {t('features:local.gyms.item3', '"Pico a las 7:00 AM y 19:00 PM"')} + {t('local.gyms.item3', '"Pico a las 7:00 AM y 19:00 PM"')}
@@ -397,20 +397,20 @@ const FeaturesPage: React.FC = () => {

- {t('features:local.competition.title', 'Tu Competencia')} + {t('local.competition.title', 'Tu Competencia')}

  • - {t('features:local.competition.item1', '"Otra panadería abrió hace 2 meses a 500m"')} + {t('local.competition.item1', '"Otra panadería abrió hace 2 meses a 500m"')}
  • - {t('features:local.competition.item2', '"Impacto: -15% en ventas de pan básico"')} + {t('local.competition.item2', '"Impacto: -15% en ventas de pan básico"')}
  • - {t('features:local.competition.item3', '"Oportunidad: Diferénciate con especialidades"')} + {t('local.competition.item3', '"Oportunidad: Diferénciate con especialidades"')}
@@ -423,20 +423,20 @@ const FeaturesPage: React.FC = () => {

- {t('features:local.weather.title', 'Clima de Tu Zona')} + {t('local.weather.title', 'Clima de Tu Zona')}

  • - {t('features:local.weather.item1', '"Datos AEMET de tu código postal"')} + {t('local.weather.item1', '"Datos AEMET de tu código postal"')}
  • - {t('features:local.weather.item2', '"Lluvia → -20% croissants, +10% pan de molde"')} + {t('local.weather.item2', '"Lluvia → -20% croissants, +10% pan de molde"')}
  • - {t('features:local.weather.item3', '"Calor → +30% productos frescos"')} + {t('local.weather.item3', '"Calor → +30% productos frescos"')}
@@ -449,20 +449,20 @@ const FeaturesPage: React.FC = () => {

- {t('features:local.events.title', 'Eventos Locales')} + {t('local.events.title', 'Eventos Locales')}

  • - {t('features:local.events.item1', '"Mercadillo los viernes en Plaza Mayor (500m)"')} + {t('local.events.item1', '"Mercadillo los viernes en Plaza Mayor (500m)"')}
  • - {t('features:local.events.item2', '"Fiestas del barrio próxima semana"')} + {t('local.events.item2', '"Fiestas del barrio próxima semana"')}
  • - {t('features:local.events.item3', '"Partido importante → pico de ventas pre-evento"')} + {t('local.events.item3', '"Partido importante → pico de ventas pre-evento"')}
@@ -473,16 +473,16 @@ const FeaturesPage: React.FC = () => {

- {t('features:local.why_matters.title', 'Por qué importa:')} + {t('local.why_matters.title', 'Por qué importa:')}

-

{t('features:local.why_matters.generic', 'IA genérica:')}

-

{t('features:local.why_matters.generic_example', '"Es lunes → vende X"')}

+

{t('local.why_matters.generic', 'IA genérica:')}

+

{t('local.why_matters.generic_example', '"Es lunes → vende X"')}

-

{t('features:local.why_matters.yours', 'TU IA:')}

-

{t('features:local.why_matters.yours_example', '"Es lunes, llueve, colegio cerrado (festivo local), mercadillo cancelado → vende Y"')}

+

{t('local.why_matters.yours', 'TU IA:')}

+

{t('local.why_matters.yours_example', '"Es lunes, llueve, colegio cerrado (festivo local), mercadillo cancelado → vende Y"')}

@@ -502,7 +502,7 @@ const FeaturesPage: React.FC = () => { Sabe Cuánto Venderás Mañana ( de Precisión)

- {t('features:forecasting.subtitle', 'No es magia. Es matemáticas con tus datos.')} + {t('forecasting.subtitle', 'No es magia. Es matemáticas con tus datos.')}

@@ -510,59 +510,59 @@ const FeaturesPage: React.FC = () => {

- {t('features:forecasting.learns_from.title', 'La IA aprende de:')} + {t('forecasting.learns_from.title', 'La IA aprende de:')}

- {t('features:forecasting.learns_from.item1', 'Tus ventas pasadas (6-12 meses)')} + {t('forecasting.learns_from.item1', 'Tus ventas pasadas (6-12 meses)')}
- {t('features:forecasting.learns_from.item2', 'Día de la semana (lunes ≠ sábado)')} + {t('forecasting.learns_from.item2', 'Día de la semana (lunes ≠ sábado)')}
- {t('features:forecasting.learns_from.item3', 'Estacionalidad (agosto ≠ diciembre)')} + {t('forecasting.learns_from.item3', 'Estacionalidad (agosto ≠ diciembre)')}
- {t('features:forecasting.learns_from.item4', 'Clima local (lluvia, calor, frío)')} + {t('forecasting.learns_from.item4', 'Clima local (lluvia, calor, frío)')}
- {t('features:forecasting.learns_from.item5', 'Eventos y festivos')} + {t('forecasting.learns_from.item5', 'Eventos y festivos')}
- {t('features:forecasting.learns_from.item6', 'Tu entorno único')} + {t('forecasting.learns_from.item6', 'Tu entorno único')}

- {t('features:forecasting.result.title', 'Resultado:')} + {t('forecasting.result.title', 'Resultado:')}

- {t('features:forecasting.result.intro', 'Mañana (martes 15 de marzo) venderás:')} + {t('forecasting.result.intro', 'Mañana (martes 15 de marzo) venderás:')}

- {t('features:forecasting.result.croissants', '78-82 croissants')} - {t('features:forecasting.result.croissants_avg', '(80 ±2)')} + {t('forecasting.result.croissants', '78-82 croissants')} + {t('forecasting.result.croissants_avg', '(80 ±2)')}
- {t('features:forecasting.result.loaves', '115-125 barras')} - {t('features:forecasting.result.loaves_avg', '(120 ±5)')} + {t('forecasting.result.loaves', '115-125 barras')} + {t('forecasting.result.loaves_avg', '(120 ±5)')}
- {t('features:forecasting.result.muffins', '45-50 magdalenas')} - {t('features:forecasting.result.muffins_avg', '(48 ±2)')} + {t('forecasting.result.muffins', '45-50 magdalenas')} + {t('forecasting.result.muffins_avg', '(48 ±2)')}

- {t('features:forecasting.confidence', 'Confianza: 92% de las veces acierta dentro del rango')} + {t('forecasting.confidence', 'Confianza: 92% de las veces acierta dentro del rango')}

@@ -575,7 +575,7 @@ const FeaturesPage: React.FC = () => {

- {t('features:waste.title', 'Menos Pan en la Basura, Más Dinero en Tu Bolsillo')} + {t('waste.title', 'Menos Pan en la Basura, Más Dinero en Tu Bolsillo')}

@@ -588,14 +588,14 @@ const FeaturesPage: React.FC = () => {

- {t('features:waste.before.title', 'Ejemplo típico de panadería:')} + {t('waste.before.title', 'Ejemplo típico de panadería:')}

    -
  • {t('features:waste.before.item1', 'Haces 50 barras de más cada día "por si acaso"')}
  • -
  • {t('features:waste.before.item2', 'Precio: €2/barra')}
  • -
  • {t('features:waste.before.daily', 'Desperdicio: 50 × €2 = €100/día')}
  • -
  • {t('features:waste.before.monthly', 'Al mes: €100 × 30 = €3,000 perdidos')}
  • -
  • {t('features:waste.before.yearly', 'Al año: €36,000 tirados a la basura')}
  • +
  • {t('waste.before.item1', 'Haces 50 barras de más cada día "por si acaso"')}
  • +
  • {t('waste.before.item2', 'Precio: €2/barra')}
  • +
  • {t('waste.before.daily', 'Desperdicio: 50 × €2 = €100/día')}
  • +
  • {t('waste.before.monthly', 'Al mes: €100 × 30 = €3,000 perdidos')}
  • +
  • {t('waste.before.yearly', 'Al año: €36,000 tirados a la basura')}
@@ -607,18 +607,18 @@ const FeaturesPage: React.FC = () => {

- {t('features:waste.after.title', 'Con Bakery-IA:')} + {t('waste.after.title', 'Con Bakery-IA:')}

    -
  • {t('features:waste.after.item1', 'Predicción precisa → Haces 5-10 barras de más (seguridad)')}
  • -
  • {t('features:waste.after.item2', 'Desperdicio: 5 × €2 = €10/día')}
  • -
  • {t('features:waste.after.monthly', 'Al mes: €300')}
  • +
  • {t('waste.after.item1', 'Predicción precisa → Haces 5-10 barras de más (seguridad)')}
  • +
  • {t('waste.after.item2', 'Desperdicio: 5 × €2 = €10/día')}
  • +
  • {t('waste.after.monthly', 'Al mes: €300')}
  • AHORRO: /mes (/año)

- {t('features:waste.after.roi', 'Recuperas la inversión en semana 1.')} + {t('waste.after.roi', 'Recuperas la inversión en semana 1.')}

@@ -646,10 +646,10 @@ const FeaturesPage: React.FC = () => {
- {t('features:sustainability.badge', 'Funcionalidad del Sistema')} + {t('sustainability.badge', 'Funcionalidad del Sistema')}

- {t('features:sustainability.title', 'Impacto Ambiental y Sostenibilidad')} + {t('sustainability.title', 'Impacto Ambiental y Sostenibilidad')}

@@ -663,14 +663,14 @@ const FeaturesPage: React.FC = () => {

- {t('features:sustainability.un_sdg.title', 'Cumplimiento Automático ODS 12.3 (ONU)')} + {t('sustainability.un_sdg.title', 'Cumplimiento Automático ODS 12.3 (ONU)')}

- {t('features:sustainability.un_sdg.description', 'Sin hacer nada extra, cumples con el Objetivo de Desarrollo Sostenible 12.3 de Naciones Unidas (reducción desperdicio alimentario).')} + {t('sustainability.un_sdg.description', 'Sin hacer nada extra, cumples con el Objetivo de Desarrollo Sostenible 12.3 de Naciones Unidas (reducción desperdicio alimentario).')}

- {t('features:sustainability.un_sdg.benefit', 'Recibes certificación automática → Credibilidad con clientes')} + {t('sustainability.un_sdg.benefit', 'Recibes certificación automática → Credibilidad con clientes')}

@@ -681,7 +681,7 @@ const FeaturesPage: React.FC = () => { {/* Sustainability Benefits */}

- {t('features:sustainability.benefits.title', 'Funcionalidades de Sostenibilidad:')} + {t('sustainability.benefits.title', 'Funcionalidades de Sostenibilidad:')}

@@ -691,10 +691,10 @@ const FeaturesPage: React.FC = () => {

- {t('features:sustainability.benefits.impact_tracking.title', 'Seguimiento de Impacto Ambiental')} + {t('sustainability.benefits.impact_tracking.title', 'Seguimiento de Impacto Ambiental')}

- {t('features:sustainability.benefits.impact_tracking.description', 'Medición automática de CO₂, agua y desperdicio alimentario con métricas detalladas')} + {t('sustainability.benefits.impact_tracking.description', 'Medición automática de CO₂, agua y desperdicio alimentario con métricas detalladas')}

@@ -707,10 +707,10 @@ const FeaturesPage: React.FC = () => {

- {t('features:sustainability.benefits.sdg_compliance.title', 'Cumplimiento ODS 12.3')} + {t('sustainability.benefits.sdg_compliance.title', 'Cumplimiento ODS 12.3')}

- {t('features:sustainability.benefits.sdg_compliance.description', 'Seguimiento automático del cumplimiento de los Objetivos de Desarrollo Sostenible de la ONU')} + {t('sustainability.benefits.sdg_compliance.description', 'Seguimiento automático del cumplimiento de los Objetivos de Desarrollo Sostenible de la ONU')}

@@ -723,10 +723,10 @@ const FeaturesPage: React.FC = () => {

- {t('features:sustainability.benefits.reporting.title', 'Informes de Sostenibilidad')} + {t('sustainability.benefits.reporting.title', 'Informes de Sostenibilidad')}

- {t('features:sustainability.benefits.reporting.description', 'Generación automática de informes listos para auditorías y certificaciones ambientales')} + {t('sustainability.benefits.reporting.description', 'Generación automática de informes listos para auditorías y certificaciones ambientales')}

@@ -739,10 +739,10 @@ const FeaturesPage: React.FC = () => {

- {t('features:sustainability.benefits.certification.title', 'Preparación para Certificaciones')} + {t('sustainability.benefits.certification.title', 'Preparación para Certificaciones')}

- {t('features:sustainability.benefits.certification.description', 'Datos y documentación listos para solicitudes de certificaciones de sostenibilidad')} + {t('sustainability.benefits.certification.description', 'Datos y documentación listos para solicitudes de certificaciones de sostenibilidad')}

@@ -755,10 +755,10 @@ const FeaturesPage: React.FC = () => {

- {t('features:sustainability.benefits.data_export.title', 'Exportación de Datos Ambientales')} + {t('sustainability.benefits.data_export.title', 'Exportación de Datos Ambientales')}

- {t('features:sustainability.benefits.data_export.description', 'Exporta tus métricas de sostenibilidad en formatos estándar para reportes externos y auditorías')} + {t('sustainability.benefits.data_export.description', 'Exporta tus métricas de sostenibilidad en formatos estándar para reportes externos y auditorías')}

@@ -769,24 +769,24 @@ const FeaturesPage: React.FC = () => { {/* How it works */}

- {t('features:sustainability.how_it_works.title', 'Cómo funciona:')} + {t('sustainability.how_it_works.title', 'Cómo funciona:')}

  • - {t('features:sustainability.how_it_works.item1', 'Bakery-IA genera reportes automáticos')} + {t('sustainability.how_it_works.item1', 'Bakery-IA genera reportes automáticos')}
  • - {t('features:sustainability.how_it_works.item2', 'Métricas de reducción de desperdicio (kg CO₂, litros agua)')} + {t('sustainability.how_it_works.item2', 'Métricas de reducción de desperdicio (kg CO₂, litros agua)')}
  • - {t('features:sustainability.how_it_works.item3', 'Documentación lista para solicitudes')} + {t('sustainability.how_it_works.item3', 'Documentación lista para solicitudes')}
  • - {t('features:sustainability.how_it_works.item4', 'Te ayudamos con el proceso')} + {t('sustainability.how_it_works.item4', 'Te ayudamos con el proceso')}
@@ -796,17 +796,17 @@ const FeaturesPage: React.FC = () => {
85kg CO₂
-

{t('features:sustainability.impact.co2', 'reducidos al mes (equivale a 3 árboles plantados)')}

+

{t('sustainability.impact.co2', 'reducidos al mes (equivale a 3 árboles plantados)')}

675,000L
-

{t('features:sustainability.impact.water', 'agua ahorrada al año')}

+

{t('sustainability.impact.water', 'agua ahorrada al año')}

-
{t('features:sustainability.impact.certification', 'Certificado')}
-

{t('features:sustainability.impact.certification_desc', 'ODS 12.3 ONU')}

+
{t('sustainability.impact.certification', 'Certificado')}
+

{t('sustainability.impact.certification_desc', 'ODS 12.3 ONU')}

@@ -817,10 +817,10 @@ const FeaturesPage: React.FC = () => {

- {t('features:business_models.title', 'Para Cualquier Modelo de Negocio')} + {t('business_models.title', 'Para Cualquier Modelo de Negocio')}

- {t('features:business_models.subtitle', 'No importa cómo trabajes, funciona para ti')} + {t('business_models.subtitle', 'No importa cómo trabajes, funciona para ti')}

@@ -830,19 +830,19 @@ const FeaturesPage: React.FC = () => {

- {t('features:business_models.local.title', 'Panadería Producción Local')} + {t('business_models.local.title', 'Panadería Producción Local')}

- {t('features:business_models.local.description', 'Horneas y vendes en el mismo local')} + {t('business_models.local.description', 'Horneas y vendes en el mismo local')}

  • - {t('features:business_models.local.benefit1', 'IA optimiza producción diaria')} + {t('business_models.local.benefit1', 'IA optimiza producción diaria')}
  • - {t('features:business_models.local.benefit2', 'Gestiona inventario de un punto')} + {t('business_models.local.benefit2', 'Gestiona inventario de un punto')}
@@ -852,23 +852,23 @@ const FeaturesPage: React.FC = () => {

- {t('features:business_models.central.title', 'Obrador Central + Puntos de Venta')} + {t('business_models.central.title', 'Obrador Central + Puntos de Venta')}

- {t('features:business_models.central.description', 'Produces en obrador, distribuyes a tiendas')} + {t('business_models.central.description', 'Produces en obrador, distribuyes a tiendas')}

  • - {t('features:business_models.central.benefit1', 'IA predice demanda por punto de venta')} + {t('business_models.central.benefit1', 'IA predice demanda por punto de venta')}
  • - {t('features:business_models.central.benefit2', 'Optimiza distribución y transporte')} + {t('business_models.central.benefit2', 'Optimiza distribución y transporte')}
  • - {t('features:business_models.central.benefit3', 'Gestiona inventario central + puntos')} + {t('business_models.central.benefit3', 'Gestiona inventario central + puntos')}
@@ -880,17 +880,17 @@ const FeaturesPage: React.FC = () => {

- {t('features:cta.title', 'Ver Bakery-IA en Acción')} + {t('cta.title', 'Ver Bakery-IA en Acción')}

- {t('features:cta.subtitle', 'Solicita una demo personalizada para tu panadería')} + {t('cta.subtitle', 'Solicita una demo personalizada para tu panadería')}

diff --git a/frontend/src/styles/components.css b/frontend/src/styles/components.css index 4f62cbcf..19ac8f2b 100644 --- a/frontend/src/styles/components.css +++ b/frontend/src/styles/components.css @@ -2,6 +2,13 @@ * Component styles for reusable UI components */ +/* Fix for no-underline utility - override global a:hover rule */ +.no-underline, +.no-underline:hover, +.no-underline:focus { + text-decoration: none !important; +} + /* Custom Utility Classes for CSS Variables */ /* Background Color Utilities */