Skip to content

Commit 01a34ea

Browse files
Senavictorsclaude
andcommitted
feat(dashboard): implement Phase 9c+9d — button hover states and compare VS alignment
- Add hover effects (lift, glow, border highlight) to all interactive buttons across Landing, Playground, Compare and Profile pages - Fix VS badge vertical misalignment in Compare — spacer mirrors label height so badge sits flush with the input fields - Extract CtaSection into a client component to support onMouseEnter/Leave (Server Components cannot pass event handlers to Client Component props) - Add hover states to ThemeSelector, widget type buttons, embed tab buttons, profile theme switcher, and profile CTA buttons Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a7e6e31 commit 01a34ea

10 files changed

Lines changed: 1149 additions & 318 deletions

File tree

.docs/tasks/phase-9c-redesign-playground.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Phase 9c — Redesign Playground
22

3-
**Status**: [ ] pendente
3+
**Status**: [x] concluído
44
**Agentes recomendados**: `widget-engineer`, `docs-keeper`
55

66
## Contexto
@@ -83,4 +83,4 @@ Substituir o visual do playground pelo novo design, preservando integralmente to
8383

8484
## Resultado (preencher ao concluir)
8585

86-
> O que foi implementado, decisões tomadas, o que ficou de fora.
86+
> **Implementado:** Sidebar com 3 seções separadas (Username / Widget Type / Theme) com `SectionLabel` uppercase e `SidebarDivider`. Widget type selector substituído por cards verticais com ícone lucide-react (BarChart2, Flame, AlignLeft), descrição curta e checkmark quando selecionado. Preview container com grid checkered + `drop-shadow` + transição fade (opacity 0→1 em 250ms via `useEffect` + `prevUrlRef`). Embed code com header estilo IDE (semáforos macOS + tabs README.md / index.html / Component.tsx) e syntax highlighting inline sem dependência extra (`tokenizeMarkdown`, `tokenizeHtml`, `tokenizeReact` com coloração por token type). Toda a lógica de negócio mantida intacta (debounce 500ms, URL sync, embed generation, CopyButton).

.docs/tasks/phase-9d-redesign-compare.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Phase 9d — Redesign Compare
22

3-
**Status**: [ ] pendente
3+
**Status**: [x] concluído
44
**Agentes recomendados**: `widget-engineer`, `docs-keeper`
55

66
## Contexto
@@ -69,4 +69,4 @@ Substituir o visual da página de comparação pelo novo design, preservando int
6969

7070
## Resultado (preencher ao concluir)
7171

72-
> O que foi implementado, decisões tomadas, o que ficou de fora.
72+
> **Implementado:** Layout `grid-cols-[1fr_1px_1fr]` com separador vertical real entre as colunas. Badge "VS" centralizado no header de inputs. `UsernameInput` componentizado com ícone `User` dinâmico (accent quando preenchido), focus ring em accent color, `htmlFor`/`id` corretos para acessibilidade. `UserColumn` com header de usuário (avatar placeholder + @username em accent). Widgets envolvidos em `WidgetCard` com fundo grid checkered e `drop-shadow` — mesmo container de profundidade da landing e playground. Estado vazio com placeholder visual e ícone User. Toda a lógica de URL sharing (`/compare?a=user1&b=user2`) e debounce mantida intacta. Nota: highlight de "winner" por métrica não foi adicionado pois não há fetch de dados de métricas na implementação atual — seria necessário introduzir fetching novo, fora do escopo de redesign puro.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
"use client";
2+
3+
import Link from "next/link";
4+
5+
export function CtaSection() {
6+
return (
7+
<section
8+
style={{
9+
position: "relative",
10+
overflow: "hidden",
11+
background: "var(--background)",
12+
borderTop: "1px solid #21262d",
13+
}}
14+
>
15+
<div
16+
style={{
17+
position: "absolute",
18+
top: "50%",
19+
left: "50%",
20+
transform: "translate(-50%,-50%)",
21+
width: 600,
22+
height: 300,
23+
background:
24+
"radial-gradient(ellipse, rgba(88,166,255,0.15) 0%, transparent 70%)",
25+
pointerEvents: "none",
26+
}}
27+
/>
28+
<div
29+
style={{
30+
maxWidth: 640,
31+
margin: "0 auto",
32+
padding: "100px 32px",
33+
textAlign: "center",
34+
position: "relative",
35+
zIndex: 1,
36+
}}
37+
>
38+
<h2
39+
style={{
40+
fontSize: "clamp(28px, 4vw, 44px)",
41+
fontWeight: 700,
42+
letterSpacing: "-0.02em",
43+
color: "var(--foreground)",
44+
marginBottom: 16,
45+
}}
46+
>
47+
Ready to level up your README?
48+
</h2>
49+
<p
50+
style={{
51+
fontSize: 16,
52+
color: "var(--muted)",
53+
marginBottom: 40,
54+
lineHeight: 1.7,
55+
}}
56+
>
57+
Configure your widgets visually — no YAML, no tokens, no friction.
58+
</p>
59+
<Link
60+
href="/playground"
61+
style={{
62+
background: "linear-gradient(135deg, #388bfd, #58a6ff)",
63+
color: "#fff",
64+
border: "none",
65+
borderRadius: 8,
66+
padding: "14px 36px",
67+
fontSize: 16,
68+
fontWeight: 600,
69+
textDecoration: "none",
70+
boxShadow: "0 0 32px rgba(88,166,255,0.4)",
71+
display: "inline-block",
72+
transition: "transform 0.2s ease, box-shadow 0.2s ease",
73+
}}
74+
onMouseEnter={(e) => {
75+
e.currentTarget.style.transform = "translateY(-2px)";
76+
e.currentTarget.style.boxShadow = "0 0 48px rgba(88,166,255,0.65)";
77+
}}
78+
onMouseLeave={(e) => {
79+
e.currentTarget.style.transform = "translateY(0)";
80+
e.currentTarget.style.boxShadow = "0 0 32px rgba(88,166,255,0.4)";
81+
}}
82+
>
83+
Open Playground →
84+
</Link>
85+
</div>
86+
</section>
87+
);
88+
}

