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:
@@ -0,0 +1,39 @@
|
||||
---
|
||||
const label = 'Volver arriba';
|
||||
---
|
||||
<button
|
||||
type="button"
|
||||
id="back-to-top"
|
||||
class="fixed bottom-24 right-6 z-30 inline-flex items-center justify-center w-11 h-11 rounded-full text-white shadow-md opacity-0 invisible transition-all"
|
||||
style="background: var(--hds-fg);"
|
||||
aria-label={label}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<polyline points="18 15 12 9 6 15"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<script is:inline>
|
||||
(function() {
|
||||
const btn = document.getElementById('back-to-top');
|
||||
if (!btn) return;
|
||||
let visible = false;
|
||||
function update() {
|
||||
const should = window.scrollY > 400;
|
||||
if (should !== visible) {
|
||||
visible = should;
|
||||
if (should) {
|
||||
btn.classList.remove('opacity-0', 'invisible');
|
||||
btn.classList.add('opacity-100', 'visible');
|
||||
} else {
|
||||
btn.classList.remove('opacity-100', 'visible');
|
||||
btn.classList.add('opacity-0', 'invisible');
|
||||
}
|
||||
}
|
||||
}
|
||||
window.addEventListener('scroll', update, { passive: true });
|
||||
btn.addEventListener('click', () => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user