feat(all-deployment)
This commit is contained in:
1 parent
e261394133
commit
4f0020bc10
39 files changed
+13182
-513
No files matched your search
@@ -0,0 +1,116 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import type { ThemeProps } from '../types';
|
||||
|
||||
const stackGroups = [
|
||||
{
|
||||
label: 'FRONTEND',
|
||||
items: ['React', 'TypeScript', 'Next.js', 'Tailwind CSS', 'Vite'],
|
||||
},
|
||||
{
|
||||
label: 'BACKEND',
|
||||
items: ['Node.js', 'Python', 'Express', 'FastAPI', 'NestJS'],
|
||||
},
|
||||
{
|
||||
label: 'DATOS',
|
||||
items: ['PostgreSQL', 'MongoDB', 'Redis', 'Prisma', 'Elasticsearch'],
|
||||
},
|
||||
{
|
||||
label: 'CLOUD & OPS',
|
||||
items: ['AWS', 'Docker', 'GitHub Actions', 'Terraform', 'Linux'],
|
||||
},
|
||||
{
|
||||
label: 'INTEGRACIONES',
|
||||
items: ['REST', 'GraphQL', 'Stripe', 'OAuth 2.0', 'Webhooks'],
|
||||
},
|
||||
];
|
||||
|
||||
export const Stack = ({ isNavyBg }: ThemeProps) => {
|
||||
const bg = isNavyBg ? '#0f1520' : '#f9f9f7';
|
||||
const text = isNavyBg ? '#eef0f4' : '#0a0a0a';
|
||||
const sub = isNavyBg ? 'rgba(255,255,255,0.35)' : '#6a6866';
|
||||
const border = isNavyBg ? 'rgba(255,255,255,0.07)' : '#dddbd5';
|
||||
const tagBg = isNavyBg ? 'rgba(255,255,255,0.04)' : '#f0efec';
|
||||
|
||||
return (
|
||||
<section
|
||||
id="stack"
|
||||
aria-labelledby="stack-heading"
|
||||
style={{ background: bg, color: text }}
|
||||
className="px-8 py-28 md:px-14 transition-colors duration-500"
|
||||
>
|
||||
<div className="mx-auto max-w-7xl">
|
||||
|
||||
{/* Header */}
|
||||
<div className="mb-16 flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-3">
|
||||
<span className="h-px w-8 bg-brand-red" />
|
||||
<span className="text-mono-label" style={{ color: '#e50914' }}>Las herramientas son el medio</span>
|
||||
</div>
|
||||
<h2
|
||||
id="stack-heading"
|
||||
className="text-headline"
|
||||
style={{ maxWidth: '26ch' }}
|
||||
>
|
||||
Las herramientas son el medio.<br className="hidden sm:block" /> El sistema es el fin.
|
||||
</h2>
|
||||
</div>
|
||||
<p className="max-w-xs text-sm leading-relaxed" style={{ color: sub }}>
|
||||
Elegimos la tecnología correcta para cada problema. No hay un stack universal.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Stack groups */}
|
||||
<div
|
||||
style={{ borderTop: `1px solid ${border}` }}
|
||||
>
|
||||
{stackGroups.map((group, i) => (
|
||||
<motion.div
|
||||
key={group.label}
|
||||
initial={{ opacity: 0, x: -8 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.4, delay: i * 0.06 }}
|
||||
className="flex flex-col gap-4 py-6 sm:flex-row sm:items-center sm:gap-10"
|
||||
style={{ borderBottom: `1px solid ${border}` }}
|
||||
>
|
||||
<span
|
||||
className="text-mono-label shrink-0"
|
||||
style={{ color: sub, width: 120 }}
|
||||
>
|
||||
{group.label}
|
||||
</span>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{group.items.map(item => (
|
||||
<span
|
||||
key={item}
|
||||
className="text-sm font-medium px-3 py-1 rounded-sm"
|
||||
style={{
|
||||
background: tagBg,
|
||||
border: `1px solid ${border}`,
|
||||
color: text,
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Footnote */}
|
||||
<motion.p
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: 0.3 }}
|
||||
className="mt-10 text-xs leading-relaxed"
|
||||
style={{ color: sub, maxWidth: '60ch' }}
|
||||
>
|
||||
Estas son las herramientas con las que trabajamos actualmente. La elección depende siempre del problema, no de la preferencia.
|
||||
</motion.p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user