feat(v3): rediseño con cloud dividers, animaciones scroll reveal, galería stock, página /servicios con 9 planes, 404 gracioso con robot, planos dark mode con todos los planes
- 9 planes de hosting con tabla completa de Mauri (USD/año) - /servicios muestra los 3 servicios a medida + 9 planes categorizados - /planes: 3 destacados + grilla con los 6 restantes - 404 con robot SVG animado tomando mate (pronet.uy + peugeot style) - Cloud dividers SVG entre secciones de la home - Scroll reveal animations (.reveal + .stagger con IntersectionObserver) - Galería de imágenes stock (datacenters, cables, código) en AVIF + WebP + JPG - Sección de testimonios con placeholder honesto (Working on it) - Back-to-top arreglado: ahora usa color naranja + icono blanco, visible en ambos temas - WorldMap con animación SVG de 4 países - Toggle light/dark funcional con anti-flash script - Footer siempre dark con Maldonado, Uruguay - i18n es/en con toggle y contenido bilingüe Tech: Astro 5 + Tailwind v4 + Keystatic + Gitea + lftp
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
---
|
||||
import { monthlyEquivalent, type Plan } from '@/lib/pricing';
|
||||
|
||||
interface Props {
|
||||
plans: Plan[];
|
||||
whatsappUrl: string;
|
||||
}
|
||||
|
||||
const { plans, whatsappUrl } = Astro.props;
|
||||
---
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 lg:gap-8">
|
||||
{plans.map((plan) => (
|
||||
<div
|
||||
class="relative rounded-2xl p-8 transition-all flex flex-col h-full group hover:-translate-y-1"
|
||||
style={plan.recommended
|
||||
? `background: var(--hds-card); border: 2px solid var(--color-hds-naranja); box-shadow: 0 16px 48px rgba(238,118,35,0.18);`
|
||||
: `background: var(--hds-card); border: 1px solid var(--hds-line);`}
|
||||
>
|
||||
{plan.recommended && (
|
||||
<div class="absolute -top-3.5 left-1/2 -translate-x-1/2 text-[11px] font-bold tracking-[0.2em] uppercase px-4 py-1.5 rounded-full whitespace-nowrap" style="background: var(--color-hds-naranja); color: white; box-shadow: 0 4px 16px rgba(238,118,35,0.4);">
|
||||
⭐ Recomendado
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div class="mb-6">
|
||||
<div class="text-xs font-semibold tracking-[0.25em] uppercase mb-3" style={`color: ${plan.recommended ? 'var(--color-hds-naranja)' : 'var(--hds-fg-muted)'};`}>
|
||||
{plan.name}
|
||||
</div>
|
||||
<div class="flex items-baseline gap-1.5">
|
||||
<span class="text-2xl font-semibold" style="color: var(--hds-fg);">USD</span>
|
||||
<span class="font-display leading-none" style="font-size: 4.5rem; color: var(--hds-fg); font-weight: 500; letter-spacing: -0.03em;">{plan.priceUsdYear}</span>
|
||||
</div>
|
||||
<div class="text-sm mt-2" style="color: var(--hds-fg-muted);">
|
||||
por año · ~USD {monthlyEquivalent(plan.priceUsdYear)}/mes
|
||||
</div>
|
||||
<div class="text-xs mt-1.5 inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full" style="background: var(--hds-bg-soft); color: var(--hds-fg-muted);">
|
||||
<span>Técnico: USD {plan.technical}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t pt-6 mb-6 flex-grow" style="border-color: var(--hds-line);">
|
||||
<ul class="space-y-2.5 text-sm" style="color: var(--hds-fg-soft);">
|
||||
{plan.features.slice(0, 6).map((feature) => (
|
||||
<li class="flex items-start gap-2.5">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="flex-shrink-0 mt-0.5" style="color: var(--color-hds-naranja);" aria-hidden="true">
|
||||
<polyline points="20 6 9 17 4 12"/>
|
||||
</svg>
|
||||
<span>{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
{plan.features.length > 6 && (
|
||||
<li class="text-xs italic" style="color: var(--hds-fg-muted);">
|
||||
+ {plan.features.length - 6} características más
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href={`https://wa.me/59899812487?text=${encodeURIComponent(`Hola, me interesa el plan ${plan.name} (USD ${plan.priceUsdYear}/año)`)}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class={plan.recommended ? 'btn-primary justify-center' : 'btn-secondary justify-center'}
|
||||
>
|
||||
Elegir {plan.name}
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
Reference in New Issue
Block a user