Sitio institucional de SERTRIFIR: emisión y renovación de firma electrónica para persona natural y jurídica en Ecuador, con capacitación gratuita en el facturador del SRI.
Producción: https://socket-studio.com/demo-aplicaciones/sertrifir/
Desarrollado por Socket Studio.
| Pieza | Elección | Por qué |
|---|---|---|
| Build | Vite 5 (MPA de 3 entradas) | Tres documentos HTML independientes; no hace falta un router de cliente. |
| UI | React 18 | Componentes reutilizables sin estado global: no hay servidor detrás. |
| Estilos | Tailwind CSS 3 con tokens propios | La paleta y la escala tipográfica viven en tailwind.config.js. |
| Movimiento | Framer Motion | Solo para los revelados en scroll. El hero no lo usa (ver abajo). |
| Imágenes | sharp en scripts/build-media.mjs |
WebP en varios anchos, recortes declarados en un solo archivo. |
| Tipografías | Autoalojadas y recortadas con pyftsubset |
Cero peticiones a terceros; 180 KB → 55 KB. |
index.html Portada (SEO + JSON-LD: ProfessionalService, WebSite, FAQPage)
privacidad.html Aviso de privacidad (LOPDP)
terminos.html Términos de uso y condiciones del servicio
src/
data/empresa.js Fuente única de verdad: tarifario, servicios, FAQ, contacto
components/ Header, Hero, CostoReal, Precios, Servicios, Nosotros,
Proceso, Faq, Contacto, Footer, LegalLayout, ui
pages/ Privacidad, Terminos
entries/ Puntos de entrada de las páginas legales
scripts/build-media.mjs Recortes WebP + imagen Open Graph
public/ favicon, robots.txt, sitemap.xml, fuentes, foto del hero
scrape/ Originales de las fotos (no se publican)
npm install
npm run dev # servidor de desarrollo
npm run media # regenera WebP e imagen Open Graph desde scrape/
npm run build # build de producción en dist/
npm run preview # sirve dist/ tal como quedará en el servidorEl contenido nunca espera a una animación. Todo lo que está sobre el pliegue —titular, botones, garantías y fotografía— se anima con CSS (animation-fill-mode: both), no con Framer Motion. Una animación de montaje basada en requestAnimationFrame puede quedarse congelada si la pestaña arranca en segundo plano y dejar el contenido invisible de forma permanente; ocurrió durante el desarrollo y por eso el hero se pasó a CSS. Framer Motion se conserva para los revelados en scroll, donde el usuario ya está mirando la página.
El titular es el elemento LCP y arranca en opacidad 1. No se envuelve en ningún revelado. La fotografía del hero se precarga desde el <head> con el mismo srcset que usa el <img>.
Fuentes recortadas. Newsreader se sirve como instancia estática de peso 600 —el único peso que usa el proyecto— en lugar de la variable completa: 132 KB → 20 KB. Inter se recortó al mismo rango latino: 48 KB → 34 KB. El unicode-range declarado coincide con el recorte, de modo que cualquier carácter fuera de él cae en la familia de respaldo.
CSS incrustado en el HTML. Un plugin de Vite en vite.config.js mete la hoja de estilos dentro de cada documento y borra el .css del build: era el único recurso que bloqueaba el primer pintado (~150 ms de LCP en móvil).
El formulario no tiene backend. Compone un mensaje y lo abre en WhatsApp; el visitante conserva el control del envío y el sitio no almacena datos personales. Es la opción que mejor se sostiene frente a la LOPDP para un sitio estático, y así se declara en el aviso de privacidad.
La tabla de precios es una tabla de verdad. <caption>, <th scope> y una sola fuente de contenido para móvil y escritorio; la columna de acción se oculta bajo md y se sustituye por un CTA general en lugar de duplicar el DOM.
- Aviso de privacidad con responsable, datos tratados, finalidades, base de licitud, destinatarios, transferencias internacionales, plazos de conservación, derechos del titular y canal de ejercicio.
- Consentimiento expreso mediante casilla no premarcada antes de enviar el formulario.
- Términos de uso con alcance del servicio, precios, custodia del certificado y límites de responsabilidad.
- Sin cookies de terceros, sin analítica y sin píxeles publicitarios: no se requiere banner de consentimiento y así se declara.
- Tipografías autoalojadas: el navegador del visitante no contacta dominios externos.
- Tarifario, teléfono y correo: flyer oficial de SERTRIFIR entregado por el cliente. Las siete vigencias y sus precios son literales, con IVA incluido.
- Cartera de servicios, tipos de titular, cobertura nacional, devolución de IVA y sanciones del SRI: publicaciones de @sertrifir en Instagram (mayo–octubre de 2024) y de su página de Facebook. Los originales quedan en
scrape/ig/para poder auditar cada dato. - Logotipo: reconstruido en SVG a partir del hexágono del flyer. Ojo: en Instagram circula un logotipo distinto (círculo amarillo con monograma «STF»); antes de dar por buena la reconstrucción hay que decidir cuál es la marca.
- Fotografías: banco de imágenes Pexels (licencia Pexels: uso comercial permitido, sin atribución obligatoria), usadas mientras el cliente no entregue fotografía propia. Los recortes están declarados en
scripts/build-media.mjs: sustituir los archivos descrape/y volver a ejecutarnpm run mediaes todo lo que hace falta para cambiarlas por fotos reales del equipo.
Lighthouse sobre el build de producción (npm run preview), septiembre de 2026:
| Métrica | Móvil | Escritorio |
|---|---|---|
| Rendimiento | 99 | 100 |
| Accesibilidad | 100 | 100 |
| Buenas prácticas | 100 | 100 |
| SEO | 100 | 100 |
| LCP | 2,1 s | 0,6 s |
| CLS | 0 | 0 |
| Peso de la portada | 215 KB | — |
El servidor no tiene CI: git push no publica nada. La publicación es por SSH con la llave ~/.ssh/deploy_socketweb.
npm run build
rsync -az --delete -e "ssh -i ~/.ssh/deploy_socketweb" dist/ \
palma@31.97.102.179:/var/www/html/socket-studio/demo-aplicaciones/sertrifir/- Tres testimonios reales con nombre, actividad y resultado. Hoy no existe ninguno: la página de Facebook tiene una sola opinión, sin calificación.
- Fotografía real del equipo y la oficina, para reemplazar las imágenes de banco.
- Decidir cuál de los dos logotipos es la marca (hexágono del flyer o monograma «STF» de Instagram) y entregar el vectorial.
- Confirmar el RUC, el año de fundación y la entidad de certificación acreditada con la que se emiten los certificados.
- Actualizar o borrar el tarifario antiguo publicado en Instagram (25-10-2024), que lista $20 el año y contradice al sitio.
- Corregir el nombre de la página de Facebook: dice «Servicios de Tribulación» en vez de «Tributación».
- Poner el enlace del sitio en las biografías de Instagram y Facebook, hoy vacías, y retomar la publicación: ambos perfiles llevan más de un año inactivos.