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:
Mauri
2026-06-08 23:27:55 -03:00
parent 393f6b0dc3
commit 79fc763025
38 changed files with 1069 additions and 113 deletions
+50 -30
View File
@@ -1,25 +1,31 @@
---
import BaseLayout from '@/layouts/BaseLayout.astro';
import SectionEyebrow from '@/components/SectionEyebrow.astro';
import PricingTiers from '@/components/PricingTiers.astro';
import PricingTiersFeatured from '@/components/PricingTiersFeatured.astro';
import PricingGrid from '@/components/PricingGrid.astro';
import CloudDivider from '@/components/CloudDivider.astro';
import CtaFinal from '@/components/CtaFinal.astro';
import { PLANS, ADDITIONAL_PLANS, monthlyEquivalent } from '@/lib/pricing';
import { PLANS, getFeaturedPlans, getOtherPlans, ADDITIONAL_PLANS } from '@/lib/pricing';
import { getLangFromUrl, useTranslations } from '@/i18n/utils';
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
const whatsappUrl = 'https://wa.me/59899812487';
const base = lang === 'en' ? '/en' : '';
const featured = getFeaturedPlans();
const other = getOtherPlans();
---
<BaseLayout
title={lang === 'en' ? 'Hosting plans' : 'Planes de hosting'}
description={lang === 'en'
? 'Hosting plans in USD, billed annually. Basic, Institutional and E-commerce tiers with optional WordPress, Advanced and Corporate plans.'
: 'Planes de hosting en USD, con cobro anual. Básico, Institucional y E-commerce, más planes opcionales WordPress, Avanzado y Corporativo.'}
? 'Hosting plans in USD, billed annually. From basic to corporate HD, choose the plan that fits your project.'
: 'Planes de hosting en USD, con cobro anual. Desde básico hasta corporativo HD, elegí el plan que se adapta a tu proyecto.'}
lang={lang}
>
<section class="pt-20 pb-12 md:pt-28 md:pb-16" style="background: var(--hds-bg-soft);">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<section class="pt-20 pb-12 md:pt-28 md:pb-16 relative" style="background: var(--hds-bg-soft);">
<div class="absolute inset-0 particle-grid opacity-60" aria-hidden="true"></div>
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<SectionEyebrow text={lang === 'en' ? 'Hosting plans' : 'Planes de hosting'} />
<h1 class="font-display leading-tight mt-5" style="font-size: clamp(2.5rem, 6vw, 4.5rem); color: var(--hds-fg);">
Elegí el plan que se<br/>adapta a tu <span style="color: var(--color-hds-naranja); font-style: italic;">proyecto</span>.
@@ -32,37 +38,51 @@ const base = lang === 'en' ? '/en' : '';
</div>
</section>
<section class="py-20 md:py-24" style="background: var(--hds-bg);">
<CloudDivider fillClass="fill-hds-bg" />
<section class="py-16 md:py-20" style="background: var(--hds-bg);">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<PricingTiers
plans={PLANS}
whatsappUrl={whatsappUrl}
/>
<div class="text-center mb-12">
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold tracking-[0.2em] uppercase" style="background: var(--hds-bg-soft); color: var(--color-hds-naranja);">
{lang === 'en' ? 'Most popular' : 'Más elegidos'}
</span>
<h2 class="font-display mt-4" style="font-size: clamp(1.75rem, 4vw, 2.5rem); color: var(--hds-fg);">
{lang === 'en' ? 'Featured plans' : 'Planes destacados'}
</h2>
</div>
<PricingTiersFeatured plans={featured} whatsappUrl={whatsappUrl} />
<div class="mt-10 text-center text-sm space-y-1" style="color: var(--hds-fg-muted);">
<p>⚠️ {lang === 'en'
? 'Prices are in US Dollars (USD). Billed annually.'
: 'Los precios están expresados en dólares estadounidenses (USD). El cobro es anual.'}</p>
<p>{lang === 'en'
? 'Features may vary based on project and server configuration.'
: 'Las características pueden variar según el proyecto y la configuración del servidor.'}</p>
<p>⚠️ {lang === 'en' ? 'Prices are in US Dollars (USD). Billed annually.' : 'Los precios están expresados en dólares estadounidenses (USD). El cobro es anual.'}</p>
<p>{lang === 'en' ? 'Features may vary based on project and server configuration.' : 'Las características pueden variar según el proyecto y la configuración del servidor.'}</p>
</div>
</div>
</section>
<section class="py-20" style="background: var(--hds-bg-soft);">
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 class="font-display mb-4" style="font-size: clamp(1.75rem, 4vw, 2.5rem); color: var(--hds-fg);">
{lang === 'en' ? 'Need a different plan?' : '¿Necesitás otro plan?'}
</h2>
<p class="text-lg mb-8" style="color: var(--hds-fg-soft);">
{lang === 'en' ? 'We also have ' : 'También tenemos '}
<strong>{ADDITIONAL_PLANS.join(', ')}</strong>.
{lang === 'en' ? ' Tell us about your project and we will tailor a plan to you.' : ' Charlá con nosotros y te armamos un plan a medida.'}
</p>
<a href={whatsappUrl} target="_blank" rel="noopener noreferrer" class="btn-primary">
{lang === 'en' ? 'Chat on WhatsApp' : 'Hablar por WhatsApp'}
</a>
<CloudDivider fillClass="fill-hds-bg-soft" flip={true} />
<section class="py-20 md:py-24" style="background: var(--hds-bg-soft);">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-12">
<span class="inline-block px-3 py-1 rounded-full text-xs font-semibold tracking-[0.2em] uppercase" style="background: var(--hds-bg); color: var(--hds-fg-soft);">
{lang === 'en' ? 'Complete catalog' : 'Catálogo completo'}
</span>
<h2 class="font-display mt-4" style="font-size: clamp(1.75rem, 4vw, 2.5rem); color: var(--hds-fg);">
{lang === 'en' ? 'All 9 plans' : 'Los 9 planes'}
</h2>
<p class="mt-3 max-w-2xl mx-auto" style="color: var(--hds-fg-soft);">
{lang === 'en' ? 'From basic personal hosting to corporate HD with everything. Find the one that fits.' : 'Desde el hosting personal básico hasta corporativo HD con todo incluido. Encontrá el que mejor se ajusta.'}
</p>
</div>
<PricingGrid plans={other} whatsappUrl={whatsappUrl} />
<div class="mt-16 text-center">
<p class="text-sm" style="color: var(--hds-fg-muted);">
{lang === 'en' ? 'Need a custom plan?' : '¿Necesitás un plan a medida?'} <a href={whatsappUrl} target="_blank" rel="noopener noreferrer" class="font-semibold" style="color: var(--color-hds-naranja);">{lang === 'en' ? 'Chat with us' : 'Charla con nosotros'}</a>
</p>
</div>
</div>
</section>
</BaseLayout>