CleaningService
Sitio demo de servicio profesional de limpieza residencial y empresarial en Colombia. Construido con Astro 7, Svelte 5 y Tailwind CSS 4, con sistema de diseño propio y deploy en Cloudflare Pages.
Stack Tecnológico
Descripción del Proyecto
CleaningService es un sitio demo de una empresa ficticia de servicios profesionales de limpieza residencial y empresarial en Colombia. El proyecto funciona como vitrina de patrones de desarrollo: arquitectura Islands, sistema de diseño con tokens, accesibilidad, SEO técnico y deploy estático en CDN global.
Como demo de diseño y desarrollo, todo el contenido — dirección, teléfono, reseñas, equipo, blog — es placeholder y no corresponde a un negocio real. La página está construida para que la conversión visual de los componentes (hero, cards, pricing, formularios, blog) pueda auditarse sin distracciones de branding real.
Características Principales
- Arquitectura Islands: solo 5 componentes Svelte se hidratan en el cliente (
ContactForm,MobileMenu,Newsletter,PricingTabs,ReviewsCarousel). El resto es HTML estático - Sistema de diseño propio: tokens de marca (verde
#23A653+ azul acento#10A1D2) definidos en@themede Tailwind 4, sintailwind.config.js - Pricing interactivo: toggle mensual/anual con
Intl.NumberFormat("es-CO")para COP y destacado del plan “Más elegido” - Formulario validado: validación client-side en
ContactForm.sveltecon$stateybind:value, manejo de errores por campo, estado de envío y mensaje de éxito - SEO completo: meta tags, Open Graph, Twitter Cards, JSON-LD
LocalBusinesscon dirección, geo, horarios y perfiles sociales - Accesibilidad: ARIA labels,
aria-live,aria-invalid,prefers-reduced-motion,focus-visiblecon outline de marca - Performance:
loading="lazy",fetchpriority="high"en hero, fuentes conpreconnect, animaciones CSS sin JS - Mobile-first: breakpoints consistentes, menú hamburguesa con
client:load, diseño responsive en todas las páginas - Carrusel de reseñas:
ReviewsCarouselcon autoplay y controles - Newsletter doble: formulario inline en footer + bloque dedicado en home
- Blog dinámico: rutas
[slug].astrocon posts tipados ensrc/data/posts.ts
Stack Tecnológico
- Astro 7.1 — framework con
getStaticPaths(), file-based routing y soporte para islands - Svelte 5.56 (Runes) — componentes interactivos con
$state,$derived,$effect - Tailwind CSS 4.3 — utility-first con
@themedirective y CSS-first config - TypeScript 6 — modo
strictconastro/tsconfigs/strict - @astrojs/sitemap — generación automática de sitemap
- Inter (Google Fonts) — tipografía con
preconnectyfont-display: swap
Arquitectura
src/├── components/ # Componentes Astro (estáticos, server-rendered)│ ├── About.astro│ ├── Blog.astro│ ├── Contact.astro│ ├── Footer.astro│ ├── Header.astro│ ├── Hero.astro│ ├── Logo.astro│ ├── PageHero.astro│ ├── Pricing.astro│ ├── Reviews.astro│ ├── Services.astro│ ├── Team.astro│ └── islands/ # Componentes Svelte (interactivos, client-hydrated)│ ├── ContactForm.svelte│ ├── MobileMenu.svelte│ ├── Newsletter.svelte│ ├── PricingTabs.svelte│ └── ReviewsCarousel.svelte├── data/│ └── posts.ts # Posts del blog (hardcoded, tipados)├── layouts/│ └── Layout.astro # SEO, OG, JSON-LD, fuentes├── pages/ # Rutas file-based│ ├── index.astro│ ├── contacto.astro│ ├── equipo.astro│ ├── nosotros.astro│ ├── opiniones.astro│ ├── precios.astro│ ├── servicios.astro│ └── blog/│ ├── index.astro│ └── [slug].astro└── styles/ └── global.css # Design tokens + componentes utilitariosSistema de Diseño
Los tokens viven en src/styles/global.css dentro del bloque @theme:
- Brand — verde
#23A653(CTAs primarios, badges, focus ring). Escala 50-950. - Accent — azul cielo
#10A1D2(contrastes, calificaciones, decorativos). Escala 50-900. - Ink — escala de grises de 50 a 900 para texto y bordes.
- Surface — blancos y fondo muted
#F7F9F8.
Componentes utilitarios disponibles: .btn-primary, .btn-ghost, .btn-outline-light, .card, .eyebrow, .container-x, .section-y, .blob. La escala tipográfica usa clamp() para adaptarse al viewport sin breakpoints intermedios.
Animaciones: float-slow (6s) y pulse-soft (3s), con prefers-reduced-motion desactivando ambas automáticamente.
Componentes Interactivos (Islands)
Solo 5 componentes Svelte se hidratan en el cliente:
ContactForm.svelte — formulario de cotización con validación en tiempo real. Usa $state para name, email, phone, service, message, submitting, submitted, errors. La validación corre client-side antes del envío (placeholder de backend).
MobileMenu.svelte — menú hamburguesa full-screen con animación staggered. Hidratado con client:load para que esté listo inmediatamente al cargar la página.
PricingTabs.svelte — toggle entre planes mensuales y anuales. Usa $state para period y Intl.NumberFormat("es-CO", { currency: "COP" }) para formatear precios en pesos colombianos.
ReviewsCarousel.svelte — carrusel de reseñas con autoplay. Acepta array de reseñas como prop, navega con flechas y dots.
Newsletter.svelte — formulario inline de suscripción. Usado en footer y en bloque dedicado en home. Mismo patrón de validación que ContactForm.
SEO y JSON-LD
El layout principal inyecta metadata completa en cada página:
- Open Graph:
og:type,og:url,og:title,og:description,og:image,og:locale: "es_CO",og:site_name - Twitter Cards:
summary_large_imagecontwitter:url/title/description/image - JSON-LD
LocalBusiness: nombre, imagen, descripción, URL, teléfono,priceRange, dirección postal, geo (4.711, -74.0721), horarios (Monday-Saturday 07:00-19:00) y perfiles sociales - Canonical URL: derivado de
Astro.url.pathname+Astro.site - Sitemap: generado por
@astrojs/sitemapen build
Performance
- Islands Architecture: solo 5 componentes con JS en cliente, el resto es HTML estático
- CSS-first: animaciones de float y pulse definidas en CSS, no en JS
- Lazy loading: todas las imágenes no-críticas usan
loading="lazy"ydecoding="async" - Critical images: el hero usa
fetchpriority="high"yloading="eager" - Fuentes: Inter cargada con
preconnectafonts.googleapis.comyfonts.gstatic.com - Pre-renderizado: todas las páginas pre-renderizadas en build, servidas como activos estáticos
Deploy en Cloudflare Pages
El sitio se despliega como Pages estático:
- Conectar el repo
naujrevilo/cleaning-servicea Cloudflare Pages - Framework preset: Astro
- Build command:
pnpm build - Output directory:
dist - Node version:
22.12+
El CDN global de Cloudflare sirve los assets estáticos con cache edge automático.
Scripts Disponibles
| Comando | Descripción |
|---|---|
pnpm install | Instalar dependencias |
pnpm dev | Servidor de desarrollo (en background según AGENTS.md) |
pnpm build | Build de producción |
pnpm preview | Preview del build localmente |
Nota Demo
Este proyecto es una demo de diseño y desarrollo, no un negocio real:
- La dirección, teléfono y reseñas son placeholder y no corresponden a una empresa existente
- El formulario de contacto no envía datos a ningún backend; simula la petición con
setTimeoutenContactForm.svelte - Los enlaces de redes sociales del footer apuntan a
#como placeholder - Las imágenes son de demostración y deben reemplazarse antes de cualquier uso público
- El blog está hardcodeado en
src/data/posts.ts; para producción conviene migrar a Content Collections o un CMS
Para usar como base de un proyecto real: reemplazar contenido, conectar el formulario a un endpoint (Resend, Formspree o un endpoint de Astro) y optimizar las imágenes con astro:assets.
Versión Actual
✅ v0.1.0 — demo funcional con sistema de diseño completo y todas las páginas navegables
Licencia
MIT
Proyectos Relacionados
Galaxy News
Portal de noticias profesional para periodista independiente, construido con Astro 4, Tailwind CSS 3 y MDX
myNewspaper (The Signal)
Periódico digital demo construido con Astro 7, Svelte 5 y Tailwind CSS 4, con pipeline de noticias automatizado y despliegue en Cloudflare