feat: sitio hostingdelsur.net v2 con Astro 5, Tailwind v4, soporte light/dark, i18n es/en, Keystatic CMS, reCAPTCHA v3

- Arista Pro Alternate Regular self-hosted (font corporativa)
- Toggle theme con CSS variables y @custom-variant dark
- 6 servicios en 3 categorías (Hosting & Correo / Diseño & Contenido / Infraestructura)
- 3 planes destacados (Básico USD 59, Institucional USD 129, E-commerce USD 219)
- Datacenters en 4 países (Canadá, USA, Alemania, Uruguay) sin ciudades en el sitio
- Sede operativa en Maldonado, Uruguay
- i18n es/en con contenido duplicado en Keystatic
- Endpoint PHP para form de contacto con PHPMailer + reCAPTCHA v3 + honeypot + rate limit
- WorldMap con animación SVG de los 4 países
- 29 páginas generadas, 0 JS por default
- Sitemap auto + robots.txt
- JSON-LD Organization + ProfessionalService con areaServed
This commit is contained in:
Mauri
2026-06-08 22:32:23 -03:00
commit 393f6b0dc3
73 changed files with 15399 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
---
import BaseLayout from '@/layouts/BaseLayout.astro';
import SectionEyebrow from '@/components/SectionEyebrow.astro';
import PricingTiers from '@/components/PricingTiers.astro';
import CtaFinal from '@/components/CtaFinal.astro';
import { PLANS, ADDITIONAL_PLANS, monthlyEquivalent } 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' : '';
---
<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.'}
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">
<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>.
</h1>
<p class="text-lg mt-5 max-w-2xl" style="color: var(--hds-fg-soft);">
{lang === 'en'
? 'Prices in USD, billed annually. Features may vary depending on the project and server configuration.'
: 'Precios en USD, con cobro anual. Las características pueden variar según el proyecto y la configuración del servidor.'}
</p>
</div>
</section>
<section class="py-20 md:py-24" 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="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>
</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>
</div>
</section>
</BaseLayout>