Redesign das páginas internas no novo design system (AAA) (#2)

* feat(design): redesign das páginas internas no novo design system

Padroniza todas as páginas e componentes internos nos tokens e primitivos
de app/globals.css, com contraste AAA (7:1) nos dois temas e alvos de toque
de 44px.

- Páginas reescritas: glossário, séries, série, seletor, comparador,
  diagnóstico, catálogo, component registry, frameworks, framework, sobre
  e a nova 404.
- Componentes: PageHero e SectionHead novos; BoardCard, CodeExample,
  PinRestrictions, SeriesTabMenu e ConnectionsDiagram refeitos, com abas
  e diálogo acessíveis.
- Remove emojis, cores avulsas por série, caixa alta com tracking, texto
  menor que 12px e os pares slate-*/dark:*.
- Comparador: "mostrar só as diferenças" e leitura de ?chips=.
- Corrige overflow em 320/390px e ajusta accent/copper do tema claro
  para fechar 7:1.
- scripts/auditar-temas.mjs passa a travar paleta crua, dark:, texto
  pequeno, emoji e contraste dos tokens.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016W1xmizFcmXLrmabSvfSuc

* ci: roda lint, auditorias de design e build em cada PR

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016W1xmizFcmXLrmabSvfSuc

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas Rayan GuerraandClaude Sonnet 5.5 authored and GitHub committed 2026-10-20 16:10:15 -03:00
1 parent 4f27f5858b
commit bc9ae5c036
34 files changed
+4911 -6874

No files matched your search

+296 -495
View File
@@ -1,468 +1,174 @@
import Header from "@/components/Header";
import Footer from "@/components/Footer";
import BookCover from "@/components/BookCover";
import Link from "next/link";
import Image from "next/image";
import {
SlidersHorizontal,
ShoppingBag,
Cpu,
Layers,
Scale,
BookOpen,
import seriesData from "@/public/series.json";
import frameworksData from "@/public/frameworks.json";
import { SITE } from "@/lib/seo";
import {
AlertTriangle,
Terminal,
Compass,
ArrowRight,
Sparkles,
CheckCircle2,
Zap,
ExternalLink,
Info,
Radio,
ShieldCheck,
Code,
HelpCircle,
Box
ArrowUpRight,
BookOpen,
Box,
Cpu,
Scale,
SlidersHorizontal,
Terminal,
} from "lucide-react";
const FEATURED = ["ESP32", "ESP32-S3", "ESP32-C6", "ESP32-C3", "ESP32-P4", "ESP32-H2"];
const TOOLS = [
{
href: "/seletor",
title: "Seletor inteligente",
desc: "Responda oito perguntas sobre o projeto e receba os chips mais compatíveis, com justificativa técnica.",
icon: SlidersHorizontal,
action: "Encontrar meu chip",
},
{
href: "/comparacao",
title: "Comparador de séries",
desc: "Coloque até quatro modelos lado a lado e compare núcleos, rádio, memória, periféricos e segurança.",
icon: Scale,
action: "Comparar agora",
},
{
href: "/diagnostico",
title: "Diagnóstico de falhas",
desc: "Causas e correções para brownout, bootloop, Guru Meditation, watchdog e falhas de flash.",
icon: AlertTriangle,
action: "Abrir diagnóstico",
},
{
href: "/componentes",
title: "Component Registry",
desc: "Drivers, bibliotecas e BSPs do registro oficial da Espressif, com manifesto pronto para o projeto.",
icon: Box,
action: "Explorar componentes",
},
{
href: "/frameworks",
title: "Frameworks e SDKs",
desc: "ESP-IDF, Arduino, Rust, Matter, MicroPython e as ferramentas que ficam em volta do chip.",
icon: Terminal,
action: "Ver frameworks",
},
{
href: "/catalogo",
title: "Catálogo de placas",
desc: "DevKits e módulos reais, com interface USB, sensores integrados e link para a loja oficial.",
icon: Cpu,
action: "Ver placas",
},
];
const ERRORS = [
{
code: "Brownout detector was triggered",
cause: "Queda de tensão na inicialização do rádio.",
fix: "Capacitor de 10–100 µF junto ao chip e fonte de 5 V com corrente suficiente.",
},
{
code: "Guru Meditation Error",
cause: "Ponteiro inválido, stack overflow ou uso incorreto de interrupção.",
fix: "Leia o backtrace com addr2line e dimensione a stack da task no FreeRTOS.",
},
{
code: "ADC2 indisponível com Wi-Fi",
cause: "O controlador de rádio reserva o ADC2 enquanto está ativo.",
fix: "Use os pinos do ADC1 para sensores analógicos que convivem com o Wi-Fi.",
},
{
code: "Flash Read err / bootloader",
cause: "Tensão ou modo de flash incorretos, ou pino de strapping preso no boot.",
fix: "Confira 3,3 V, pull-ups de boot e a configuração de flash no esptool.",
},
];
export default function Home() {
// Estatísticas da Plataforma
const stats = [
{ value: "12", label: "Séries Documentadas", desc: "Do ESP32 clássico ao P4 e C61" },
{ value: "14", label: "Frameworks & SDKs", desc: "ESP-IDF, RainMaker, Rust, Matter, etc." },
{ value: "35+", label: "Componentes Curados", desc: "ESP Component Registry & idf_component.yml" },
{ value: "30+", label: "Guias de Diagnóstico", desc: "Soluções para bootloops, brownouts e WDT" },
];
// Ferramentas da Plataforma (100% Clicáveis)
const tools = [
{
title: "Seletor Inteligente",
badge: "Recomendado",
badgeColor: "bg-purple-100 text-purple-700 dark:bg-purple-950/60 dark:text-purple-300",
description: "Responda algumas perguntas sobre seu projeto e descubra o chip ESP32 ideal com análise técnica e justificativa.",
href: "/seletor",
icon: <SlidersHorizontal className="w-6 h-6" />,
iconBg: "text-purple-600 bg-purple-50 dark:bg-purple-950/40 dark:text-purple-400",
ctaText: "Iniciar Quiz de Seleção",
},
{
title: "ESP Component Registry",
badge: "Oficial & Modular",
badgeColor: "bg-purple-100 text-purple-700 dark:bg-purple-950/60 dark:text-purple-300",
description: "Explore o catálogo oficial de pacotes modulares da Espressif (LVGL, RainMaker, ESP-SR, BSPs) e gere manifestos idf_component.yml.",
href: "/componentes",
icon: <Box className="w-6 h-6" />,
iconBg: "text-purple-600 bg-purple-50 dark:bg-purple-950/40 dark:text-purple-400",
ctaText: "Explorar Componentes",
},
{
title: "Diagnóstico de Falhas",
badge: "30+ Soluções",
badgeColor: "bg-amber-100 text-amber-700 dark:bg-amber-950/60 dark:text-amber-300",
description: "Encontre a causa e o passo a passo para corrigir erros frequentes como Brownout, Guru Meditation, Bootloops e falhas de Flash.",
href: "/diagnostico",
icon: <AlertTriangle className="w-6 h-6" />,
iconBg: "text-amber-600 bg-amber-50 dark:bg-amber-950/40 dark:text-amber-400",
ctaText: "Resolver Erro no Código",
},
{
title: "Comparador de Séries",
badge: "Lado a Lado",
badgeColor: "bg-indigo-100 text-indigo-700 dark:bg-indigo-950/60 dark:text-indigo-300",
description: "Compare especificações de até 4 séries simultaneamente: núcleos, clock, memória SRAM/PSRAM, interfaces e conexões.",
href: "/comparacao",
icon: <Scale className="w-6 h-6" />,
iconBg: "text-indigo-600 bg-indigo-50 dark:bg-indigo-950/40 dark:text-indigo-400",
ctaText: "Comparar Modelos",
},
{
title: "Explorador de Séries & Pinouts",
badge: "12 Chips",
badgeColor: "bg-blue-100 text-blue-700 dark:bg-blue-950/60 dark:text-blue-300",
description: "Consulte diagramas interativos de conexões, mapas de periféricos, datasheets oficiais e restrições de pinos (strapping, ADC2).",
href: "/series",
icon: <Cpu className="w-6 h-6" />,
iconBg: "text-blue-600 bg-blue-50 dark:bg-blue-950/40 dark:text-blue-400",
ctaText: "Ver Todas as Séries",
},
{
title: "Catálogo de Placas",
badge: "Hardware Real",
badgeColor: "bg-emerald-100 text-emerald-700 dark:bg-emerald-950/60 dark:text-emerald-300",
description: "Filtre placas de desenvolvimento (DevKit, Xiao, Wemos, LilyGO) por série, interface USB, sensores integrados e links de compra.",
href: "/catalogo",
icon: <ShoppingBag className="w-6 h-6" />,
iconBg: "text-emerald-600 bg-emerald-50 dark:bg-emerald-950/40 dark:text-emerald-400",
ctaText: "Explorar Placas Físicas",
},
{
title: "Frameworks & SDKs",
badge: "14 Frameworks",
badgeColor: "bg-teal-100 text-teal-700 dark:bg-teal-950/60 dark:text-teal-300",
description: "Documentação completa de frameworks oficiais: ESP-IDF, RainMaker, Rust, Matter, ESP-SR, Arduino, MicroPython e mais.",
href: "/frameworks",
icon: <Terminal className="w-6 h-6" />,
iconBg: "text-teal-600 bg-teal-50 dark:bg-teal-950/40 dark:text-teal-400",
ctaText: "Acessar Guias de SDK",
},
{
title: "Glossário Técnico",
badge: "60+ Conceitos",
badgeColor: "bg-pink-100 text-pink-700 dark:bg-pink-950/60 dark:text-pink-300",
description: "Dicionário de termos técnicos essenciais: entenda RTOS, NVS, Partições OTA, eFuse, Brownout, RISC-V e protocolos industriais.",
href: "/glossario",
icon: <BookOpen className="w-6 h-6" />,
iconBg: "text-pink-600 bg-pink-50 dark:bg-pink-950/40 dark:text-pink-400",
ctaText: "Consultar Termos",
},
{
title: "Sobre a Plataforma",
badge: "Comunidade",
badgeColor: "bg-slate-200 text-slate-700 dark:bg-slate-800 dark:text-slate-300",
description: "Conheça a missão da ESPDocs, a autoria de Lucas Rayan Guerra e a parceria educacional com o blog Ciência Embarcada.",
href: "/sobre",
icon: <Info className="w-6 h-6" />,
iconBg: "text-slate-650 bg-slate-100 dark:bg-slate-800 dark:text-slate-350",
ctaText: "Conhecer o Projeto",
},
];
// Chips em Destaque
const featuredChips = [
{
name: "ESP32",
slug: "ESP32",
badge: "Padrão da Indústria",
arch: "Xtensa LX6 Dual-Core @ 240 MHz",
wireless: "Wi-Fi 4 (802.11 b/g/n) + BLE 4.2 / Clássico",
highlights: "Suporte maduro, 36 pinos GPIO, ADC duplo, DAC de 8 bits",
cor: "#007bff",
},
{
name: "ESP32-S3",
slug: "ESP32-S3",
badge: "IA & USB Nativo",
arch: "Xtensa LX7 Dual-Core @ 240 MHz",
wireless: "Wi-Fi 4 + BLE 5.0 (Long Range)",
highlights: "Instruções vetoriais para IA, USB OTG nativo, até 45 GPIOs",
cor: "#fd7e14",
},
{
name: "ESP32-C6",
slug: "ESP32-C6",
badge: "Wi-Fi 6 + Zigbee/Matter",
arch: "RISC-V 32-bit Single-Core @ 160 MHz + LP Core",
wireless: "Wi-Fi 6 (ax) + BLE 5.3 + Zigbee 3.0 & Thread (802.15.4)",
highlights: "Protocolo Matter, Target Wake Time (TWT), segurança de hardware",
cor: "#17a2b8",
},
{
name: "ESP32-C3",
slug: "ESP32-C3",
badge: "Custo-Benefício RISC-V",
arch: "RISC-V 32-bit Single-Core @ 160 MHz",
wireless: "Wi-Fi 4 + BLE 5.0 (Mesh & Long Range)",
highlights: "Substituto direto do ESP8266, pinout compacto, baixo consumo",
cor: "#20c997",
},
{
name: "ESP32-P4",
slug: "ESP32-P4",
badge: "Superprocessador 400MHz",
arch: "Dual-Core RISC-V HP @ 400 MHz + LP Core @ 40 MHz",
wireless: "Sem rádio interno (Focado em processamento multimídia)",
highlights: "MIPI-CSI/DSI, codificador H.264, Ethernet 100M, 50+ GPIOs",
cor: "#ffc107",
},
{
name: "ESP32-H2",
slug: "ESP32-H2",
badge: "Zigbee & Thread",
arch: "RISC-V 32-bit Single-Core @ 96 MHz",
wireless: "IEEE 802.15.4 (Zigbee 3.0, Thread) + BLE 5.3",
highlights: "Automação residencial ultrabaixo consumo, nós finais de rede",
cor: "#6c757d",
},
];
// Problemas Comuns do Diagnóstico
const commonErrors = [
{
title: "Brownout detector was triggered",
cause: "Queda de tensão súbita na alimentação ao inicializar o Wi-Fi",
solution: "Adicionar capacitor de desacoplamento de 10µF–100µF e usar fonte externa de 5V 1A+",
},
{
title: "Guru Meditation Error: IllegalInstruction",
cause: "Acesso a ponteiro nulo, estouro de pilha (stack overflow) ou interrupção incorreta",
solution: "Inspecione o Backtrace usando o addr2line e aumente o tamanho da stack da task FreeRTOS",
},
{
title: "ADC2 leitura inválida com Wi-Fi",
cause: "O rádio Wi-Fi bloqueia o conversor analógico-digital ADC2 enquanto está ativo",
solution: "Utilize exclusivamente pinos do ADC1 (GPIOs 32 a 39 no ESP32) para sensores analógicos",
},
{
title: "Flash Read err / Bootloader falhou",
cause: "Tensão de Flash incorreta (1.8V vs 3.3V) ou pino de strapping (GPIO 0, 2, 12, 15) travado",
solution: "Verifique resistores pull-up/pull-down nos pinos de boot e confirme a frequência de Flash no esptool",
},
];
const seriesCount = Object.keys(seriesData).length;
const frameworkCount = Object.keys(frameworksData).length;
const featured = FEATURED.map((key) => [key, seriesData[key]]).filter(([, serie]) => Boolean(serie));
return (
<div className="bg-gradient-to-br from-slate-100 via-slate-50 to-purple-100/40 dark:from-slate-950 dark:via-slate-950 dark:to-slate-900 min-h-screen text-slate-900 dark:text-slate-100">
<div className="site-canvas min-h-screen">
<Header />
<main className="px-4 sm:px-6 pt-10 md:pt-16 pb-24 max-w-7xl mx-auto">
{/* Hero Section */}
<section className="text-center mb-20 max-w-5xl mx-auto">
{/* Pill Tag */}
<div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-purple-50 dark:bg-purple-950/50 border border-purple-200 dark:border-purple-800/80 text-purple-700 dark:text-purple-300 text-xs md:text-sm font-bold mb-6 shadow-xs">
<Sparkles className="w-3.5 h-3.5 text-purple-600 dark:text-purple-400" />
<span>O Maior Hub Técnico de ESP32 em Português</span>
</div>
<main id="conteudo">
<section className="shell pb-10 pt-14 sm:pt-20 lg:pb-14 lg:pt-24">
<div className="mx-auto max-w-4xl text-center">
<span className="chip chip-accent">
<Cpu className="h-3.5 w-3.5" aria-hidden="true" />
Documentação aberta do ESP32
</span>
<h1 className="display mt-6 text-[clamp(2.9rem,7.4vw,5.4rem)]">
O ESP32,
<br className="sm:hidden" /> sem ruído.
</h1>
<p className="lede mx-auto mt-6 max-w-2xl">
Especificações, pinagem, comparações e diagnóstico em uma leitura só.
Menos tradução de datasheet, mais tempo com o protótipo na bancada.
</p>
<h1 className="text-4xl sm:text-6xl md:text-7xl lg:text-8xl font-display font-extrabold bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500 bg-clip-text text-transparent mb-6 tracking-tight leading-[1.1] select-none">
ESPDocs
</h1>
<h2 className="text-xl sm:text-2xl md:text-3xl text-slate-850 dark:text-slate-100 font-extrabold mb-6 max-w-3xl mx-auto leading-snug">
Tudo o que você precisa para dominar o ecossistema ESP32
</h2>
<p className="text-sm sm:text-base md:text-lg text-slate-650 dark:text-slate-350 max-w-3xl mx-auto leading-relaxed mb-10">
Chega de perder tempo traduzindo datasheets dispersos ou decifrando bootloops no escuro.
Compare 12 séries de chips, diagnostique erros comuns de firmware, descubra o ESP32 ideal
para o seu projeto e consulte pinouts interativos 100% em português brasileiro.
</p>
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
<Link href="/seletor" className="btn btn-primary w-full sm:w-auto">
<SlidersHorizontal className="h-4 w-4" aria-hidden="true" />
Escolher meu chip
</Link>
<Link href="/series" className="btn btn-ghost w-full sm:w-auto">
Explorar as {seriesCount} séries
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>
{/* Botões de Ação Hero */}
<div className="flex flex-wrap gap-3.5 justify-center items-center mb-16">
<Link
className="group inline-flex items-center gap-2.5 bg-gradient-to-r from-purple-600 to-indigo-600 text-white px-7 py-3.5 rounded-xl font-bold text-sm shadow-md hover:shadow-purple-500/25 hover:-translate-y-0.5 transition-all duration-200 cursor-pointer active:scale-95"
href="/seletor"
>
<Compass className="w-4 h-4" />
<span>Encontrar ESP32 Ideal</span>
<ArrowRight className="w-4 h-4 transform group-hover:translate-x-1 transition-transform" />
</Link>
<Link
className="group inline-flex items-center gap-2.5 bg-amber-700 hover:bg-amber-800 text-white px-7 py-3.5 rounded-xl font-bold text-sm shadow-md hover:-translate-y-0.5 transition-all duration-200 cursor-pointer active:scale-95"
href="/diagnostico"
>
<AlertTriangle className="w-4 h-4" />
<span>Diagnosticar Falhas</span>
</Link>
<Link
className="group inline-flex items-center gap-2.5 bg-blue-600 hover:bg-blue-700 text-white px-7 py-3.5 rounded-xl font-bold text-sm shadow-md hover:-translate-y-0.5 transition-all duration-200 cursor-pointer active:scale-95"
href="/series"
>
<Cpu className="w-4 h-4" />
<span>Explorar 12 Séries</span>
</Link>
<Link
className="group inline-flex items-center gap-2.5 bg-white dark:bg-slate-900 text-slate-700 dark:text-slate-300 px-7 py-3.5 rounded-xl font-bold text-sm shadow-xs border border-slate-300 dark:border-slate-800 hover:border-purple-500 dark:hover:border-purple-400 hover:text-purple-600 dark:hover:text-purple-400 hover:-translate-y-0.5 transition-all duration-200 cursor-pointer active:scale-95"
href="/comparacao"
>
<Scale className="w-4 h-4" />
<span>Comparar Chips</span>
</Link>
</div>
{/* Faixa de Estatísticas */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 max-w-4xl mx-auto">
{stats.map((stat) => (
<div
key={stat.label}
className="bg-white dark:bg-slate-900/60 backdrop-blur-md p-4 sm:p-5 rounded-2xl border border-slate-300 dark:border-slate-800/80 shadow-xs text-center"
>
<div className="text-2xl sm:text-3xl font-display font-extrabold bg-gradient-to-r from-blue-600 to-purple-600 dark:from-blue-400 dark:to-purple-400 bg-clip-text text-transparent mb-1">
{stat.value}
</div>
<div className="text-xs sm:text-sm font-bold text-slate-850 dark:text-slate-100 mb-0.5">
{stat.label}
</div>
<div className="text-[11px] text-slate-500 dark:text-slate-400 leading-tight">
{stat.desc}
</div>
</div>
))}
</div>
</section>
{/* Seção 2: Central de Ferramentas & Recursos (Cards 100% Clicáveis) */}
<section className="mb-24">
<div className="text-center mb-12">
<h2 className="text-2xl sm:text-3xl md:text-4xl font-display font-extrabold text-slate-850 dark:text-slate-100 mb-3">
Central de Ferramentas e Guias
</h2>
<p className="text-sm sm:text-base text-slate-650 dark:text-slate-350 max-w-2xl mx-auto leading-relaxed">
Escolha o que você deseja fazer hoje. Cada ferramenta foi desenvolvida para acelerar seu desenvolvimento e eliminar gargalos.
<p className="mt-7 flex flex-wrap items-center justify-center gap-x-5 gap-y-2 text-sm text-muted">
<span><strong className="font-semibold text-ink">{seriesCount}</strong> séries</span>
<span aria-hidden="true" className="text-line-strong">·</span>
<span><strong className="font-semibold text-ink">{frameworkCount}</strong> frameworks</span>
<span aria-hidden="true" className="text-line-strong">·</span>
<span><strong className="font-semibold text-ink">78</strong> capítulos no livro</span>
<span aria-hidden="true" className="text-line-strong">·</span>
<span>100% em português</span>
</p>
</div>
<div className="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5">
{tools.map((tool) => (
<Link
key={tool.title}
href={tool.href}
className="group flex flex-col justify-between bg-white dark:bg-slate-900/50 backdrop-blur-md p-6 rounded-2xl border border-slate-300 dark:border-slate-800/80 hover:border-purple-500 dark:hover:border-purple-400 shadow-xs hover:shadow-xl hover:shadow-purple-500/5 hover:-translate-y-1 transition-all duration-300 cursor-pointer"
>
<div>
{/* Top Bar: Icon + Badge */}
<div className="flex items-center justify-between gap-2 mb-4">
<div className={`w-12 h-12 rounded-xl flex items-center justify-center shrink-0 transform group-hover:scale-105 transition-transform duration-300 shadow-xs ${tool.iconBg}`}>
{tool.icon}
</div>
<span className={`text-[11px] font-bold px-2.5 py-1 rounded-full ${tool.badgeColor}`}>
{tool.badge}
</span>
</div>
{/* Content */}
<h3 className="text-base font-bold text-slate-850 dark:text-slate-100 mb-2 group-hover:text-purple-600 dark:group-hover:text-purple-400 transition-colors">
{tool.title}
</h3>
<p className="text-xs sm:text-sm text-slate-650 dark:text-slate-350 leading-relaxed mb-6">
{tool.description}
</p>
</div>
{/* Bottom Action Link */}
<div className="pt-3 border-t border-slate-100 dark:border-slate-800/60 flex items-center justify-between text-xs font-bold text-purple-600 dark:text-purple-400">
<span>{tool.ctaText}</span>
<ArrowRight className="w-3.5 h-3.5 transform group-hover:translate-x-1 transition-transform" />
</div>
</Link>
))}
</div>
</section>
{/* Seção 3: Explore as Séries em Destaque */}
<section className="mb-24">
<div className="flex flex-col md:flex-row md:items-end justify-between mb-10 gap-4">
<div>
<div className="inline-flex items-center gap-1.5 text-xs font-bold uppercase tracking-wider text-purple-600 dark:text-purple-400 mb-2">
<Cpu className="w-4 h-4" />
<span>Hardware & Silício</span>
</div>
<h2 className="text-2xl sm:text-3xl md:text-4xl font-display font-extrabold text-slate-850 dark:text-slate-100">
Séries Populares de ESP32
</h2>
<p className="text-sm text-slate-650 dark:text-slate-350 mt-1">
Conheça as principais famílias de chips da Espressif, da arquitetura aos protocolos sem fio.
</p>
</div>
<Link
href="/series"
className="inline-flex items-center gap-2 text-sm font-bold text-purple-600 dark:text-purple-400 hover:text-purple-700 dark:hover:text-purple-300 shrink-0"
>
<span>Ver todas as 12 Séries</span>
<ArrowRight className="w-4 h-4" />
</Link>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{featuredChips.map((chip) => (
<Link
key={chip.slug}
href={`/series/${chip.slug}`}
prefetch={false}
className="group bg-white dark:bg-slate-900/50 backdrop-blur-md p-6 rounded-2xl border border-slate-300 dark:border-slate-800/80 hover:border-purple-500 dark:hover:border-purple-400 shadow-xs hover:shadow-lg transition-all duration-300 flex flex-col justify-between"
>
<div>
<div className="flex items-center justify-between mb-3">
<h3 className="text-xl font-display font-extrabold text-slate-850 dark:text-slate-100 group-hover:text-purple-600 dark:group-hover:text-purple-400 transition-colors">
{chip.name}
</h3>
<span className="text-[11px] font-bold px-2.5 py-0.5 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300">
{chip.badge}
</span>
</div>
<div className="space-y-2 mb-5">
<div className="flex items-start gap-2 text-xs text-slate-650 dark:text-slate-350">
<Zap className="w-3.5 h-3.5 text-amber-500 shrink-0 mt-0.5" />
<span className="font-semibold">{chip.arch}</span>
</div>
<div className="flex items-start gap-2 text-xs text-slate-650 dark:text-slate-350">
<Radio className="w-3.5 h-3.5 text-blue-500 shrink-0 mt-0.5" />
<span>{chip.wireless}</span>
</div>
<div className="flex items-start gap-2 text-xs text-slate-500 dark:text-slate-400">
<CheckCircle2 className="w-3.5 h-3.5 text-emerald-500 shrink-0 mt-0.5" />
<span>{chip.highlights}</span>
</div>
</div>
</div>
<div className="pt-4 border-t border-slate-100 dark:border-slate-800/60 flex items-center justify-between text-xs font-bold text-purple-600 dark:text-purple-400">
<span>Ver Pinout e Especificações</span>
<ArrowRight className="w-3.5 h-3.5 transform group-hover:translate-x-1 transition-transform" />
</div>
</Link>
))}
</div>
</section>
{/* Seção 4: Problemas Comuns & Diagnóstico Rápido */}
<section className="mb-24">
<div className="bg-gradient-to-br from-indigo-50/70 via-purple-50/50 to-white dark:from-slate-900/60 dark:via-slate-900/40 dark:to-purple-950/20 rounded-3xl p-6 sm:p-10 border border-indigo-200/80 dark:border-slate-800 shadow-xs">
<div className="flex flex-col lg:flex-row lg:items-center justify-between gap-6 mb-8">
<div className="panel mt-12 overflow-hidden sm:mt-16">
<div className="flex flex-wrap items-center justify-between gap-3 px-5 py-4 sm:px-7">
<div>
<div className="inline-flex items-center gap-1.5 text-xs font-bold uppercase tracking-wider text-amber-600 dark:text-amber-400 mb-2">
<AlertTriangle className="w-4 h-4" />
<span>Resolução Imediata</span>
</div>
<h2 className="text-2xl sm:text-3xl font-display font-extrabold text-slate-850 dark:text-slate-100">
Enfrentando Erros ou Travamentos?
</h2>
<p className="text-sm text-slate-650 dark:text-slate-350 mt-1 max-w-xl">
Acesse guias práticos com causas comprovadas e soluções passo a passo para as falhas mais comuns de hardware e firmware.
</p>
<h2 className="text-sm font-semibold text-ink">Séries em destaque</h2>
<p className="mt-0.5 text-xs text-muted">O essencial de cada família, antes de abrir o datasheet.</p>
</div>
<Link
href="/diagnostico"
className="inline-flex items-center gap-2 bg-gradient-to-r from-amber-500 to-orange-500 text-white px-6 py-3 rounded-xl font-bold text-sm shadow-md hover:-translate-y-0.5 transition-all duration-200 shrink-0 self-start lg:self-auto cursor-pointer"
>
<AlertTriangle className="w-4 h-4" />
<span>Abrir Guia de 30+ Erros</span>
<Link href="/series" className="inline-flex min-h-11 items-center gap-1.5 text-sm font-medium text-accent transition-colors hover:text-accent-strong">
Índice completo
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>
<div className="grid md:grid-cols-2 gap-4">
{commonErrors.map((err) => (
<div className="grid gap-px border-t border-line bg-line sm:grid-cols-2 lg:grid-cols-3">
{featured.map(([key, serie]) => (
<Link
key={err.title}
href="/diagnostico"
prefetch={false}
className="group bg-white dark:bg-slate-900/80 p-5 rounded-2xl border border-slate-200 dark:border-slate-800 hover:border-amber-400 dark:hover:border-amber-400 transition-all duration-200 flex flex-col justify-between"
key={key}
href={`/series/${key}`}
className="group flex min-w-0 flex-col bg-surface p-5 transition-colors duration-300 hover:bg-surface-2 sm:p-6"
>
<div>
<div className="font-mono text-xs font-bold text-amber-600 dark:text-amber-400 mb-2 group-hover:underline">
{err.title}
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<h3 className="font-display text-xl font-semibold tracking-[-0.035em] text-ink">{key}</h3>
<p className="mt-1 truncate text-xs text-muted">{serie.arquitetura}</p>
</div>
<p className="text-xs text-slate-650 dark:text-slate-350 mb-3">
<strong className="text-slate-800 dark:text-slate-200">Causa provável: </strong>
{err.cause}
</p>
<p className="text-xs text-slate-500 dark:text-slate-400">
<strong className="text-emerald-700 dark:text-emerald-400">Solução rápida: </strong>
{err.solution}
</p>
<span className="grid h-9 w-9 shrink-0 place-items-center rounded-full bg-accent-soft text-accent transition-transform duration-300 group-hover:scale-105">
<Cpu className="h-4 w-4" aria-hidden="true" />
</span>
</div>
<div className="mt-4 pt-3 border-t border-slate-100 dark:border-slate-800/60 flex items-center justify-between text-[11px] font-bold text-amber-600 dark:text-amber-400">
<span>Ver diagnóstico completo</span>
<ArrowRight className="w-3.5 h-3.5 transform group-hover:translate-x-1 transition-transform" />
<p className="mt-5 line-clamp-2 text-sm leading-relaxed text-muted">{serie.descricao}</p>
<div className="mt-5 flex items-center justify-between gap-3 border-t border-line pt-3.5">
<span className="truncate font-mono text-[0.6875rem] text-ink-soft">{serie.frequencia}</span>
<span className="inline-flex shrink-0 items-center gap-1 text-xs font-medium text-accent">
Ficha
<ArrowUpRight className="h-3.5 w-3.5 transition-transform duration-300 group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
</span>
</div>
</Link>
))}
@@ -470,71 +176,166 @@ export default function Home() {
</div>
</section>
{/* Seção 5: Ciência Embarcada & Curadoria */}
<section className="mb-8">
<div className="bg-gradient-to-br from-white to-purple-50/50 dark:from-slate-900/40 dark:to-purple-950/10 rounded-3xl shadow-xs border border-slate-300 dark:border-slate-800/80 p-8 md:p-12 relative overflow-hidden">
{/* Background soft glow decoration */}
<div className="absolute right-0 bottom-0 w-80 h-80 bg-purple-500/5 rounded-full blur-3xl pointer-events-none" />
<section className="shell section pt-8 sm:pt-12" aria-labelledby="livro-titulo">
<div className="relative isolate overflow-hidden rounded-[2rem] bg-[#0b0d10] ring-1 ring-white/10 dark:bg-[#05070a] dark:ring-white/15 sm:rounded-[2.5rem]">
<div
className="pointer-events-none absolute -left-24 top-1/2 -z-10 h-80 w-80 -translate-y-1/2 rounded-full bg-[#2dd4bf]/15 blur-3xl"
aria-hidden="true"
/>
<div className="grid lg:grid-cols-[0.82fr_1.18fr]">
<div className="order-1 flex flex-col justify-center p-7 sm:p-10 lg:order-2 lg:p-14">
<span className="inline-flex w-fit items-center gap-2 rounded-full border border-white/15 bg-white/5 px-3 py-1 text-xs font-semibold text-[#75cdc1]">
<BookOpen className="h-3.5 w-3.5" aria-hidden="true" />
Livro novo
</span>
<h2 id="livro-titulo" className="mt-5 font-display text-[clamp(2rem,4.2vw,3.2rem)] font-semibold leading-[1.05] tracking-[-0.04em] text-[#f4f6f8]">
{SITE.livroTitulo}
</h2>
<p className="mt-2 text-base text-[#a6afbd]">{SITE.livroSubtitulo}</p>
<p className="mt-5 max-w-xl text-sm leading-relaxed text-[#c4cbd5]">
Um percurso completo pelo hardware e pelo firmware do ESP32: da arquitetura do chip
à implantação de produtos conectados. São 12 partes e 78 capítulos sobre Arduino,
ESP-IDF, FreeRTOS, Wi-Fi, BLE, Thread e Matter, periféricos, depuração, baixo consumo
e segurança.
</p>
<div className="flex flex-col items-center text-center relative z-10 max-w-3xl mx-auto">
<a
href="https://cienciaembarcada.com.br"
target="_blank"
rel="noopener noreferrer"
className="group mb-6"
>
<Image
src="/logo.png"
alt="Ciência Embarcada Logo"
width={80}
height={80}
className="h-16 w-16 md:h-20 md:w-20 mb-2 transition-transform duration-300 group-hover:scale-105 object-contain"
/>
</a>
<h2 className="text-xl sm:text-2xl font-bold text-slate-850 dark:text-slate-100 mb-3">
Conteúdo e Curadoria por{' '}
<a
href="https://cienciaembarcada.com.br"
target="_blank"
rel="noopener noreferrer"
className="text-purple-600 dark:text-purple-400 hover:underline transition-colors font-extrabold"
>
Ciência Embarcada
</a>
</h2>
<p className="text-sm text-slate-650 dark:text-slate-350 leading-relaxed mb-8 max-w-xl">
Acesse artigos profundos sobre programação de microcontroladores, design de hardware, Internet das Coisas (IoT), laboratórios práticos e projetos reais em nosso blog parceiro oficial.
</p>
<p className="mt-6 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs text-[#a6afbd]">
<span>12 partes</span>
<span aria-hidden="true" className="text-white/20">·</span>
<span>78 capítulos</span>
<span aria-hidden="true" className="text-white/20">·</span>
<span>ISBN {SITE.livroIsbn}</span>
</p>
<a
href="https://cienciaembarcada.com.br"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 bg-gradient-to-r from-purple-600 to-indigo-600 text-white px-6 py-3 rounded-xl font-bold text-sm shadow-md hover:shadow-purple-500/10 hover:-translate-y-0.5 transition-all duration-200 cursor-pointer active:scale-95"
>
<span>Visitar Blog Ciência Embarcada</span>
<ExternalLink className="w-4 h-4" />
</a>
</div>
<div className="mt-7 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center">
<a
href={SITE.livroAmazon}
target="_blank"
rel="noopener noreferrer"
className="inline-flex min-h-11 items-center justify-center gap-2 rounded-full bg-[#2dd4bf] px-5 text-sm font-semibold text-[#06201d] transition-colors duration-300 hover:bg-[#5eead4]"
>
Comprar digital
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
</a>
<a
href={SITE.livroUiclap}
target="_blank"
rel="noopener noreferrer"
className="inline-flex min-h-11 items-center justify-center gap-2 rounded-full border border-white/20 px-5 text-sm font-semibold text-[#f4f6f8] transition-colors duration-300 hover:border-white/40 hover:bg-white/5"
>
Comprar impresso
<ArrowUpRight className="h-4 w-4" aria-hidden="true" />
</a>
<Link href="/livro" className="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-full px-3 text-sm font-medium text-[#a6afbd] transition-colors duration-300 hover:text-[#f4f6f8]">
Ficha completa
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>
</div>
{/* Disclaimer Oficial */}
<div className="border-t border-slate-300 dark:border-slate-800/80 pt-8 mt-10">
<div className="bg-slate-100/60 dark:bg-slate-900/60 border-l-4 border-purple-500 p-5 rounded-r-2xl">
<div className="flex gap-4">
<Info className="w-5 h-5 text-purple-600 dark:text-purple-400 mt-0.5 shrink-0" />
<p className="text-xs leading-relaxed text-slate-500 dark:text-slate-400">
<strong className="font-bold text-slate-700 dark:text-slate-200">Plataforma independente e não oficial:</strong> O ESPDocs é um projeto educativo que compila, filtra e expõe dados públicos e links de documentações oficiais fornecidas pela fabricante Espressif Systems. Para projetos industriais ou decisões de engenharia críticas, sempre consulte a documentação técnica nativa do fabricante.
</p>
<div className="order-2 flex items-center justify-center border-t border-white/10 p-8 sm:p-12 lg:order-1 lg:border-r lg:border-t-0 lg:p-14">
<div className="relative w-[min(15.5rem,68%)] lg:w-[min(17rem,100%)]">
<div className="absolute -inset-10 -z-10 rounded-full bg-[#2dd4bf]/10 blur-3xl" aria-hidden="true" />
<BookCover />
</div>
</div>
</div>
</div>
</section>
</section>
<section className="shell section" aria-labelledby="ferramentas-titulo">
<div className="mx-auto max-w-2xl text-center">
<p className="eyebrow">Ferramentas</p>
<h2 id="ferramentas-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
Comece pelo problema.
</h2>
<p className="lede mt-4">
Cada ferramenta resolve uma etapa concreta do projeto, sem cadastro e sem rodeio.
</p>
</div>
<div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{TOOLS.map((tool) => {
const Icon = tool.icon;
return (
<Link key={tool.href} href={tool.href} className="card card-interactive group flex flex-col p-5 sm:p-6">
<span className="grid h-11 w-11 place-items-center rounded-2xl bg-accent-soft text-accent">
<Icon className="h-5 w-5" aria-hidden="true" />
</span>
<h3 className="mt-5 font-display text-lg font-semibold tracking-[-0.025em] text-ink">{tool.title}</h3>
<p className="mt-2 flex-1 text-sm leading-relaxed text-muted">{tool.desc}</p>
<span className="mt-5 inline-flex items-center gap-1.5 text-sm font-medium text-accent">
{tool.action}
<ArrowRight className="h-4 w-4 transition-transform duration-300 group-hover:translate-x-0.5" aria-hidden="true" />
</span>
</Link>
);
})}
</div>
</section>
<section className="shell section pt-0" aria-labelledby="diagnostico-titulo">
<div className="grid items-start gap-10 lg:grid-cols-[0.78fr_1.22fr] lg:gap-16">
<div className="lg:sticky lg:top-28">
<p className="eyebrow">Diagnóstico</p>
<h2 id="diagnostico-titulo" className="display mt-4 text-[clamp(2rem,4.8vw,3.4rem)]">
O primeiro boot não precisa virar noite.
</h2>
<p className="lede mt-4">
Os erros mais comuns têm causa conhecida. O guia parte da mensagem no terminal e chega ao ajuste de hardware ou firmware.
</p>
<Link href="/diagnostico" className="btn btn-accent mt-7">
<AlertTriangle className="h-4 w-4" aria-hidden="true" />
Abrir os 30+ diagnósticos
</Link>
</div>
<div className="panel-dark min-w-0 overflow-hidden rounded-[1.75rem]">
<div className="flex flex-wrap items-center justify-between gap-3 border-b border-white/10 px-5 py-4 sm:px-6">
<span className="inline-flex items-center gap-2 font-mono text-xs text-[#75cdc1]">
<Terminal className="h-4 w-4" aria-hidden="true" />
boot.log
</span>
<span className="text-xs text-[#a6afbd]">4 exemplos de 30+</span>
</div>
<div className="divide-y divide-white/10">
{ERRORS.map((item) => (
<Link key={item.code} href="/diagnostico" className="group grid gap-2 px-5 py-5 transition-colors duration-300 hover:bg-white/[0.035] sm:px-6">
<span className="break-words font-mono text-[0.75rem] font-medium leading-relaxed text-[#ffb39b]">{item.code}</span>
<span className="text-sm font-medium text-[#f4f6f8]">{item.cause}</span>
<span className="text-xs leading-relaxed text-[#a6afbd]">{item.fix}</span>
</Link>
))}
</div>
</div>
</div>
</section>
<section className="shell pb-20 pt-4 md:pb-28">
<div className="mx-auto max-w-3xl text-center">
<p className="eyebrow">Curadoria independente</p>
<h2 className="display mt-4 text-[clamp(2rem,4.5vw,3.2rem)]">
Feito para consultar no meio do projeto.
</h2>
<p className="lede mx-auto mt-4 max-w-2xl">
O ESPDocs organiza dados públicos da Espressif e aponta sempre para a fonte oficial.
Para decisões críticas, o datasheet e o Technical Reference Manual continuam sendo a palavra final.
</p>
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
<Link href="/glossario" className="btn btn-ghost w-full sm:w-auto">
<BookOpen className="h-4 w-4" aria-hidden="true" />
Glossário
</Link>
<Link href="/sobre" className="btn btn-primary w-full sm:w-auto">
Sobre o projeto
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>
</div>
</section>
</main>
<Footer />
</div>
);
}
}