diff --git a/app/components/Cursor.tsx b/app/components/Cursor.tsx new file mode 100644 index 0000000..6145fc4 --- /dev/null +++ b/app/components/Cursor.tsx @@ -0,0 +1,49 @@ +"use client"; + +import { useEffect, useRef } from "react"; +import { gsap } from "gsap"; + +export default function Cursor() { + const dot = useRef(null); + const ring = useRef(null); + + useEffect(() => { + if (window.matchMedia("(pointer: coarse)").matches) return; + if (!dot.current || !ring.current) return; + + const xD = gsap.quickTo(dot.current, "x", { duration: 0.15, ease: "power3" }); + const yD = gsap.quickTo(dot.current, "y", { duration: 0.15, ease: "power3" }); + const xR = gsap.quickTo(ring.current, "x", { duration: 0.5, ease: "power3" }); + const yR = gsap.quickTo(ring.current, "y", { duration: 0.5, ease: "power3" }); + + const move = (e: MouseEvent) => { + xD(e.clientX); + yD(e.clientY); + xR(e.clientX); + yR(e.clientY); + }; + + const over = (e: Event) => { + if ((e.target as HTMLElement).closest("a,button,.hoverable")) { + ring.current?.classList.add("cursor-ring--big"); + } + }; + const out = () => ring.current?.classList.remove("cursor-ring--big"); + + window.addEventListener("mousemove", move); + document.addEventListener("mouseover", over); + document.addEventListener("mouseout", out); + return () => { + window.removeEventListener("mousemove", move); + document.removeEventListener("mouseover", over); + document.removeEventListener("mouseout", out); + }; + }, []); + + return ( + <> +
+
+ + ); +} diff --git a/app/components/Hero.tsx b/app/components/Hero.tsx new file mode 100644 index 0000000..fca4493 --- /dev/null +++ b/app/components/Hero.tsx @@ -0,0 +1,108 @@ +"use client"; + +import { useEffect, useRef } from "react"; +import { gsap } from "gsap"; + +const line1 = "La mayoría de agencias alquilan sus herramientas.".split(" "); +const line2 = "Nosotros construimos la nuestra.".split(" "); + +function Words({ words, grad }: { words: string[]; grad?: boolean }) { + return ( + + {words.map((w, i) => ( + + {w}{" "} + + ))} + + ); +} + +export default function Hero() { + const root = useRef(null); + const mark = useRef(null); + + useEffect(() => { + const el = root.current; + if (!el) return; + + const ctx = gsap.context(() => { + const tl = gsap.timeline({ defaults: { ease: "power4.out" } }); + tl.from(".eyebrow", { y: 20, opacity: 0, duration: 0.8 }) + .from( + ".word-in", + { yPercent: 115, duration: 1.05, stagger: 0.045 }, + "-=0.4" + ) + .from(".hero-sub", { y: 24, opacity: 0, duration: 0.9 }, "-=0.7") + .from(".hero-actions > *", { y: 20, opacity: 0, stagger: 0.12, duration: 0.7 }, "-=0.6") + .from(".bar", { scaleX: 0, transformOrigin: "left", stagger: 0.08, duration: 0.7, ease: "power3.inOut" }, "-=1.1"); + + // floating pill-mark + gsap.to(".bar", { + y: "+=8", + duration: 2.4, + ease: "sine.inOut", + repeat: -1, + yoyo: true, + stagger: { each: 0.15, from: "random" }, + }); + + }, el); + + const onMove = (e: MouseEvent) => { + const rx = (e.clientX / window.innerWidth - 0.5) * 2; + const ry = (e.clientY / window.innerHeight - 0.5) * 2; + gsap.to(mark.current, { x: rx * 22, y: ry * 22, duration: 0.8, ease: "power3" }); + gsap.to(".blob", { x: rx * 30, y: ry * 30, duration: 1.2, ease: "power3" }); + }; + window.addEventListener("mousemove", onMove); + + return () => { + window.removeEventListener("mousemove", onMove); + ctx.revert(); + }; + }, []); + + return ( +
+
+ + + + +
+ +
+

Agencia de marketing AI-native

+ +
+ +
+ + +
+ +
+ +

+ + +

+ +

+ Estrategia humana + nuestra propia plataforma de IA. Web, SEO, ads y + contenido — más rápido, más medible y a mejor coste que una agencia + tradicional. +

+ + +
+ +
scroll
+
+ ); +} diff --git a/app/components/Reveal.tsx b/app/components/Reveal.tsx new file mode 100644 index 0000000..e0f7b51 --- /dev/null +++ b/app/components/Reveal.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { useEffect, useRef, ReactNode } from "react"; +import { gsap } from "gsap"; +import { ScrollTrigger } from "gsap/ScrollTrigger"; + +gsap.registerPlugin(ScrollTrigger); + +export default function Reveal({ + children, + className = "", + stagger = 0, + y = 40, +}: { + children: ReactNode; + className?: string; + stagger?: number; + y?: number; +}) { + const ref = useRef(null); + + useEffect(() => { + const el = ref.current; + if (!el) return; + const targets = stagger > 0 ? Array.from(el.children) : [el]; + + const ctx = gsap.context(() => { + gsap.from(targets, { + y, + opacity: 0, + duration: 1, + ease: "power3.out", + stagger, + scrollTrigger: { trigger: el, start: "top 85%" }, + }); + }, el); + + return () => ctx.revert(); + }, [stagger, y]); + + return ( +
+ {children} +
+ ); +} diff --git a/app/components/SmoothScroll.tsx b/app/components/SmoothScroll.tsx new file mode 100644 index 0000000..eb93a6d --- /dev/null +++ b/app/components/SmoothScroll.tsx @@ -0,0 +1,31 @@ +"use client"; + +import { useEffect } from "react"; +import Lenis from "lenis"; +import { gsap } from "gsap"; +import { ScrollTrigger } from "gsap/ScrollTrigger"; + +gsap.registerPlugin(ScrollTrigger); + +export default function SmoothScroll() { + useEffect(() => { + const lenis = new Lenis({ + duration: 1.15, + smoothWheel: true, + easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), + }); + + lenis.on("scroll", ScrollTrigger.update); + + const ticker = (time: number) => lenis.raf(time * 1000); + gsap.ticker.add(ticker); + gsap.ticker.lagSmoothing(0); + + return () => { + gsap.ticker.remove(ticker); + lenis.destroy(); + }; + }, []); + + return null; +} diff --git a/app/globals.css b/app/globals.css index 106737b..d7b0eb9 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,122 +1,162 @@ :root { - --bg: #0a0a0b; - --bg-2: #101013; - --fg: #fafafa; - --muted: #a1a1aa; - --line: rgba(255, 255, 255, 0.1); - --accent: #6366f1; - --accent-2: #22d3ee; - --maxw: 1140px; + --violet: #8b5cf6; + --blue: #3b82f6; + --green: #10b981; + --ink: #111827; + --bg-ink: #08080d; + --bg-ink-2: #0e0e16; + --fg: #f6f6f9; + --muted: #9aa0ad; + --maxw: 1180px; } * { box-sizing: border-box; margin: 0; padding: 0; } - html { scroll-behavior: smooth; } - body { - background: var(--bg); + background: var(--bg-ink); color: var(--fg); - font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + font-family: "Satoshi", ui-sans-serif, system-ui, -apple-system, sans-serif; -webkit-font-smoothing: antialiased; - line-height: 1.5; + line-height: 1.45; + overflow-x: hidden; } - a { color: inherit; text-decoration: none; } +::selection { background: var(--violet); color: #fff; } -.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 clamp(20px, 5vw, 40px); width: 100%; } - +.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 clamp(22px, 5vw, 48px); width: 100%; } .grad { - background: linear-gradient(90deg, var(--accent), var(--accent-2)); - -webkit-background-clip: text; - background-clip: text; - color: transparent; + background: linear-gradient(100deg, var(--violet), var(--blue) 60%, var(--green)); + -webkit-background-clip: text; background-clip: text; color: transparent; } +/* CUSTOM CURSOR */ +@media (hover: hover) and (pointer: fine) { + body { cursor: none; } + a, button, .hoverable { cursor: none; } +} +.cursor-dot, .cursor-ring { + position: fixed; top: 0; left: 0; border-radius: 50%; + pointer-events: none; z-index: 9999; transform: translate(-50%, -50%); + mix-blend-mode: difference; +} +.cursor-dot { width: 7px; height: 7px; background: #fff; } +.cursor-ring { width: 34px; height: 34px; border: 1px solid #fff; transition: width .25s, height .25s, opacity .25s; } +.cursor-ring--big { width: 64px; height: 64px; opacity: .6; } +@media (hover: none), (pointer: coarse) { .cursor-dot, .cursor-ring { display: none; } } + /* HEADER */ .hd { - position: sticky; top: 0; z-index: 50; + position: fixed; top: 0; left: 0; right: 0; z-index: 100; display: flex; justify-content: space-between; align-items: center; - padding: 16px clamp(20px, 5vw, 40px); - background: rgba(10, 10, 11, 0.7); - backdrop-filter: blur(12px); - border-bottom: 1px solid var(--line); + padding: 18px clamp(22px, 5vw, 48px); + mix-blend-mode: difference; color: #fff; } -.logo { font-weight: 700; letter-spacing: -0.02em; } -.hd-nav { display: flex; gap: 1.6rem; align-items: center; font-size: 0.92rem; } -.hd-nav a { color: var(--muted); transition: color 0.15s; } -.hd-nav a:hover { color: var(--fg); } -.hd-cta { color: var(--fg) !important; border: 1px solid var(--line); padding: 0.5rem 1rem; border-radius: 999px; } -@media (max-width: 640px) { .hd-nav a:not(.hd-cta) { display: none; } } +.logo { font-weight: 900; letter-spacing: -.03em; font-size: 1.05rem; } +.logo-dot { font-weight: 400; opacity: .7; } +.hd-nav { display: flex; gap: 1.8rem; align-items: center; font-size: .92rem; font-weight: 500; } +.hd-cta { border: 1px solid rgba(255,255,255,.5); padding: .5rem 1.1rem; border-radius: 999px; } +@media (max-width: 680px) { .hd-nav a:not(.hd-cta) { display: none; } } /* HERO */ -.hero { position: relative; overflow: hidden; padding: clamp(80px, 14vw, 160px) 0 clamp(60px, 9vw, 110px); } -.hero::before { - content: ""; position: absolute; inset: 0; pointer-events: none; - background: radial-gradient(55% 50% at 72% -10%, rgba(99, 102, 241, 0.28), transparent 70%), - radial-gradient(40% 45% at 0% 110%, rgba(34, 211, 238, 0.12), transparent 70%); +.hero { + position: relative; min-height: 100svh; display: flex; align-items: center; + background: linear-gradient(180deg, #efe9fb 0%, #f6f3fd 55%, #eef0fe 100%); + color: var(--ink); overflow: hidden; } -.hero .wrap { position: relative; z-index: 1; } -.eyebrow { text-transform: uppercase; letter-spacing: 0.18em; font-size: 0.76rem; color: var(--accent-2); margin-bottom: 1.1rem; } -h1 { font-size: clamp(2.3rem, 6vw, 4.6rem); line-height: 1.04; letter-spacing: -0.03em; font-weight: 800; } -.sub { margin-top: 1.5rem; max-width: 620px; font-size: clamp(1rem, 1.5vw, 1.2rem); color: var(--muted); } -.actions { margin-top: 2.2rem; display: flex; gap: 1rem; flex-wrap: wrap; } +.mesh { position: absolute; inset: 0; z-index: 0; } +.blob { position: absolute; border-radius: 50%; filter: blur(70px); opacity: .75; will-change: transform; } +.b1 { width: 46vw; height: 46vw; background: var(--violet); top: -8%; left: -6%; animation: drift1 16s ease-in-out infinite; } +.b2 { width: 42vw; height: 42vw; background: var(--blue); top: 10%; right: -8%; animation: drift2 19s ease-in-out infinite; } +.b3 { width: 34vw; height: 34vw; background: #f5a8e4; bottom: -10%; left: 18%; opacity: .6; animation: drift3 22s ease-in-out infinite; } +.b4 { width: 26vw; height: 26vw; background: var(--green); bottom: 4%; right: 14%; opacity: .45; animation: drift1 18s ease-in-out infinite reverse; } +@keyframes drift1 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(6%, 8%) scale(1.12); } } +@keyframes drift2 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-7%, 5%) scale(1.08); } } +@keyframes drift3 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(5%, -6%) scale(1.15); } } -.btn { padding: 0.85rem 1.5rem; border-radius: 999px; font-weight: 600; font-size: 0.95rem; transition: transform 0.15s; display: inline-block; } -.btn:hover { transform: translateY(-2px); } -.btn.primary { background: linear-gradient(90deg, var(--accent), var(--accent-2)); color: #04060a; } -.btn.ghost { border: 1px solid var(--line); color: var(--fg); } -.btn.big { padding: 1.05rem 2.2rem; font-size: 1.05rem; } +.hero-inner { position: relative; z-index: 2; padding: 7rem 0 5rem; } +.eyebrow { text-transform: uppercase; letter-spacing: .24em; font-size: .74rem; font-weight: 700; color: var(--violet); margin-bottom: 1.6rem; } -/* PROOF STRIP */ -.strip { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; padding: 22px clamp(20px, 5vw, 40px); color: var(--muted); font-size: 0.9rem; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); } -.strip .dot { opacity: 0.4; } +.pillmark { display: inline-flex; flex-direction: column; gap: 7px; margin-bottom: 2rem; } +.bar { height: 13px; border-radius: 999px; display: block; will-change: transform; } +.bar-grad { width: 70px; background: linear-gradient(90deg, var(--violet), var(--blue)); } +.bar-row { display: flex; gap: 7px; } +.bar-ink { width: 44px; background: var(--ink); } +.bar-blue { width: 19px; background: var(--blue); } +.bar-green { width: 70px; background: var(--green); } + +.hero-h1 { font-size: clamp(2.5rem, 7vw, 6rem); line-height: .98; letter-spacing: -.04em; font-weight: 900; max-width: 16ch; } +.line { display: block; } +.word { display: inline-block; overflow: hidden; margin-right: .22em; } +.word-in { display: inline-block; will-change: transform; } +.hero-h1 .line:first-child { color: var(--ink); opacity: .92; } + +.hero-sub { margin-top: 2rem; max-width: 560px; font-size: clamp(1rem, 1.5vw, 1.22rem); color: #3a3f4c; font-weight: 500; } +.hero-actions { margin-top: 2.6rem; display: flex; gap: 1rem; flex-wrap: wrap; } + +.btn { padding: .95rem 1.7rem; border-radius: 999px; font-weight: 700; font-size: .96rem; transition: transform .25s, box-shadow .25s; display: inline-block; } +.btn:hover { transform: translateY(-3px); } +.btn.primary { background: linear-gradient(100deg, var(--violet), var(--blue)); color: #fff; box-shadow: 0 12px 30px -10px rgba(99,102,241,.6); } +.btn.ghost { border: 1px solid rgba(17,24,39,.25); color: var(--ink); } +.btn.big { padding: 1.15rem 2.4rem; font-size: 1.05rem; } +.cta .btn.ghost, .band .btn.ghost { border-color: rgba(255,255,255,.3); color: #fff; } + +.scroll-hint { position: absolute; bottom: 26px; left: 50%; transform: translateX(-50%); z-index: 2; font-size: .72rem; text-transform: uppercase; letter-spacing: .3em; color: var(--ink); opacity: .5; animation: bob 2s ease-in-out infinite; } +@keyframes bob { 0%,100% { transform: translate(-50%,0); } 50% { transform: translate(-50%,6px); } } + +/* MARQUEE */ +.marquee { background: var(--bg-ink); border-top: 1px solid rgba(255,255,255,.08); border-bottom: 1px solid rgba(255,255,255,.08); padding: 1.1rem 0; overflow: hidden; white-space: nowrap; } +.marquee-track { display: inline-block; animation: scrollx 26s linear infinite; font-weight: 700; font-size: 1.05rem; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; } +@keyframes scrollx { from { transform: translateX(0); } to { transform: translateX(-50%); } } /* BANDS */ -.band { padding: clamp(56px, 9vw, 110px) 0; } -.band.alt { background: var(--bg-2); } -.band h2 { font-size: clamp(1.7rem, 3.4vw, 2.6rem); letter-spacing: -0.02em; font-weight: 800; } -.lead { margin-top: 0.9rem; max-width: 640px; color: var(--muted); font-size: clamp(1rem, 1.4vw, 1.15rem); } -.lead strong { color: var(--fg); } +.band { padding: clamp(72px, 12vw, 150px) 0; background: var(--bg-ink); position: relative; } +.band.ink:nth-of-type(even) { background: var(--bg-ink-2); } +.kicker { text-transform: uppercase; letter-spacing: .2em; font-size: .76rem; font-weight: 700; color: var(--green); margin-bottom: 1.2rem; } +.band-h2 { font-size: clamp(1.9rem, 4.4vw, 3.6rem); letter-spacing: -.03em; font-weight: 900; max-width: 18ch; line-height: 1.05; } -/* GRIDS + CARDS */ -.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; margin-top: 2.6rem; } -.grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.1rem; margin-top: 2.6rem; } -@media (max-width: 900px) { .grid3, .grid4 { grid-template-columns: repeat(2, 1fr); } } -@media (max-width: 560px) { .grid3, .grid4 { grid-template-columns: 1fr; } } +.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.2rem; margin-top: 3.5rem; } +@media (max-width: 820px) { .grid3 { grid-template-columns: 1fr; } } +.card { background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.08); border-radius: 18px; padding: 1.9rem; transition: border-color .3s, transform .3s, background .3s; } +.card:hover { border-color: var(--violet); transform: translateY(-4px); background: rgba(139,92,246,.06); } +.card h3 { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; margin-bottom: .6rem; } +.card p { color: var(--muted); font-size: 1rem; } -.card { - background: rgba(255, 255, 255, 0.025); - border: 1px solid var(--line); - border-radius: 16px; - padding: 1.5rem; - transition: border-color 0.2s, transform 0.2s; -} -.card:hover { border-color: rgba(99, 102, 241, 0.5); transform: translateY(-3px); } -.card h3 { font-size: 1.15rem; margin-bottom: 0.5rem; letter-spacing: -0.01em; } -.card p { color: var(--muted); font-size: 0.96rem; } -.card .step { font-size: 0.85rem; font-weight: 700; color: var(--accent-2); letter-spacing: 0.1em; } - -.vertical { display: grid; gap: 2rem; } +/* SERVICES LIST */ +.svc-list { margin-top: 3rem; border-top: 1px solid rgba(255,255,255,.1); } +.svc { display: grid; grid-template-columns: 70px 1fr 1.3fr; gap: 1.5rem; align-items: baseline; padding: 1.6rem 0; border-bottom: 1px solid rgba(255,255,255,.1); transition: padding .3s, background .3s; } +.svc:hover { padding-left: 1.2rem; background: linear-gradient(90deg, rgba(139,92,246,.08), transparent); } +.svc-n { color: var(--violet); font-weight: 700; font-size: .9rem; } +.svc-t { font-size: clamp(1.3rem, 2.6vw, 2.1rem); font-weight: 800; letter-spacing: -.02em; } +.svc-d { color: var(--muted); font-size: 1rem; } +@media (max-width: 760px) { .svc { grid-template-columns: 40px 1fr; } .svc-d { grid-column: 2; } } /* PACKAGES */ -.pkg { position: relative; background: rgba(255, 255, 255, 0.025); border: 1px solid var(--line); border-radius: 16px; padding: 1.6rem 1.4rem; } -.pkg.featured { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), 0 20px 50px -20px rgba(99, 102, 241, 0.5); } -.pkg .tag { position: absolute; top: -11px; left: 1.4rem; background: linear-gradient(90deg, var(--accent), var(--accent-2)); color: #04060a; font-size: 0.7rem; font-weight: 700; padding: 0.25rem 0.7rem; border-radius: 999px; } -.pkg h3 { font-size: 1.2rem; } -.pkg .who { color: var(--muted); font-size: 0.85rem; margin: 0.3rem 0 1rem; } -.pkg ul { list-style: none; display: flex; flex-direction: column; gap: 0.55rem; } -.pkg li { font-size: 0.92rem; padding-left: 1.4rem; position: relative; } -.pkg li::before { content: "→"; position: absolute; left: 0; color: var(--accent-2); } +.grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; margin-top: 3.5rem; } +@media (max-width: 980px) { .grid4 { grid-template-columns: repeat(2, 1fr); } } +@media (max-width: 540px) { .grid4 { grid-template-columns: 1fr; } } +.pkg { position: relative; background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.1); border-radius: 18px; padding: 1.8rem 1.5rem; transition: transform .3s, border-color .3s; } +.pkg:hover { transform: translateY(-4px); border-color: rgba(255,255,255,.25); } +.pkg.featured { border-color: var(--violet); background: linear-gradient(180deg, rgba(139,92,246,.12), rgba(255,255,255,.02)); box-shadow: 0 30px 60px -30px rgba(139,92,246,.6); } +.pkg .tag { position: absolute; top: -12px; left: 1.5rem; background: linear-gradient(100deg, var(--violet), var(--blue)); color: #fff; font-size: .68rem; font-weight: 800; padding: .3rem .8rem; border-radius: 999px; text-transform: uppercase; letter-spacing: .05em; } +.pkg h3 { font-size: 1.35rem; font-weight: 800; } +.pkg .who { color: var(--muted); font-size: .85rem; margin: .3rem 0 1.2rem; } +.pkg ul { list-style: none; display: flex; flex-direction: column; gap: .65rem; } +.pkg li { font-size: .94rem; padding-left: 1.5rem; position: relative; color: #d4d7de; } +.pkg li::before { content: "→"; position: absolute; left: 0; color: var(--green); font-weight: 700; } /* CTA */ -.cta { position: relative; overflow: hidden; padding: clamp(70px, 11vw, 130px) 0; text-align: center; } -.cta::before { content: ""; position: absolute; inset: 0; background: radial-gradient(50% 80% at 50% 0%, rgba(99, 102, 241, 0.22), transparent 70%); pointer-events: none; } -.cta .wrap { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; } -.cta h2 { font-size: clamp(1.9rem, 4vw, 3rem); letter-spacing: -0.02em; } -.cta .lead { margin-left: auto; margin-right: auto; text-align: center; } -.cta .btn { margin-top: 2rem; } +.cta { position: relative; overflow: hidden; padding: clamp(90px, 14vw, 180px) 0; text-align: center; background: #efe9fb; color: var(--ink); } +.mesh-cta .blob { opacity: .55; } +.cta .wrap { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; } +.cta-h2 { font-size: clamp(2.2rem, 6vw, 4.6rem); font-weight: 900; letter-spacing: -.04em; line-height: 1; } +.cta .hero-sub { color: #3a3f4c; text-align: center; margin-left: auto; margin-right: auto; } +.cta .btn { margin-top: 2.4rem; } /* FOOTER */ -.ft { border-top: 1px solid var(--line); padding: 2.5rem 0; } -.ft .wrap { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: 0.85rem; } -.ft .muted { color: var(--muted); } +.ft { background: var(--bg-ink); border-top: 1px solid rgba(255,255,255,.08); padding: 3rem 0; } +.ft .wrap { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; } +.ft .muted { color: var(--muted); font-size: .85rem; } + +@media (prefers-reduced-motion: reduce) { + * { animation: none !important; } +} diff --git a/app/layout.tsx b/app/layout.tsx index ccef644..476e4cc 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,10 +1,19 @@ import type { Metadata } from "next"; import "./globals.css"; +import SmoothScroll from "./components/SmoothScroll"; +import Cursor from "./components/Cursor"; export const metadata: Metadata = { title: "Feedback Studios — La agencia de marketing AI-native", description: "Estrategia humana, ejecución sobre nuestra propia plataforma de IA. Web, SEO, ads y contenido: más rápido, más medible y a mejor coste.", + // Test environment — keep everything out of search engines. + robots: { + index: false, + follow: false, + nocache: true, + googleBot: { index: false, follow: false }, + }, }; export default function RootLayout({ @@ -14,7 +23,18 @@ export default function RootLayout({ }) { return ( - {children} + + + + + + + + {children} + ); } diff --git a/app/page.tsx b/app/page.tsx index 3bea3a5..212220b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,11 +1,5 @@ -const services = [ - { t: "Web & Desarrollo", d: "Sitios en código, rápidos y editables. Sin plantillas genéricas." }, - { t: "SEO", d: "Posicionamiento técnico y de contenido, con reporting real." }, - { t: "Paid Ads", d: "Google, Meta, TikTok, LinkedIn — creatividad + optimización con IA." }, - { t: "Contenido", d: "Artículos y piezas optimizadas para Google y para IA (GEO)." }, - { t: "Diseño & Marca", d: "Identidad y dirección de arte con criterio, no plantillas." }, - { t: "Automatización", d: "Flujos que ahorran horas: leads, reporting, operativa." }, -]; +import Hero from "./components/Hero"; +import Reveal from "./components/Reveal"; const pillars = [ { k: "Más rápido", d: "Entregamos en días lo que una agencia tradicional tarda semanas." }, @@ -13,6 +7,15 @@ const pillars = [ { k: "Mejor coste", d: "Nuestra plataforma hace el trabajo pesado. Pagas resultado, no horas." }, ]; +const services = [ + { n: "01", t: "Web & Desarrollo", d: "Sitios en código, rápidos y editables. Sin plantillas." }, + { n: "02", t: "SEO", d: "Posicionamiento técnico y de contenido, con reporting real." }, + { n: "03", t: "Paid Ads", d: "Google, Meta, TikTok, LinkedIn — creatividad + IA." }, + { n: "04", t: "Contenido", d: "Piezas optimizadas para Google y para IA (GEO)." }, + { n: "05", t: "Diseño & Marca", d: "Identidad y dirección de arte con criterio." }, + { n: "06", t: "Automatización", d: "Flujos que ahorran horas: leads, reporting, operativa." }, +]; + const packages = [ { n: "Sitio AI-native", who: "Necesitas web ya", f: ["Web editable en código", "SEO base + tracking", "Listo en tiempo récord"] }, { n: "Base", who: "Estás arrancando", f: ["Fundamentos SEO", "Contenido inicial", "Analítica"] }, @@ -20,157 +23,108 @@ const packages = [ { n: "Partner", who: "Quieres escalar", f: ["Full-stack de crecimiento", "Automatización a medida", "Prioridad y plataforma"] }, ]; -const steps = [ - { n: "01", t: "Diagnóstico", d: "Analizamos tu negocio, tu mercado y tus números." }, - { n: "02", t: "Sistema", d: "Montamos el motor: web, canales, automatización." }, - { n: "03", t: "Crecimiento", d: "Iteramos sobre datos. Tú ves el resultado en tu dashboard." }, -]; - export default function Home() { return ( <>
- Feedback Studios + feedbackstudios
- {/* HERO */} -
-
-

Agencia de marketing AI-native

-

- La mayoría de agencias alquilan sus herramientas. -
- Nosotros construimos la nuestra. -

-

- Estrategia humana + nuestra propia plataforma de IA. Web, SEO, ads - y contenido — más rápido, más medible y a mejor coste que una - agencia tradicional. -

- -
-
+ - {/* PROOF STRIP */} -
- +60 marcas confían en nosotros - · - Web · SEO · Ads · Contenido - · - Resultados medibles -
+ {/* MARQUEE */} +
+
+ {Array.from({ length: 2 }).map((_, i) => ( + + Web · SEO · Paid Ads · Contenido · Diseño · Automatización · IA ·  + + ))} +
+
{/* VENTAJA INJUSTA */} -
+
-

Nuestra ventaja injusta

-

- No alquilamos herramientas ni envolvemos un ChatGPT. Operamos tu - marketing sobre nuestra propia plataforma de IA. -

-
+ +

01 — Ventaja injusta

+

+ No alquilamos herramientas. Construimos la máquina. +

+
+ {pillars.map((p) => (

{p.k}

{p.d}

))} -
+
{/* SERVICIOS */} -
+
-

Qué hacemos

-

Todo lo que necesita tu crecimiento, bajo un mismo techo y un mismo sistema.

-
+ +

02 — Qué hacemos

+

Todo tu crecimiento, un mismo sistema.

+
+ {services.map((s) => ( -
-

{s.t}

-

{s.d}

+
+ {s.n} + {s.t} + {s.d}
))} -
-
-
- - {/* PROFUNDIDAD POR SECTOR */} -
-
-
-

Soluciones a medida

-

Generalistas por fuera, profundos por dentro

-

- Para sectores exigentes construimos soluciones específicas sobre - nuestra plataforma — por ejemplo, clínicas estéticas con captación, - seguimiento y operativa a medida. Profundidad que un generalista no tiene. -

-
+
{/* PAQUETES */} -
+
-

Paquetes

-

Cada uno con un resultado prometido y su dashboard. No listas de tareas.

-
+ +

03 — Paquetes

+

Cada uno con un resultado. No listas de tareas.

+
+ {packages.map((p) => ( -
+
{p.featured && Más popular}

{p.n}

{p.who}

-
    - {p.f.map((x) => ( -
  • {x}
  • - ))} -
+
    {p.f.map((x) =>
  • {x}
  • )}
))} -
+
- {/* PROCESO */} -
-
-

Cómo trabajamos

-
- {steps.map((s) => ( -
- {s.n} -

{s.t}

-

{s.d}

-
- ))} -
-
-
- - {/* CONTACTO */} + {/* CTA */}
-
-

¿Hablamos de tu crecimiento?

-

Cuéntanos dónde estás y te enseñamos cómo llegar al siguiente nivel.

- Habla con nosotros +
+
+ +

¿Hablamos de tu crecimiento?

+

Cuéntanos dónde estás y te enseñamos cómo llegar al siguiente nivel.

+ Habla con nosotros +
diff --git a/app/robots.ts b/app/robots.ts new file mode 100644 index 0000000..3d74d93 --- /dev/null +++ b/app/robots.ts @@ -0,0 +1,8 @@ +import type { MetadataRoute } from "next"; + +// Test environment: disallow all crawling. +export default function robots(): MetadataRoute.Robots { + return { + rules: { userAgent: "*", disallow: "/" }, + }; +} diff --git a/next.config.mjs b/next.config.mjs index d5456a1..37fba98 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,6 +1,17 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, + async headers() { + return [ + { + // Test environment — hard noindex at the header level too. + source: "/:path*", + headers: [ + { key: "X-Robots-Tag", value: "noindex, nofollow, noarchive, nosnippet" }, + ], + }, + ]; + }, }; export default nextConfig; diff --git a/package.json b/package.json index 8c37143..4ffd9a3 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "start": "next start -H 0.0.0.0 -p 3000" }, "dependencies": { + "gsap": "^3.12.5", + "lenis": "^1.1.14", "next": "15.1.6", "react": "19.0.0", "react-dom": "19.0.0"