// components.jsx — Reusable building blocks for Advogado AI landing page
// All components exported to window at the bottom.
const { useState, useEffect, useRef } = React;
// ─────────────────────────────────────────────────────────────────────────
// Icon set — minimal stroked icons (no robots, no gavels)
// ─────────────────────────────────────────────────────────────────────────
const Icon = ({ name, size = 18, stroke = 1.6, style }) => {
const s = { width: size, height: size, ...style };
const common = { fill: "none", stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" };
switch (name) {
case "play":
return ;
case "arrow-right":
return ;
case "arrow-up-right":
return ;
case "spark":
return ;
case "scale":
return ;
case "book":
return ;
case "doc":
return ;
case "workflow":
return ;
case "shield":
return ;
case "users":
return ;
case "bolt":
return ;
case "compass":
return ;
case "newspaper":
return ;
case "mail":
return ;
case "youtube":
return ;
case "instagram":
return ;
case "linkedin":
return ;
case "check":
return ;
case "menu":
return ;
case "x":
return ;
case "download":
return ;
case "search":
return ;
case "megaphone":
return ;
case "clock":
return ;
case "globe":
return ;
case "grid":
return ;
case "chat":
return ;
case "wrench":
return ;
case "lock":
return ;
case "briefcase":
return ;
case "star":
return ;
case "map-pin":
return ;
case "phone":
return ;
case "target":
return ;
case "layers":
return ;
case "cpu":
return ;
case "pen":
return ;
default: return null;
}
};
// ─────────────────────────────────────────────────────────────────────────
// Logo — wordmark "Advogado AI" with a small mark
// ─────────────────────────────────────────────────────────────────────────
const Logo = ({ size = 22 }) => (
);
// ─────────────────────────────────────────────────────────────────────────
// Buttons (declarative)
// ─────────────────────────────────────────────────────────────────────────
const Button = ({ variant = "primary", size, icon, iconRight, children, onClick, href, style }) => {
const cls = `btn btn-${variant}${size ? " btn-" + size : ""}`;
const inner = (
<>
{icon && }
{children}
{iconRight && }
>
);
if (href) return {inner} ;
return {inner} ;
};
// ─────────────────────────────────────────────────────────────────────────
// Eyebrow label (mono uppercase with rule)
// ─────────────────────────────────────────────────────────────────────────
const Eyebrow = ({ children, style }) => {children} ;
// ─────────────────────────────────────────────────────────────────────────
// SectionHeader: eyebrow + headline + lede + optional cta
// ─────────────────────────────────────────────────────────────────────────
const SectionHeader = ({ eyebrow, title, titleAccent, lede, cta, align = "left" }) => (
{eyebrow &&
{eyebrow} }
{title}{titleAccent && <> {titleAccent} >}
{lede &&
{lede}
}
{cta && align !== "center" &&
{cta}
}
);
// ─────────────────────────────────────────────────────────────────────────
// Video thumbnail — design-system cover with category + title
// ─────────────────────────────────────────────────────────────────────────
const VideoThumb = ({ category = "", title = "", featured = false, variant = 0 }) => {
const iconMap = {
"IA para escritórios": "briefcase",
"Ferramentas IA": "cpu",
"Ética e limites": "shield",
"IA na prática": "spark",
"LGPD e IA": "lock",
"Produtividade": "bolt",
"Automação": "workflow",
"IA para petições": "doc",
"IA para estudos": "book",
};
const iconName = iconMap[category] || "spark";
const bgs = [
"linear-gradient(135deg, #0B2545 0%, #11315F 60%, #173E7C 100%)",
"linear-gradient(150deg, #0A0F1C 0%, #0B2545 55%, #11315F 100%)",
"linear-gradient(125deg, #0E1424 0%, #11315F 50%, #1E2638 100%)",
"linear-gradient(118deg, #0B2545 0%, #0A0F1C 60%, #0E1424 100%)",
"linear-gradient(142deg, #173E7C 0%, #0B2545 55%, #0A0F1C 100%)",
];
const glows = [
{ top: "-35%", right: "-10%" },
{ bottom: "-25%", left: "-10%" },
{ top: "-20%", right: "15%" },
{ top: "25%", right: "-18%" },
{ top: "-30%", left: "5%" },
];
const shapes = [
,
<> >,
<> >,
<> >,
,
];
const v = variant % 5;
const patId = `tvg${v}`;
const pad = featured ? "18px 20px" : "14px 16px";
return (
{/* Grid */}
{shapes[v]}
{/* Glow blob */}
{/* Watermark icon */}
{/* Bottom accent line */}
{/* Text content */}
{/* Category */}
{/* Title */}
{title}
);
};
// ─────────────────────────────────────────────────────────────────────────
// Video card (YouTube-style)
// ─────────────────────────────────────────────────────────────────────────
const VideoCard = ({ title, category, duration, thumb, featured, youtubeId, variant = 0 }) => {
const href = youtubeId ? `https://www.youtube.com/watch?v=${youtubeId}` : undefined;
const inner = (
<>
{youtubeId
?
:
}
{duration && (
{duration}
)}
{category}
{title}
>
);
const sharedStyle = {
overflow: "hidden", display: "flex", flexDirection: "column",
gridColumn: featured ? "span 2" : undefined,
};
if (href) return (
{inner}
);
return {inner} ;
};
// ─────────────────────────────────────────────────────────────────────────
// Trail card (learning path)
// ─────────────────────────────────────────────────────────────────────────
const TrailCard = ({ number, title, description, icon, modules, level }) => (
{number}
{modules} módulos · {level}
Ver trilha
);
// ─────────────────────────────────────────────────────────────────────────
// Material card (lead magnet)
// ─────────────────────────────────────────────────────────────────────────
const MaterialCard = ({ kind, title, pages, format = "PDF" }) => (
{kind}
{title}
{pages} · gratuito
);
// ─────────────────────────────────────────────────────────────────────────
// Course card
// ─────────────────────────────────────────────────────────────────────────
const CourseCard = ({ title, description, status, statusLabel, modules, hours }) => (
{statusLabel}
{title}
{description}
{modules} módulos
·
{hours} de aulas
);
// ─────────────────────────────────────────────────────────────────────────
// Article card (editorial)
// ─────────────────────────────────────────────────────────────────────────
const ArticleCard = ({ category, title, excerpt, date, readTime }) => (
{category}
{date}
{title}
{excerpt}
{readTime} de leitura
Ler artigo
);
// ─────────────────────────────────────────────────────────────────────────
// Benefit tile (differentiators)
// ─────────────────────────────────────────────────────────────────────────
const BenefitTile = ({ icon, title, description }) => (
);
// ─────────────────────────────────────────────────────────────────────────
// Page Hero — internal page header
// ─────────────────────────────────────────────────────────────────────────
const PageHero = ({ eyebrow, title, titleAccent, lede, children, dark }) => (
{eyebrow &&
{eyebrow} }
{title}{titleAccent && <> {titleAccent} >}
{lede &&
{lede}
}
{children}
);
// ─────────────────────────────────────────────────────────────────────────
// Tool Card — ferramentas page
// ─────────────────────────────────────────────────────────────────────────
const ToolCardComp = ({ icon, title, description, category, status, statusLabel }) => (
{status &&
{statusLabel} }
{category && {category} }
{title}
{description}
{status === 'in-breve' ? 'Em breve' : 'Saiba mais'}
);
Object.assign(window, {
Icon, Logo, Button, Eyebrow, SectionHeader,
VideoCard, TrailCard, MaterialCard, CourseCard, ArticleCard, BenefitTile,
PageHero, ToolCardComp,
});