BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
스포츠 학원 관리 소프트웨어, 학생·수업 일정·권한·소통을 한 패널에서
Software de gestión para academias deportivas: alumnos, calendario de clases, bonos y comunicación en un solo panel. Nacido en una academia de fútbol real, en producción desde el primer día.
스포츠·피트니스JavaScript · HTMLGitHub @MallenK온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Landing page de conversión para Mallen'k Academy Software: la plataforma de gestión nacida en una escuela de tecnificación de fútbol (Barcelona) y ahora abierta a otras academias. Next.js 16 (App Router) + TypeScript + Tailwind CSS v4 + shadcn/ui + Motion (motion.dev) + anime.js.README 전문 보기 ↗
Landing page de conversión para Mallen'k Academy Software: la plataforma de gestión nacida en una escuela de tecnificación de fútbol (Barcelona) y ahora abierta a otras academias. Next.js 16 (App Router) + TypeScript + Tailwind CSS v4 + shadcn/ui + Motion (motion.dev) + anime.js.
Demo en vivo del producto real: https://plataforma-jp-1.onrender.com/
src/app/globals.css, sin tailwind.config.js)Accordion, Button, Badge, Separator)next/og (ImageResponse) para generar favicon, apple-icon y las imágenes Open Graph/Twitter sin ningún diseñador ni herramienta externasrc/
proxy.ts # Middleware de next-intl: detecta idioma y redirige "/" -> /es|/en|/ca
i18n/
routing.ts # Locales soportados, locale por defecto, prefijo siempre visible
navigation.ts # Link/usePathname/useRouter conscientes del locale
request.ts # Carga messages/<locale>.json según la petición
app/
layout.tsx # Fuentes, metadata SEO base (es), JSON-LD, tema oscuro fijo — 100% estático
[locale]/
layout.tsx # NextIntlClientProvider + GlobalWidgets (por locale, sigue siendo estático)
page.tsx # Home: ensambla todas las secciones, generateMetadata por idioma
not-found.tsx / error.tsx # 404 y error runtime con la identidad de marca (siempre en español)
globals.css # Tokens de color de marca, utilidades, reduced-motion
sitemap.ts / robots.ts / manifest.ts
icon.tsx / apple-icon.tsx # Favicon + apple-touch-icon generados
opengraph-image.tsx / twitter-image.tsx # Imagen social generada (1200×630)
privacidad/ · terminos/ · cookies/ page.tsx # Páginas legales, SIEMPRE en español (ver sección Legal)
components/
layout/
Header.tsx # Nav sticky + selector de idioma, cambia de transparente a sólido con el scroll
Footer.tsx
sections/
Hero.tsx # Parallax en orbes y mock de producto
Story.tsx # "La historia": timeline con línea de progreso ligada al scroll
Features.tsx # Módulos reales, con stagger de scroll
HowItWorks.tsx
SocialProof.tsx # Stats animados + proof points (antes/ahora/resultado)
CTASection.tsx
FAQ.tsx # Accordion (shadcn/ui) + JSON-LD FAQPage
Contact.tsx # Formulario de contacto (Web3Forms)
shared/
Container.tsx, SectionHeading.tsx, Logo.tsx
Reveal.tsx # Wrapper de scroll-reveal (motion, whileInView)
Parallax.tsx # Wrapper de parallax continuo (motion, useScroll+useTransform)
ScrollProgressBar.tsx
AnimatedCounter.tsx # Contador con animejs
AmbientOrbs.tsx # Orbes de fondo con animejs (loop continuo)
ProductMock.tsx # Mock de producto en CSS (sustituir por capturas reales)
DemoGate.tsx # Contexto + modal: pide email antes de abrir la demo
GatedDemoButton.tsx # Botón reutilizable que dispara el gate de email
CookieConsent.tsx # Banner de aceptar/rechazar cookies analíticas
Analytics.tsx # Carga GA4 solo si hay consentimiento aceptado
GlobalWidgets.tsx # Agrupa CookieConsent + BackToTop + WhatsApp + Analytics
LanguageSwitcher.tsx # Selector ES/EN/CA (cambia de idioma sin perder la ruta)
LegalLayout.tsx # Layout + tipografía compartidos por las 3 páginas legales
ui/ # Componentes shadcn/ui generados
lib/
constants.ts # Solo datos estructurales no traducibles: iconos, ids, SITE_URL, LEGAL
consent.ts # Store de consentimiento de cookies (useSyncExternalStore-friendly)
og.tsx # JSX compartido por opengraph-image y twitter-image
web3forms.ts # Cliente del formulario (contacto + gate de demo)
utils.ts # cn()
types/
index.ts
messages/
es.json / en.json / ca.json # Todo el copy traducible del sitio, por idioma
@theme en globals.css)| Token | Valor | Uso |
|---|---|---|
--color-brand-black | #111111 | Fondo base |
--color-brand-black-soft | #1a1a1a | Superficies / tarjetas |
--color-brand-black-elevated | #212121 | Superficies elevadas (barra de mock) |
--color-brand-yellow | #ffd21f | Acento primario, CTAs |
--color-brand-yellow-dim | #e6bd1c | Hover del amarillo |
--color-brand-white | #ffffff | Texto principal |
--color-brand-gray | #a3a3a3 | Texto secundario |
Tema oscuro fijo (es la identidad de marca, no un modo con toggle).
color-scheme: dark declarado en <html> y en viewport.
Reveal.tsx): whileInView + viewport={{ once: true }}.Parallax.tsx): useScroll/useTransform continuos — orbes y
mock del Hero, blur decorativo del CTA final.Story.tsx): la línea vertical se dibuja con
scaleY ligado a scrollYProgress a medida que el usuario avanza por los
4 hitos de la historia.Features.tsx): variantes padre/hijo con staggerChildren.useScroll + useMotionValueEvent.animejs (createScope, animate).prefers-reduced-motion (ver globals.css).Todo lo de abajo usa únicamente convenciones nativas de Next.js (Metadata API,
next/og) y servicios gratuitos de Google/Bing. Cero herramientas de pago.
Ya en el código:
layout.tsx): title/description con las palabras
clave reales del sector (investigadas por búsqueda: "software gestión
academia deportiva/de fútbol/club deportivo", frente a competidores como
SportMember, Playoff o Controla.Club), Open Graph, Twitter Card, alternates.canonical.@graph (Organization + WebSite + SoftwareApplication) en
layout.tsx, más FAQPage en FAQ.tsx — esto habilita rich snippets
de preguntas frecuentes directamente en los resultados de Google, gratis.opengraph-image.tsx,
twitter-image.tsx, 1200×630) con next/og — no ha hecho falta ningún
diseñador ni Canva: se renderiza en build.icon.tsx, apple-icon.tsx) y
manifest.ts (web app manifest).sitemap.ts y robots.ts dinámicos (usan SITE_URL).<h1> (el titular del Hero) y jerarquía h2/h3 correcta en
cada sección — importante para cómo Google interpreta la estructura.<nav aria-label> y landmarks semánticos (<header>, <main>, <footer>).Lo único que tienes que hacer tú, fuera de código, y gratis:
mallenk-academy-software
para que la URL final coincida con SITE_URL en src/lib/constants.ts
(si usas otro nombre o luego compras un dominio propio, actualiza esa
única constante — toda la metadata se recalcula sola).content="...") y ponlo como variable de entorno en Vercel:
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION=ese-código → redeploy. Luego envía
https://tu-dominio/sitemap.xml en la sección Sitemaps.FAQPage y el Organization se leen bien.founder en el schema: en src/lib/constants.ts, la
constante ORGANIZATION.founder está vacía a propósito para no inventar
un nombre en datos estructurados. Si quieres la señal E-E-A-T de "quién
hay detrás del producto" (recomendable y gratis), pon ahí tu nombre real.No hay backend de "content marketing" (blog) todavía. Si más adelante quieres pelear por keywords informacionales (p. ej. "cómo gestionar los bonos de una academia de fútbol"), la vía gratuita es añadir
src/app/blog/[slug]/page.tsxcon contenido propio — eso, no las meta tags, es lo que de verdad compite en Google a medio plazo.
Dos piezas nuevas, ambas usando el mismo backend gratuito (web3forms.com, sin servidor propio, sin límite mensual publicitado):
DemoGate.tsx + GatedDemoButton.tsx):
cualquier botón "Explorar demo en vivo" del sitio abre un modal que pide el
email antes de abrir DEMO_URL en una pestaña nueva. Una vez enviado, se
guarda una marca en localStorage del navegador para no volver a pedirlo
en visitas futuras desde el mismo dispositivo.Contact.tsx, #contacto): formulario email +
mensaje, mismo backend.Configuración obligatoria antes de desplegar (gratis, ~2 minutos):
NEXT_PUBLIC_WEB3FORMS_KEY con ese valor → redeploy..env.example a .env.local y pega la misma clave si
quieres probar los formularios con npm run dev.Sin esta variable configurada, el modal y el formulario de contacto se muestran igual, pero el envío falla con un aviso en pantalla — no hay un "modo simulado" silencioso, para que no publiques el sitio pensando que funciona sin haberlo comprobado.
/privacidad, /terminos, /cookies
(antes eran enlaces muertos href="#" en el footer). Comparten layout y
tipografía vía LegalLayout.tsx.LEGAL en constants.ts): taxId se deja
vacío a propósito para no inventar un NIF/CIF. Rellénalo con el real
antes de publicar en producción — mientras esté vacío, la página de
Términos simplemente omite esa línea./privacidad, no /es/privacidad ni /en/privacidad) — decisión de
producto, no una limitación técnica. Desde /en o /ca, el footer añade
un aviso "(Spanish only)" / "(només en castellà)" junto a esos enlaces.CookieConsent.tsx + consent.ts): aparece en la
primera visita, guarda la elección en localStorage
(mk_cookie_consent). Google Analytics (Analytics.tsx) solo se
carga si el visitante pulsa "Aceptar" — antes se cargaba siempre, sin
consentimiento previo.not-found.tsx, error.tsx): páginas con la
identidad de marca en vez de las genéricas de Next.js. Viven fuera del
árbol [locale], así que también se muestran siempre en español./es, /en, /ca (via next-intl,
localePrefix: "always" en src/i18n/routing.ts). Un visitante que entra
por / recibe un 307 hacia el idioma detectado en Accept-Language
(con fallback a /es) — lo hace src/proxy.ts (el middleware de
next-intl; en Next.js 16 esta convención se llama "proxy", no
"middleware", y debe vivir en src/ cuando el proyecto usa src/app,
no en la raíz del repo).messages/{es,en,ca}.json, organizado por
sección (hero, story, features, faq, cookieConsent, etc.).
src/lib/constants.ts ya solo guarda lo que NO se traduce: iconos, ids,
slugs de sección y valores numéricos.LanguageSwitcher.tsx, en el header desktop y en
el menú móvil): cambia de ruta preservando la página actual
(/en#faq → /ca#faq), usando usePathname/useRouter de
src/i18n/navigation.ts./es, /en, /ca) se
prerrenderizan como HTML estático en build (generateStaticParams +
setRequestLocale en [locale]/layout.tsx) — no uses getLocale() ni
getMessages() en el layout raíz (src/app/layout.tsx): eso lee la
negociación de idioma de la petición y fuerza renderizado dinámico en
todas las rutas del sitio, legales incluidas. Ese provider vive en
[locale]/layout.tsx, y las páginas legales tienen su propio
NextIntlClientProvider estático con messages/es.json importado
directamente (ver LegalLayout.tsx).[locale]/page.tsx genera alternates.languages
(hreflang) por idioma + x-default, y sitemap.ts lista las 3 URLs de
home con sus alternates.#inicio) — badge + titular + subtítulo con la historia real →
2 CTAs (demo en vivo / ver la historia) → mock de producto con parallax →
indicador de scroll.#historia) — timeline de scroll: problema → construcción → prueba → producto.#caracteristicas) — los módulos reales de la plataforma + tarjeta de seguridad.#como-funciona) — 3 pasos, empezando por la demo.#resultados) — stats honestas + proof points antes/ahora/resultado.#cta) — banner amarillo: demo (con gate de email) + enlace a contacto.#faq) — accordion + FAQPage JSON-LD.#contacto) — formulario email + mensaje (Web3Forms).npm install
npm run dev # http://localhost:3000
npm run lint
npm run build && npm start
Proyecto zero-config: Vercel detecta Next.js automáticamente.
npm install -g vercel # si no lo tienes
vercel login
vercel # despliegue de preview
vercel --prod # despliegue a producción
O conectando el repositorio de Git desde el dashboard de Vercel (New Project → Import Git Repository) para despliegues automáticos en cada push.
Antes de publicar:
SITE_URL
(o actualiza esa constante tras el primer deploy).NEXT_PUBLIC_WEB3FORMS_KEY en Vercel (ver sección de
Contacto arriba) — sin esto el gate de la demo y el formulario de
contacto no envían nada.ProductMock.tsx por capturas reales (next/image, con
width/height explícitos para no introducir CLS).Con el stack actual (fuentes con next/font y display: swap, sin imágenes
externas en el above-the-fold, animaciones basadas en transform/opacity,
CSS-first Tailwind v4, sin JS bloqueante):
| Métrica | Objetivo | Por qué se cumple |
|---|---|---|
| LCP | < 2.5s | El elemento LCP (titular del Hero) es texto del sistema con fuente precargada; el mock de producto es CSS puro, no una imagen que bloquee. |
| CLS | < 0.1 | Contenedores con aspect-ratio fijo, sin fuentes con fallback descuadrado (display: swap + fallback métrico de next/font), sin imágenes sin dimensiones. |
| INP | < 200ms | Animaciones limitadas a transform/opacity (compositor), sin listeners pesados en scroll. |
| TBT | Bajo | Sin librerías de terceros pesadas; motion y animejs se cargan solo en los client components que los necesitan. |
Verificar siempre con Lighthouse/PageSpeed Insights sobre el despliegue real,
especialmente al sustituir el ProductMock por imágenes reales.