/home/crealab/cntxt.brainware.com.co/cotizador-campestre-v5.html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Configurador Vivienda Campestre - CNTXT®</title>
    
    <!-- React & Tailwind -->
    <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    
    <!-- Librería PDF -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>

    <style>
        /* Tipografía Premium */
        @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@200;300;400;500;600;700&display=swap');

        body { margin: 0; background-color: #000; color: #fff; font-family: 'Manrope', sans-serif; }
        .cursor-wait { cursor: wait; }
        @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
        .animate-fade-in { animation: fadeIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
        
        /* Scrollbar */
        ::-webkit-scrollbar { width: 6px; }
        ::-webkit-scrollbar-track { background: #050505; }
        ::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }
        ::-webkit-scrollbar-thumb:hover { background: #D4AF37; }
        
        /* Checkbox */
        .custom-checkbox:checked + div { border-color: #D4AF37; background-color: #0a0a0a; }
        .custom-checkbox:checked + div .check-icon { opacity: 1; transform: scale(1); }
        .custom-checkbox:checked + div h3 { color: #fff; }
        .custom-checkbox:checked + div .price-tag { color: #D4AF37; }

        /* ESTILOS DEL DOCUMENTO (COTIZACIÓN - OCULTO) */
        .quotation-sheet {
            background-color: #ffffff; /* Fondo blanco para PDF impreso profesional */
            color: #000000;
            width: 100%;
            max-width: 800px;
            margin: 0 auto;
            padding: 50px;
            position: relative;
            /* Oculto en pantalla normal, visible solo para html2pdf */
            position: absolute;
            left: -9999px;
            top: 0;
        }
        
        /* Ajustes Impresión */
        @media print {
            body { background: #fff; color: #000; }
            .quotation-sheet {
                position: static;
                left: 0;
                display: block;
            }
            .no-print { display: none !important; }
        }
    </style>
</head>
<body>
    <div id="root"><div style="display:flex;height:100vh;align-items:center;justify-content:center;color:#333;">Cargando experiencia CNTXT®...</div></div>

    <script type="text/babel">
        const { useState, useEffect, useRef } = React;

        // --- CONFIGURACIÓN ---
        const CLIENT_PORTAL_URL = "/portal-clientes"; // URL a donde se redirige al cliente

        // --- ICONOS ---
        const Icons = {
            Cube: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m21.12 6.4-6.05-4.06a2 2 0 0 0-2.17-.05L2.9 8.12a2 2 0 0 0-.9 1.7v9.58a2 2 0 0 0 1.12 1.83l12.9 4.43a2 2 0 0 0 1.37 0l5.5-2.2a2 2 0 0 0 1.1-1.83V8.12a2 2 0 0 0-.87-1.73ZM12 3v18.75"/></svg>,
            Home: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>,
            Check: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>,
            ChevronRight: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 18 15 12 9 6"/></svg>,
            ArrowLeft: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg>,
            Plus: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>,
            Eye: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>,
            Video: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m22 8-6 4 6 4V8Z"/><rect width="14" height="12" x="2" y="6" rx="2" ry="2"/></svg>,
            Globe: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>,
            Layers: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>,
            Zap: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>,
            Loader: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>,
            Printer: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect width="12" height="8" x="6" y="14"/></svg>,
            Minus: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="12" x2="19" y2="12"/></svg>,
            Copy: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>,
            Download: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>,
            User: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>,
            Lock: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>,
            FileText: (p)=><svg {...p} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
        };

        // --- SERVICIOS ---
        const BASE_PLAN = {
            id: 'esencia_exterior',
            name: 'ESENCIA EXTERIOR',
            tagline: 'Visualización Arquitectónica Integral',
            price: 3200000,
            description: 'Paquete fundamental para entender volumetría y materialidad. Incluye modelado y visualización completa del edificio desde el exterior.',
            features: [
                'V0.1 Modelado arquitectónico sobre planos',
                'V0.3 Modelo 3D de edificios exteriores',
                'V1.2 Pack ilimitado imágenes exteriores',
                'V4.1 Planimetría comercial ambientada'
            ]
        };

        const ADDON_CATEGORIES = [
            {
                name: "Interiorismo",
                items: [
                    { id: 'v0_4', code: 'V0.4', title: 'Modelo Ambientación Interior', price: 1200000, desc: 'Modelado de detalles especiales: Zócalos, cielos, muebles fijos.', icon: <Icons.Home/> },
                    { id: 'v1_3', code: 'V1.3', title: 'Pack Renders Interiores', price: 800000, desc: 'Pack ilimitado de imágenes de interiores con iluminación configurada.', icon: <Icons.Home/> },
                ]
            },
            {
                name: "Video & Animación",
                items: [
                    { id: 'v2_3', code: 'V2.3', title: 'Clip Comercial (40 seg)', price: 1200000, desc: 'Video cinematográfico versión Trailer para redes (720p).', icon: <Icons.Video/> },
                    { id: 'v2_4', code: 'V2.4', title: 'Clip Emocional (1:20 min)', price: 2200000, desc: 'Video versión Trailer extendido cinematográfico (720p).', icon: <Icons.Video/> },
                    { id: 'v2_1', code: 'V2.1', title: 'Video Comercial (2:30 min)', price: 4500000, desc: 'Video 2K con guion y dirección creativa completa.', icon: <Icons.Video/> },
                    { id: 'v2_2', code: 'V2.2', title: 'Video Recorrido Espacial', price: 1800000, desc: 'Recorrido de entendimiento espacial en primera persona.', icon: <Icons.Video/> },
                    { id: 'v2_5', code: 'V2.5', title: 'Escalado 8K (Upgrade)', price: 500000, desc: 'Escalado de videos hasta resolución 8K mediante IA.', icon: <Icons.Zap/> },
                ]
            },
            {
                name: "Interactivo & Inmersivo",
                items: [
                    { id: 'v3_1', code: 'V3.1', title: 'Recorridos 360°', price: 950000, desc: '4 imágenes 360° alojadas en Kuula. Experiencia interactiva.', icon: <Icons.Eye/> },
                    { id: 'v3_2', code: 'V3.2', title: 'Recorrido en Tiempo Real', price: 1500000, desc: 'Servicio en vivo (2 horas) para eventos o lanzamientos.', icon: <Icons.Eye/> },
                    { id: 'v0_5', code: 'V0.5', title: 'Gaussian Splatting', price: 1500000, desc: 'Modelo implantado realista del entorno para plataformas.', icon: <Icons.Layers/> },
                ]
            },
            {
                name: "Web & Comercial",
                items: [
                    { id: 'v5_1', code: 'V5.1', title: 'Web Inmobiliaria Basic', price: 2500000, desc: 'Diseño y montaje web con dominio propio.', icon: <Icons.Globe/> },
                    { id: 'v5_4', code: 'V5.4', title: 'Landing Page Lanzamiento', price: 1800000, desc: 'Plataforma web para lanzamiento comercial (Wix).', icon: <Icons.Globe/> },
                    { id: 'v5_3', code: 'V5.3', title: 'Web Lite (Web3D)', price: 3500000, desc: 'Plataforma web interactiva con integración 3D (Hasta 100 Und).', icon: <Icons.Globe/> },
                    { id: 'v5_5', code: 'V5.5', title: 'Ficha de Lote Web', price: 1200000, desc: 'Link de interfaz con visita a lote y video drone.', icon: <Icons.Globe/> },
                    { id: 'v5_2', code: 'V5.2', title: 'Brochure Digital/Print', price: 850000, desc: 'Diagramación PDF para envío virtual e impresión.', icon: <Icons.Layers/> },
                ]
            }
        ];

        const ALL_ADDONS = ADDON_CATEGORIES.flatMap(cat => cat.items);

        // --- UTILIDADES ---
        const formatCurrency = (val) => new Intl.NumberFormat('es-CO', { style: 'currency', currency: 'COP', minimumFractionDigits: 0 }).format(val);
        const generateOrderId = () => `VC-${Math.floor(10000 + Math.random() * 90000)}-${new Date().getFullYear().toString().substr(-2)}`;
        const generatePassword = () => Math.random().toString(36).slice(-8).toUpperCase();

        // --- COMPONENTES ---
        const ProgressBar = ({ step }) => (
            <div className="w-full h-1 bg-gray-900 sticky top-0 z-50">
                <div className="h-full bg-[#D4AF37] transition-all duration-700 ease-out" style={{ width: `${(step / 3) * 100}%` }}></div>
            </div>
        );

        const BasePlanCard = ({ plan }) => (
            <div className="bg-neutral-900 border border-neutral-800 p-6 md:p-8 flex flex-col md:flex-row gap-8 items-start animate-fade-in relative overflow-hidden">
                <div className="flex-grow z-10">
                    <div className="flex items-center gap-3 mb-3">
                        <Icons.Cube className="text-[#D4AF37] w-5 h-5" />
                        <h4 className="text-[#D4AF37] text-xs uppercase tracking-[0.2em] font-bold">{plan.tagline}</h4>
                    </div>
                    <h2 className="text-3xl md:text-4xl font-light text-white mb-4">{plan.name}</h2>
                    <p className="text-gray-400 font-light mb-8 max-w-xl text-sm leading-relaxed">{plan.description}</p>
                    <div className="grid grid-cols-1 md:grid-cols-2 gap-y-3 gap-x-6">
                        {plan.features.map((feat, i) => (
                            <div key={i} className="flex items-start gap-3">
                                <div className="mt-1.5 w-1.5 h-1.5 rounded-full bg-[#D4AF37] shrink-0"></div>
                                <span className="text-xs text-gray-300 uppercase tracking-wider">{feat}</span>
                            </div>
                        ))}
                    </div>
                </div>
                <div className="w-full md:w-auto min-w-[180px] border-t md:border-t-0 md:border-l border-neutral-800 pt-6 md:pt-0 md:pl-8 text-right flex flex-row md:flex-col justify-between items-center md:items-end z-10">
                    <span className="text-[10px] text-gray-500 uppercase tracking-widest mb-1">Inversión Base (Unitario)</span>
                    <span className="text-3xl font-light text-white">{formatCurrency(plan.price)}</span>
                </div>
            </div>
        );

        const QuantitySelector = ({ quantity, setQuantity }) => (
            <div className="max-w-5xl mx-auto mb-16 animate-fade-in">
                <div className="flex flex-col md:flex-row items-center justify-between bg-black border-y border-neutral-800 py-6 px-4 md:px-0">
                    <div className="flex items-center gap-4 mb-4 md:mb-0">
                        <div className="p-3 bg-neutral-900 rounded-full text-[#D4AF37]">
                            <Icons.Copy className="w-5 h-5" />
                        </div>
                        <div>
                            <h3 className="text-sm font-bold text-white uppercase tracking-widest">Modelos de Vivienda</h3>
                            <p className="text-xs text-gray-500">¿Cuántas tipologías diferentes deseas cotizar?</p>
                        </div>
                    </div>
                    <div className="flex items-center gap-6">
                        <button onClick={() => setQuantity(q => Math.max(1, q - 1))} className="w-10 h-10 flex items-center justify-center border border-neutral-700 hover:border-white text-gray-400 hover:text-white transition-all rounded-sm hover:bg-neutral-900"><Icons.Minus className="w-4 h-4" /></button>
                        <div className="text-center w-12"><span className="text-3xl font-light text-[#D4AF37]">{quantity}</span></div>
                        <button onClick={() => setQuantity(q => q + 1)} className="w-10 h-10 flex items-center justify-center border border-neutral-700 hover:border-white text-gray-400 hover:text-white transition-all rounded-sm hover:bg-neutral-900"><Icons.Plus className="w-4 h-4" /></button>
                    </div>
                </div>
            </div>
        );

        const AddonItem = ({ item, isSelected, onToggle }) => (
            <label className="relative cursor-pointer group animate-fade-in h-full block">
                <input type="checkbox" className="custom-checkbox sr-only" checked={isSelected} onChange={() => onToggle(item.id)}/>
                <div className={`p-5 border transition-all duration-200 h-full flex flex-col justify-between relative ${isSelected ? 'bg-neutral-900 border-[#D4AF37]' : 'bg-black border-neutral-800 hover:border-neutral-700'}`}>
                    <div className="flex justify-between items-start mb-4">
                        <div className="flex items-center gap-2">
                            <span className="text-[10px] text-gray-600 font-mono border border-neutral-800 px-1 rounded">{item.code}</span>
                        </div>
                        <div className={`w-4 h-4 border rounded-[2px] flex items-center justify-center transition-all duration-200 check-icon ${isSelected ? 'bg-[#D4AF37] border-[#D4AF37] opacity-100' : 'border-neutral-700 opacity-20'}`}>
                            <Icons.Check className="w-2.5 h-2.5 text-black" />
                        </div>
                    </div>
                    <div>
                        <div className={`text-gray-500 mb-2 ${isSelected ? 'text-[#D4AF37]' : ''}`}>{item.icon}</div>
                        <h3 className="text-sm font-medium mb-2 text-gray-300 leading-tight group-hover:text-white transition-colors">{item.title}</h3>
                        <p className="text-[10px] text-gray-500 mb-4 leading-relaxed min-h-[30px]">{item.desc}</p>
                        <div className="border-t border-neutral-800 pt-3 mt-auto">
                            <p className="text-xs font-mono text-gray-400 price-tag">+ {formatCurrency(item.price)}</p>
                        </div>
                    </div>
                </div>
            </label>
        );

        // --- DOCUMENTO PDF OCULTO ---
        const HiddenPDFDocument = ({ orderId, formData, quantity, basePrice, selectedAddons, ALL_ADDONS, subtotal, total }) => (
            <div id="quotation-document" className="quotation-sheet">
                {/* Estilos inline para asegurar PDF exacto */}
                <div style={{display: 'flex', justifyContent: 'space-between', borderBottom: '1px solid #ddd', paddingBottom: '30px', marginBottom: '30px'}}>
                    <div>
                        <h1 style={{fontSize: '36px', fontWeight: 'bold', margin: '0', color: '#000'}}>CNTXT®</h1>
                        <p style={{fontSize: '10px', textTransform: 'uppercase', letterSpacing: '3px', color: '#666', margin: '5px 0 0 0'}}>Arquitectura & Visualización</p>
                    </div>
                    <div style={{textAlign: 'right'}}>
                        <h2 style={{fontSize: '24px', fontWeight: '300', color: '#333', margin: '0', textTransform: 'uppercase'}}>Cotización</h2>
                        <p style={{fontSize: '16px', color: '#000', margin: '5px 0 0 0', fontFamily: 'monospace'}}>{orderId}</p>
                        <p style={{fontSize: '12px', color: '#666', margin: '5px 0 0 0'}}>{new Date().toLocaleDateString()}</p>
                    </div>
                </div>

                <div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '40px', marginBottom: '40px'}}>
                    <div>
                        <h4 style={{fontSize: '10px', fontWeight: 'bold', textTransform: 'uppercase', color: '#999', margin: '0 0 10px 0'}}>Cliente</h4>
                        <p style={{fontSize: '16px', fontWeight: 'bold', margin: '0 0 5px 0', color: '#000'}}>{formData.name}</p>
                        <p style={{fontSize: '12px', color: '#333', margin: '0'}}>{formData.email}</p>
                        <p style={{fontSize: '12px', color: '#333', margin: '0'}}>{formData.phone}</p>
                    </div>
                    <div>
                        <h4 style={{fontSize: '10px', fontWeight: 'bold', textTransform: 'uppercase', color: '#999', margin: '0 0 10px 0'}}>Proyecto</h4>
                        <p style={{fontSize: '16px', fontWeight: 'bold', margin: '0 0 5px 0', color: '#000'}}>{formData.projectType || 'Vivienda Campestre'}</p>
                        <p style={{fontSize: '12px', color: '#333', margin: '0 0 5px 0'}}>{formData.location}</p>
                        <p style={{fontSize: '12px', color: '#000', fontWeight: 'bold', margin: '0'}}>{quantity} Modelo(s) de Vivienda</p>
                    </div>
                </div>

                <table style={{width: '100%', borderCollapse: 'collapse', marginBottom: '40px'}}>
                    <thead>
                        <tr style={{borderBottom: '1px solid #eee'}}>
                            <th style={{padding: '10px 0', textAlign: 'left', fontSize: '10px', textTransform: 'uppercase', color: '#999'}}>Descripción</th>
                            <th style={{padding: '10px 0', textAlign: 'right', fontSize: '10px', textTransform: 'uppercase', color: '#999'}}>Cant.</th>
                            <th style={{padding: '10px 0', textAlign: 'right', fontSize: '10px', textTransform: 'uppercase', color: '#999'}}>Unitario</th>
                            <th style={{padding: '10px 0', textAlign: 'right', fontSize: '10px', textTransform: 'uppercase', color: '#999'}}>Total</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr style={{borderBottom: '1px solid #f5f5f5'}}>
                            <td style={{padding: '15px 0'}}>
                                <p style={{fontWeight: 'bold', margin: '0 0 5px 0', fontSize: '14px', color: '#000'}}>{BASE_PLAN.name}</p>
                                <p style={{fontSize: '10px', color: '#666', margin: '0', maxWidth: '400px'}}>{BASE_PLAN.description}</p>
                            </td>
                            <td style={{padding: '15px 0', textAlign: 'right', fontFamily: 'monospace', fontSize: '12px', color: '#333'}}>{quantity}</td>
                            <td style={{padding: '15px 0', textAlign: 'right', fontFamily: 'monospace', fontSize: '12px', color: '#333'}}>{formatCurrency(basePrice)}</td>
                            <td style={{padding: '15px 0', textAlign: 'right', fontFamily: 'monospace', fontSize: '12px', fontWeight: 'bold', color: '#000'}}>{formatCurrency(basePrice * quantity)}</td>
                        </tr>
                        {selectedAddons.map(id => {
                            const item = ALL_ADDONS.find(a => a.id === id);
                            return (
                                <tr key={id} style={{borderBottom: '1px solid #f5f5f5'}}>
                                    <td style={{padding: '12px 0 12px 20px'}}>
                                        <p style={{margin: '0 0 3px 0', fontSize: '12px', color: '#333', fontWeight: '500'}}>+ {item.title}</p>
                                        <p style={{fontSize: '10px', color: '#999', margin: '0'}}>{item.desc}</p>
                                    </td>
                                    <td style={{padding: '12px 0', textAlign: 'right', fontFamily: 'monospace', fontSize: '12px', color: '#666'}}>{quantity}</td>
                                    <td style={{padding: '12px 0', textAlign: 'right', fontFamily: 'monospace', fontSize: '12px', color: '#666'}}>{formatCurrency(item.price)}</td>
                                    <td style={{padding: '12px 0', textAlign: 'right', fontFamily: 'monospace', fontSize: '12px', color: '#333'}}>{formatCurrency(item.price * quantity)}</td>
                                </tr>
                            );
                        })}
                    </tbody>
                </table>

                <div style={{display: 'flex', justifyContent: 'flex-end', marginBottom: '60px'}}>
                    <div style={{width: '250px'}}>
                        <div style={{display: 'flex', justifyContent: 'space-between', padding: '5px 0', fontSize: '12px', color: '#666'}}>
                            <span>Subtotal</span>
                            <span style={{fontFamily: 'monospace'}}>{formatCurrency(subtotal)}</span>
                        </div>
                        <div style={{display: 'flex', justifyContent: 'space-between', padding: '5px 0', fontSize: '12px', color: '#666', borderBottom: '1px solid #eee'}}>
                            <span>IVA (19%)</span>
                            <span style={{fontFamily: 'monospace'}}>{formatCurrency(subtotal * 0.19)}</span>
                        </div>
                        <div style={{display: 'flex', justifyContent: 'space-between', padding: '15px 0', fontSize: '18px', fontWeight: 'bold', color: '#000'}}>
                            <span>Total</span>
                            <span>{formatCurrency(total)}</span>
                        </div>
                    </div>
                </div>

                <div style={{textAlign: 'center', borderTop: '1px solid #eee', paddingTop: '30px'}}>
                    <p style={{fontSize: '10px', textTransform: 'uppercase', letterSpacing: '2px', color: '#999', margin: '0 0 5px 0'}}>Contexto Arquitectura S.A.S</p>
                    <p style={{fontSize: '9px', color: '#aaa', margin: '0'}}>Cotización válida por 15 días. Sujeta a verificación final.</p>
                </div>
            </div>
        );

        // --- APP PRINCIPAL ---
        const App = () => {
            const [step, setStep] = useState(1);
            const [selectedAddons, setSelectedAddons] = useState([]);
            const [quantity, setQuantity] = useState(1);
            const [formData, setFormData] = useState({ name: '', email: '', phone: '', location: '', projectType: '' });
            const [orderId] = useState(generateOrderId());
            const [generatedPassword] = useState(generatePassword());
            const [isGeneratingPDF, setIsGeneratingPDF] = useState(false);

            // Cálculos
            const basePrice = BASE_PLAN.price;
            const addonsPrice = selectedAddons.reduce((sum, id) => {
                const addon = ALL_ADDONS.find(a => a.id === id);
                return sum + (addon ? addon.price : 0);
            }, 0);
            
            const unitSubtotal = basePrice + addonsPrice;
            const subtotal = unitSubtotal * quantity;
            const total = subtotal * 1.19;

            const toggleAddon = (id) => {
                if (selectedAddons.includes(id)) setSelectedAddons(prev => prev.filter(x => x !== id));
                else setSelectedAddons(prev => [...prev, id]);
            };

            const handleInput = (e) => {
                const { name, value } = e.target;
                setFormData(prev => ({ ...prev, [name]: value }));
            };

            const handleDownloadPDF = () => {
                const element = document.getElementById('quotation-document');
                if (!element) return;
                
                setIsGeneratingPDF(true);
                const opt = {
                    margin: 0,
                    filename: `Cotizacion_CNTXT_${orderId}.pdf`,
                    image: { type: 'jpeg', quality: 0.98 },
                    html2canvas: { scale: 2, useCORS: true },
                    jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
                };

                html2pdf().set(opt).from(element).save().then(() => setIsGeneratingPDF(false));
            };

            const handleGoToPortal = () => {
                // Redirigir al portal de clientes
                window.location.href = CLIENT_PORTAL_URL;
            };

            const handleSubmitData = () => {
                setIsGeneratingPDF(true);
                // Simulación de envío al backend para crear usuario
                setTimeout(() => {
                    setStep(3); // Ir al Dashboard
                    setIsGeneratingPDF(false);
                }, 1500);
            };

            return (
                <div className="min-h-screen bg-black text-white selection:bg-[#D4AF37] selection:text-black pb-48 font-light">
                    <ProgressBar step={step} />

                    {/* RENDERIZADO DEL PDF OCULTO SIEMPRE PRESENTE PARA GENERACIÓN */}
                    <HiddenPDFDocument 
                        orderId={orderId} 
                        formData={formData} 
                        quantity={quantity} 
                        basePrice={basePrice} 
                        selectedAddons={selectedAddons} 
                        ALL_ADDONS={ALL_ADDONS} 
                        subtotal={subtotal} 
                        total={total} 
                    />

                    <main className="max-w-7xl mx-auto px-4 py-12 md:py-16">
                        {/* PASO 1: SELECCIÓN */}
                        {step === 1 && (
                            <div className="space-y-12 animate-fade-in">
                                <div className="text-center mb-8">
                                    <span className="text-[#D4AF37] text-[10px] uppercase tracking-[0.3em]">Configurador</span>
                                    <h1 className="text-3xl md:text-5xl font-extralight mt-3 tracking-tight">Vivienda Campestre</h1>
                                </div>

                                <section className="max-w-5xl mx-auto">
                                    <BasePlanCard plan={BASE_PLAN} />
                                </section>

                                <QuantitySelector quantity={quantity} setQuantity={setQuantity} />

                                <section>
                                    <div className="text-center mb-10">
                                        <h3 className="text-sm uppercase tracking-widest text-white mb-2">Personalización Extendida</h3>
                                        <p className="text-xs text-gray-500">Selecciona los servicios complementarios por tipología</p>
                                    </div>
                                    <div className="space-y-12">
                                        {ADDON_CATEGORIES.map((cat, idx) => (
                                            <div key={idx}>
                                                <div className="flex items-center gap-4 mb-6">
                                                    <h4 className="text-xs font-bold text-[#D4AF37] uppercase tracking-widest shrink-0">{cat.name}</h4>
                                                    <div className="h-px bg-neutral-900 flex-grow"></div>
                                                </div>
                                                <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 gap-4">
                                                    {cat.items.map(addon => (
                                                        <AddonItem key={addon.id} item={addon} isSelected={selectedAddons.includes(addon.id)} onToggle={toggleAddon} />
                                                    ))}
                                                </div>
                                            </div>
                                        ))}
                                    </div>
                                    <div className="h-40 md:h-48"></div>
                                </section>

                                <div className="fixed bottom-0 left-0 w-full bg-black/95 backdrop-blur-md border-t border-neutral-800 p-4 md:px-8 z-40 transition-all shadow-2xl">
                                    <div className="max-w-7xl mx-auto flex flex-col md:flex-row justify-between items-center gap-4">
                                        <div className="text-center md:text-left flex items-center gap-6">
                                            <div>
                                                <p className="text-[10px] text-gray-500 uppercase tracking-widest mb-1">Configuración</p>
                                                <span className="text-white font-mono text-sm">{quantity} Modelo{quantity > 1 ? 's' : ''} x ({1 + selectedAddons.length} Servicios)</span>
                                            </div>
                                            <div className="h-8 w-px bg-neutral-800 hidden md:block"></div>
                                            <div>
                                                <p className="text-[10px] text-gray-500 uppercase tracking-widest mb-1">Total Estimado</p>
                                                <div className="text-2xl text-[#D4AF37] font-light">{formatCurrency(total)}</div>
                                            </div>
                                        </div>
                                        <button onClick={() => setStep(2)} className="w-full md:w-auto bg-white hover:bg-gray-200 text-black px-10 py-3 text-xs font-bold uppercase tracking-[0.15em] transition-all flex justify-center items-center gap-3">
                                            Continuar <Icons.ChevronRight className="w-3 h-3" />
                                        </button>
                                    </div>
                                </div>
                            </div>
                        )}

                        {/* PASO 2: DATOS DEL CLIENTE */}
                        {step === 2 && (
                            <div className="max-w-3xl mx-auto animate-fade-in">
                                <button onClick={() => setStep(1)} className="flex items-center gap-2 text-gray-500 hover:text-white mb-10 text-[10px] uppercase tracking-widest transition-colors"><Icons.ArrowLeft className="w-3 h-3" /> Volver a Configuración</button>
                                
                                <div className="border border-neutral-800 bg-neutral-900/50 p-8 md:p-12">
                                    <div className="mb-10 text-center">
                                        <h2 className="text-2xl md:text-3xl font-light text-white mb-2">Crear Cuenta & Cotizar</h2>
                                        <p className="text-gray-500 text-sm font-light">Generaremos tu usuario y documento oficial automáticamente.</p>
                                    </div>
                                    <div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-10">
                                        <div className="col-span-1 md:col-span-2"><label className="block text-[10px] uppercase tracking-widest text-gray-500 mb-2">Nombre Completo</label><input type="text" name="name" onChange={handleInput} className="w-full bg-black border border-neutral-700 p-4 text-white text-sm focus:border-[#D4AF37] outline-none transition-colors placeholder-neutral-700" placeholder="Nombre Apellido" /></div>
                                        <div><label className="block text-[10px] uppercase tracking-widest text-gray-500 mb-2">Email (Será tu usuario)</label><input type="email" name="email" onChange={handleInput} className="w-full bg-black border border-neutral-700 p-4 text-white text-sm focus:border-[#D4AF37] outline-none transition-colors placeholder-neutral-700" placeholder="correo@ejemplo.com" /></div>
                                        <div><label className="block text-[10px] uppercase tracking-widest text-gray-500 mb-2">Teléfono</label><input type="tel" name="phone" onChange={handleInput} className="w-full bg-black border border-neutral-700 p-4 text-white text-sm focus:border-[#D4AF37] outline-none transition-colors placeholder-neutral-700" placeholder="+57 300..." /></div>
                                        <div><label className="block text-[10px] uppercase tracking-widest text-gray-500 mb-2">Ubicación</label><input type="text" name="location" onChange={handleInput} className="w-full bg-black border border-neutral-700 p-4 text-white text-sm focus:border-[#D4AF37] outline-none transition-colors placeholder-neutral-700" placeholder="Ciudad / Municipio" /></div>
                                        <div><label className="block text-[10px] uppercase tracking-widest text-gray-500 mb-2">Área Aprox.</label><input type="text" name="projectType" onChange={handleInput} className="w-full bg-black border border-neutral-700 p-4 text-white text-sm focus:border-[#D4AF37] outline-none transition-colors placeholder-neutral-700" placeholder="Ej: 250 m2" /></div>
                                    </div>
                                    
                                    <button onClick={handleSubmitData} disabled={!formData.email || !formData.name || isGeneratingPDF} className={`w-full py-4 text-xs font-bold uppercase tracking-[0.2em] transition-all flex justify-center items-center gap-2 ${(!formData.email || !formData.name) ? 'bg-neutral-800 text-gray-600 cursor-not-allowed' : 'bg-[#D4AF37] hover:bg-[#b5952f] text-black'}`}>
                                        {isGeneratingPDF ? <><Icons.Loader className="animate-spin w-4 h-4"/> Procesando...</> : "Finalizar & Crear Cuenta"}
                                    </button>
                                    <p className="text-[10px] text-gray-600 text-center mt-4">Al continuar, aceptas recibir tus credenciales de acceso al correo ingresado.</p>
                                </div>
                            </div>
                        )}

                        {/* PASO 3: DASHBOARD CLIENTE (NUEVO) */}
                        {step === 3 && (
                            <div className="animate-fade-in">
                                {/* HEADER DASHBOARD */}
                                <div className="flex flex-col md:flex-row justify-between items-end border-b border-neutral-800 pb-6 mb-10">
                                    <div>
                                        <div className="flex items-center gap-2 mb-1">
                                            <div className="w-2 h-2 rounded-full bg-green-500"></div>
                                            <p className="text-[10px] uppercase tracking-[0.2em] text-gray-400">Cuenta Creada</p>
                                        </div>
                                        <h2 className="text-3xl font-light text-white">Hola, {formData.name.split(' ')[0]}</h2>
                                    </div>
                                    <div className="text-right mt-4 md:mt-0">
                                        <p className="text-[10px] text-gray-500 uppercase tracking-widest">Tus Credenciales han sido enviadas a:</p>
                                        <p className="text-sm text-[#D4AF37] font-mono">{formData.email}</p>
                                        <p className="text-[10px] text-gray-600 mt-1">Contraseña temporal: <span className="text-white">********</span></p>
                                    </div>
                                </div>

                                {/* SECCIÓN COTIZACIÓN ACTUAL */}
                                <div className="bg-neutral-900 border border-neutral-800 p-8 mb-12">
                                    <div className="flex justify-between items-start mb-6">
                                        <div>
                                            <h3 className="text-lg font-medium text-white mb-1">Cotización Reciente</h3>
                                            <p className="text-xs text-gray-500 font-mono">{orderId} • {new Date().toLocaleDateString()}</p>
                                        </div>
                                        <div className="bg-black/50 px-4 py-2 rounded border border-neutral-800">
                                            <p className="text-[10px] text-gray-500 uppercase tracking-widest text-center">Estado</p>
                                            <p className="text-xs text-[#D4AF37] font-bold uppercase">Pendiente Firma</p>
                                        </div>
                                    </div>

                                    <div className="flex flex-col md:flex-row gap-8 items-center bg-black p-6 border border-neutral-800 mb-8">
                                        <div className="flex-grow">
                                            <p className="text-sm text-gray-300 font-medium mb-1">Vivienda Campestre - {quantity} Modelo(s)</p>
                                            <p className="text-xs text-gray-500">Incluye: {BASE_PLAN.name} + {selectedAddons.length} Adicionales</p>
                                        </div>
                                        <div className="text-right">
                                            <p className="text-xs text-gray-500 uppercase tracking-widest">Valor Total</p>
                                            <p className="text-xl font-light text-white">{formatCurrency(total)}</p>
                                        </div>
                                    </div>

                                    {/* ACCIONES DEL DASHBOARD */}
                                    <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                        <button onClick={handleDownloadPDF} className="py-4 px-6 border border-neutral-700 hover:border-white text-gray-300 hover:text-white transition-all flex justify-center items-center gap-3 uppercase text-xs tracking-widest font-bold">
                                            <Icons.Download className="w-4 h-4"/> Descargar PDF
                                        </button>
                                        <button onClick={handleGoToPortal} className="py-4 px-6 bg-[#D4AF37] hover:bg-[#b5952f] text-black transition-all flex justify-center items-center gap-3 uppercase text-xs tracking-widest font-bold shadow-lg shadow-[#D4AF37]/20">
                                            Continuar al Portal de Clientes <Icons.ChevronRight className="w-4 h-4"/>
                                        </button>
                                    </div>
                                </div>

                                {/* HISTORIAL (SIMULADO) */}
                                <div>
                                    <h4 className="text-xs text-gray-500 uppercase tracking-widest mb-4 border-b border-neutral-800 pb-2">Historial de Documentos</h4>
                                    <div className="opacity-50 pointer-events-none">
                                        <div className="flex justify-between items-center py-4 border-b border-neutral-900">
                                            <div className="flex items-center gap-3">
                                                <div className="p-2 bg-neutral-800 rounded"><Icons.FileText className="w-4 h-4 text-gray-500"/></div>
                                                <div>
                                                    <p className="text-xs text-gray-400">Cotización Anterior</p>
                                                    <p className="text-[10px] text-gray-600">No hay documentos previos</p>
                                                </div>
                                            </div>
                                            <span className="text-[10px] text-gray-700">--/--/----</span>
                                        </div>
                                    </div>
                                </div>
                                
                                <div className="h-20"></div>
                            </div>
                        )}
                    </main>
                </div>
            );
        };

        const root = ReactDOM.createRoot(document.getElementById('root'));
        root.render(<App />);
    </script>
</body>
</html>