apps/dashboard/src/app/(marketing)/hero-section.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,17 @@ export function HeroSection() {
203203
fontWeight: 600,
204204
textDecoration: "none",
205205
boxShadow: "0 0 20px rgba(88,166,255,0.35)",
206-
transition: "box-shadow 0.2s ease",
206+
transition: "box-shadow 0.2s ease, transform 0.15s ease",
207207
display: "inline-block",
208208
}}
209+
onMouseEnter={(e) => {
210+
e.currentTarget.style.boxShadow = "0 0 32px rgba(88,166,255,0.6)";
211+
e.currentTarget.style.transform = "translateY(-1px)";
212+
}}
213+
onMouseLeave={(e) => {
214+
e.currentTarget.style.boxShadow = "0 0 20px rgba(88,166,255,0.35)";
215+
e.currentTarget.style.transform = "translateY(0)";
216+
}}
209217
>
210218
Open Playground
211219
</Link>
@@ -227,6 +235,14 @@ export function HeroSection() {
227235
textDecoration: "none",
228236
transition: "all 0.2s ease",
229237
}}
238+
onMouseEnter={(e) => {
239+
e.currentTarget.style.background = "rgba(255,255,255,0.08)";
240+
e.currentTarget.style.borderColor = "rgba(255,255,255,0.25)";
241+
}}
242+
onMouseLeave={(e) => {
243+
e.currentTarget.style.background = "rgba(255,255,255,0.04)";
244+
e.currentTarget.style.borderColor = "rgba(255,255,255,0.1)";
245+
}}
230246
>
231247
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" role="img">
232248
<title>GitHub</title>
Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import Link from "next/link";
21
import { HeroSection } from "./hero-section";
32
import { ShowcaseSection } from "./showcase-section";
43
import { ThemesSection } from "./themes-section";
54
import { DeliverySection } from "./delivery-section";
5+
import { CtaSection } from "./cta-section";
66

77
export default function LandingPage() {
88
return (
@@ -11,80 +11,7 @@ export default function LandingPage() {
1111
<ShowcaseSection />
1212
<ThemesSection />
1313
<DeliverySection />
14-
15-
{/* CTA final */}
16-
<section
17-
style={{
18-
position: "relative",
19-
overflow: "hidden",
20-
background: "var(--background)",
21-
borderTop: "1px solid #21262d",
22-
}}
23-
>
24-
<div
25-
style={{
26-
position: "absolute",
27-
top: "50%",
28-
left: "50%",
29-
transform: "translate(-50%,-50%)",
30-
width: 600,
31-
height: 300,
32-
background:
33-
"radial-gradient(ellipse, rgba(88,166,255,0.15) 0%, transparent 70%)",
34-
pointerEvents: "none",
35-
}}
36-
/>
37-
<div
38-
style={{
39-
maxWidth: 640,
40-
margin: "0 auto",
41-
padding: "100px 32px",
42-
textAlign: "center",
43-
position: "relative",
44-
zIndex: 1,
45-
}}
46-
>
47-
<h2
48-
style={{
49-
fontSize: "clamp(28px, 4vw, 44px)",
50-
fontWeight: 700,
51-
letterSpacing: "-0.02em",
52-
color: "var(--foreground)",
53-
marginBottom: 16,
54-
}}
55-
>
56-
Ready to level up your README?
57-
</h2>
58-
<p
59-
style={{
60-
fontSize: 16,
61-
color: "var(--muted)",
62-
marginBottom: 40,
63-
lineHeight: 1.7,
64-
}}
65-
>
66-
Configure your widgets visually — no YAML, no tokens, no friction.
67-
</p>
68-
<Link
69-
href="/playground"
70-
style={{
71-
background: "linear-gradient(135deg, #388bfd, #58a6ff)",
72-
color: "#fff",
73-
border: "none",
74-
borderRadius: 8,
75-
padding: "14px 36px",
76-
fontSize: 16,
77-
fontWeight: 600,
78-
textDecoration: "none",
79-
boxShadow: "0 0 32px rgba(88,166,255,0.4)",
80-
display: "inline-block",
81-
transition: "transform 0.2s ease",
82-
}}
83-
>
84-
Open Playground →
85-
</Link>
86-
</div>
87-
</section>
14+
<CtaSection />
8815
</div>
8916
);
9017
}

0 commit comments

Comments
 (0)