style: reskin NovaSpark en las 7 apps

Del look editorial (verde #1B4332, esquinas a 0, botones en mayusculas)
al sistema NovaSpark: primario azul #2563EB, detalle naranja #F97316,
fondo #F8FAFC con tarjetas blancas rounded-xl + shadow-sm, chips
rounded-full semanticos, focus ring azul, transiciones 100-200ms.
Incluye headers de tabla en los PDFs (cotizador y estado de cuenta).
This commit is contained in:
2026-09-03 02:35:34 +00:00
parent 89fcd1c579
commit 599dce2629
78 changed files with 842 additions and 828 deletions

View File

@@ -20,14 +20,14 @@ export default function CoacreditadoForm({ valores, onAnterior, onSiguiente }: P
return (
<FormProvider {...metodos}>
<form onSubmit={metodos.handleSubmit(onSiguiente)} noValidate>
<label htmlFor="tieneCoacreditado" className="flex items-center gap-3 border border-neutral-200 bg-white p-6">
<label htmlFor="tieneCoacreditado" className="flex items-center gap-3 rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-sm">
<input
id="tieneCoacreditado"
type="checkbox"
className="h-5 w-5 accent-accent"
{...metodos.register('tieneCoacreditado')}
/>
<span className="text-xs font-bold uppercase tracking-widest text-neutral-900">¿Hay co-acreditado o cónyuge?</span>
<span className="text-sm font-medium text-[#111827]">¿Hay co-acreditado o cónyuge?</span>
</label>
{tieneCoacreditado && (

View File

@@ -29,7 +29,7 @@ export default function DatosGeneralesCampos({ prefix, compacto = false }: Props
<CampoTexto nombre={p('nivelEstudios')} etiqueta="Nivel de estudios" />
<CampoTexto nombre={p('curp')} etiqueta="CURP" requerido={!compacto} placeholder="XXXX000000XXXXXXX0" />
{advertenciasCurp.length > 0 && (
<div role="alert" className="border border-amber-300 bg-amber-50 px-4 py-3 sm:col-span-2">
<div role="alert" className="rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 sm:col-span-2">
{advertenciasCurp.map((aviso) => (
<p key={aviso} className="text-xs text-amber-700">
{aviso}

View File

@@ -22,25 +22,25 @@ export default function EconomicosCampos({ prefix }: Props) {
<CampoNumero nombre={p('ingresosMensuales')} etiqueta="Ingresos mensuales" />
<CampoNumero nombre={p('otrosIngresos')} etiqueta="Otros ingresos" />
<label htmlFor={`${prefix}totalIngresos`} className="block">
<span className="mb-1 block text-xs font-bold uppercase tracking-widest text-neutral-500">Total ingresos</span>
<span className="mb-1 block text-xs font-medium text-[#4B5563]">Total ingresos</span>
<input
id={`${prefix}totalIngresos`}
type="text"
readOnly
value={formatoMoneda(ingresosMensuales + otrosIngresos)}
className="w-full border border-neutral-200 bg-neutral-50 px-3 py-2.5 text-sm font-bold text-neutral-900"
className="w-full rounded-lg border border-[#E5E7EB] bg-[#F8FAFC] px-3 py-2.5 text-sm font-semibold text-[#111827]"
/>
</label>
<CampoNumero nombre={p('gastosLuz')} etiqueta="Gastos luz" />
<CampoNumero nombre={p('gastosOtros')} etiqueta="Otros gastos" />
<label htmlFor={`${prefix}gastosTotal`} className="block">
<span className="mb-1 block text-xs font-bold uppercase tracking-widest text-neutral-500">Gastos total</span>
<span className="mb-1 block text-xs font-medium text-[#4B5563]">Gastos total</span>
<input
id={`${prefix}gastosTotal`}
type="text"
readOnly
value={formatoMoneda(gastosLuz + gastosOtros)}
className="w-full border border-neutral-200 bg-neutral-50 px-3 py-2.5 text-sm font-bold text-neutral-900"
className="w-full rounded-lg border border-[#E5E7EB] bg-[#F8FAFC] px-3 py-2.5 text-sm font-semibold text-[#111827]"
/>
</label>
<CampoTexto nombre={p('dependientes.personas')} etiqueta="Dependientes económicos (personas)" />

View File

@@ -66,42 +66,42 @@ export default function FirmasForm({ alta, onCambiarFirma, onAnterior }: Props)
<SectionCard titulo="Resumen del alta">
<dl className="grid grid-cols-2 gap-x-6 gap-y-4 text-sm sm:col-span-2 lg:col-span-3 lg:grid-cols-3">
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">Cliente</dt>
<dd className="mt-1 font-light text-neutral-900">{g.nombreCompleto}</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">Cliente</dt>
<dd className="mt-1 text-[#111827]">{g.nombreCompleto}</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">CURP</dt>
<dd className="mt-1 font-light text-neutral-900">{g.curp}</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">CURP</dt>
<dd className="mt-1 text-[#111827]">{g.curp}</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">RFC</dt>
<dd className="mt-1 font-light text-neutral-900">{g.rfc}</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">RFC</dt>
<dd className="mt-1 text-[#111827]">{g.rfc}</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">Proyecto</dt>
<dd className="mt-1 font-light text-neutral-900">{proyecto || '—'}</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">Proyecto</dt>
<dd className="mt-1 text-[#111827]">{proyecto || '—'}</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">Ubicación / Modelo</dt>
<dd className="mt-1 font-light text-neutral-900">
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">Ubicación / Modelo</dt>
<dd className="mt-1 text-[#111827]">
{v.ubicacion || '—'} {v.modelo}
</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">Valor venta</dt>
<dd className="mt-1 font-light text-neutral-900">{formatoMoneda(Number(v.valorVenta) || 0)}</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">Valor venta</dt>
<dd className="mt-1 text-[#111827]">{formatoMoneda(Number(v.valorVenta) || 0)}</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">Total ingresos</dt>
<dd className="mt-1 font-light text-neutral-900">{formatoMoneda(calcularTotalIngresos(economicos))}</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">Total ingresos</dt>
<dd className="mt-1 text-[#111827]">{formatoMoneda(calcularTotalIngresos(economicos))}</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">Fecha</dt>
<dd className="mt-1 font-light text-neutral-900">{formatoFechaCorta(g.fecha)}</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">Fecha</dt>
<dd className="mt-1 text-[#111827]">{formatoFechaCorta(g.fecha)}</dd>
</div>
<div>
<dt className="text-xs font-bold uppercase tracking-widest text-neutral-500">Documentos</dt>
<dd className="mt-1 font-light text-neutral-900">{alta.documentos.length} de 5</dd>
<dt className="text-xs font-semibold uppercase tracking-wider text-[#64748B]">Documentos</dt>
<dd className="mt-1 text-[#111827]">{alta.documentos.length} de 5</dd>
</div>
</dl>
</SectionCard>
@@ -113,7 +113,7 @@ export default function FirmasForm({ alta, onCambiarFirma, onAnterior }: Props)
<SignaturePad onFirma={(dataUrl) => onCambiarFirma({ ...firma, firmaDataUrl: dataUrl })} />
</div>
<label htmlFor="asesorNombre" className="block">
<span className="mb-1 block text-xs font-bold uppercase tracking-widest text-neutral-500">
<span className="mb-1 block text-xs font-semibold uppercase tracking-wider text-[#64748B]">
Nombre del asesor <span className="text-red-700">*</span>
</span>
<input
@@ -121,7 +121,7 @@ export default function FirmasForm({ alta, onCambiarFirma, onAnterior }: Props)
type="text"
value={firma.asesorNombre}
onChange={(e) => onCambiarFirma({ ...firma, asesorNombre: e.target.value.toUpperCase() })}
className="w-full border border-neutral-300 bg-white px-3 py-2.5 text-sm uppercase transition-colors duration-150 focus:border-neutral-900 focus:outline-none"
className="w-full rounded-lg border border-[#D1D5DB] bg-white px-3 py-2.5 text-sm uppercase transition-colors focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/20"
/>
</label>
</SectionCard>
@@ -132,7 +132,7 @@ export default function FirmasForm({ alta, onCambiarFirma, onAnterior }: Props)
{avisoExpediente && (
<p
role="alert"
className="border border-amber-300 bg-amber-50 px-4 py-3 text-xs text-amber-700 sm:col-span-2 lg:col-span-3"
className="rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-xs text-amber-700 sm:col-span-2 lg:col-span-3"
>
{avisoExpediente}
</p>
@@ -143,7 +143,7 @@ export default function FirmasForm({ alta, onCambiarFirma, onAnterior }: Props)
key={g3.tipo}
type="button"
onClick={() => generar(g3.descargar)}
className="border border-neutral-900 bg-transparent px-5 py-2.5 text-xs font-bold uppercase tracking-widest text-neutral-900 transition-colors duration-150 hover:bg-neutral-900 hover:text-white"
className="rounded-lg border border-[#D1D5DB] bg-white px-5 py-2.5 text-sm font-medium text-[#374151] shadow-sm transition-all duration-100 ease-out hover:bg-[#F9FAFB]"
>
{g3.tipo}
</button>
@@ -151,7 +151,7 @@ export default function FirmasForm({ alta, onCambiarFirma, onAnterior }: Props)
<button
type="button"
onClick={generarTodos}
className="bg-accent px-5 py-2.5 text-xs font-bold uppercase tracking-widest text-white transition-colors duration-150 hover:bg-neutral-900 disabled:opacity-40"
className="rounded-lg bg-accent px-5 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-100 ease-out hover:bg-accent-hover disabled:opacity-40"
>
Generar todos
</button>
@@ -162,7 +162,7 @@ export default function FirmasForm({ alta, onCambiarFirma, onAnterior }: Props)
<button
type="button"
onClick={onAnterior}
className="border border-neutral-900 bg-transparent px-5 py-2.5 text-xs font-bold uppercase tracking-widest text-neutral-900 transition-colors duration-150 hover:bg-neutral-900 hover:text-white"
className="rounded-lg border border-[#D1D5DB] bg-white px-5 py-2.5 text-sm font-medium text-[#374151] shadow-sm transition-all duration-100 ease-out hover:bg-[#F9FAFB]"
>
Anterior
</button>

View File

@@ -13,7 +13,7 @@ export default function Navegacion({ onAnterior, onSiguiente, textoSiguiente = '
<button
type="button"
onClick={onAnterior}
className="border border-neutral-900 bg-transparent px-5 py-2.5 text-xs font-bold uppercase tracking-widest text-neutral-900 transition-colors duration-150 hover:bg-neutral-900 hover:text-white"
className="rounded-lg border border-[#D1D5DB] bg-white px-5 py-2.5 text-sm font-medium text-[#374151] shadow-sm transition-all duration-100 ease-out hover:bg-[#F9FAFB]"
>
Anterior
</button>
@@ -23,7 +23,7 @@ export default function Navegacion({ onAnterior, onSiguiente, textoSiguiente = '
<button
type={onSiguiente ? 'button' : 'submit'}
onClick={onSiguiente}
className="bg-accent px-5 py-2.5 text-xs font-bold uppercase tracking-widest text-white transition-colors duration-150 hover:bg-neutral-900 disabled:opacity-40"
className="rounded-lg bg-accent px-5 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-100 ease-out hover:bg-accent-hover disabled:opacity-40"
>
{textoSiguiente}
</button>

View File

@@ -31,8 +31,8 @@ export default function ReferenciasForm({ valores, onAnterior, onSiguiente }: Pa
descripcion="Captura al menos 1 referencia con nombre y teléfono."
>
{[0, 1, 2, 3].map((i) => (
<div key={i} className="border border-neutral-200 p-6">
<p className="mb-4 text-xs font-bold uppercase tracking-widest text-neutral-500">Referencia {i + 1}</p>
<div key={i} className="rounded-xl border border-[#E5E7EB] p-6">
<p className="mb-4 text-xs font-semibold uppercase tracking-wider text-[#64748B]">Referencia {i + 1}</p>
<div className="space-y-3">
<CampoTexto nombre={`referencias.${i}.nombre`} etiqueta="Nombre completo" />
<CampoTexto nombre={`referencias.${i}.telefono`} etiqueta="Teléfono" />

View File

@@ -80,10 +80,10 @@ export default function ViviendaCreditoForm({ valores, onAnterior, onSiguiente }
<label
key={tc.valor}
htmlFor={`tipoCredito-${tc.valor}`}
className={`cursor-pointer border px-3 py-1.5 text-xs font-bold uppercase tracking-wider transition-colors duration-150 ${
className={`cursor-pointer rounded-full border px-3 py-1.5 text-xs font-medium transition-all duration-100 ease-out ${
tiposSeleccionados.includes(tc.valor)
? 'border-accent bg-accent text-white'
: 'border-neutral-300 bg-white text-neutral-600 hover:border-neutral-900'
? 'border-accent bg-accent text-white shadow-sm'
: 'border-[#D1D5DB] bg-white text-[#4B5563] hover:border-accent hover:text-accent'
}`}
>
<input