Skip to content

Commit daa0a61

Browse files
committed
feat: EN/PT i18n (English default), iridescent crypto pill and round hero avatar
1 parent ad15658 commit daa0a61

10 files changed

Lines changed: 387 additions & 108 deletions

File tree

app/globals.css

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,51 @@
6565
}
6666
}
6767

68+
/* Crypto nav pill — iridescent Ethereum mark + periodic sheen sweep */
69+
.eth-holo {
70+
animation: eth-holo 8s linear infinite;
71+
}
72+
@keyframes eth-holo {
73+
to {
74+
filter: hue-rotate(360deg);
75+
}
76+
}
77+
78+
.crypto-pill {
79+
position: relative;
80+
overflow: hidden;
81+
}
82+
.crypto-pill::after {
83+
content: "";
84+
position: absolute;
85+
inset: 0;
86+
pointer-events: none;
87+
background: linear-gradient(
88+
115deg,
89+
transparent 32%,
90+
var(--sheen) 50%,
91+
transparent 68%
92+
);
93+
transform: translateX(-130%);
94+
animation: crypto-sheen 5.5s ease-in-out infinite;
95+
}
96+
:root {
97+
--sheen: rgba(255, 255, 255, 0.55);
98+
}
99+
[data-theme="dark"] {
100+
--sheen: rgba(255, 255, 255, 0.13);
101+
}
102+
@keyframes crypto-sheen {
103+
0%,
104+
58% {
105+
transform: translateX(-130%);
106+
}
107+
88%,
108+
100% {
109+
transform: translateX(130%);
110+
}
111+
}
112+
68113
/* Scroll reveal */
69114
.reveal {
70115
opacity: 0;
@@ -83,6 +128,10 @@
83128
transform: none !important;
84129
transition: none !important;
85130
}
131+
.eth-holo,
132+
.crypto-pill::after {
133+
animation: none;
134+
}
86135
html {
87136
scroll-behavior: auto;
88137
}

app/layout.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Metadata } from "next";
22
import localFont from "next/font/local";
3+
import { LanguageProvider } from "@/lib/useLanguage";
34
import "./globals.css";
45

56
const geistSans = localFont({
@@ -15,26 +16,27 @@ const geistMono = localFont({
1516

1617
export const metadata: Metadata = {
1718
title: "Matheus Louzada",
18-
description: "Desenvolvedor Fullstack — .NET, C#, React, TypeScript",
19+
description: "Fullstack Developer — .NET, C#, React, TypeScript",
1920
};
2021

21-
// Set the theme before paint to avoid a flash of the wrong color scheme.
22-
const themeScript = `(function(){try{var t=localStorage.getItem('ml-theme');if(!t){t=window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';}document.documentElement.setAttribute('data-theme',t);}catch(e){}})();`;
22+
// Set the theme and language before paint to avoid a flash of the wrong
23+
// color scheme / lang attribute.
24+
const themeScript = `(function(){try{var t=localStorage.getItem('ml-theme');if(!t){t=window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';}document.documentElement.setAttribute('data-theme',t);var l=localStorage.getItem('ml-lang');document.documentElement.lang=l==='pt'?'pt-BR':'en';}catch(e){}})();`;
2325

2426
export default function RootLayout({
2527
children,
2628
}: Readonly<{
2729
children: React.ReactNode;
2830
}>) {
2931
return (
30-
<html lang="pt-BR" suppressHydrationWarning>
32+
<html lang="en" suppressHydrationWarning>
3133
<head>
3234
<script dangerouslySetInnerHTML={{ __html: themeScript }} />
3335
</head>
3436
<body
3537
className={`${geistSans.variable} ${geistMono.variable} antialiased bg-bg text-fg font-sans overflow-x-hidden`}
3638
>
37-
{children}
39+
<LanguageProvider>{children}</LanguageProvider>
3840
</body>
3941
</html>
4042
);

components/About.tsx

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,26 @@
1-
import Reveal from "./Reveal";
1+
"use client";
22

3-
const groups = [
4-
{
5-
label: "BACK-END",
6-
items: ["C#", "ASP.NET Core", ".NET", "SQL Server", "Entity Framework", "APIs REST"],
7-
},
8-
{
9-
label: "FRONT-END",
10-
items: ["React", "TypeScript", "Next.js", "JavaScript", "HTML / CSS"],
11-
},
12-
{
13-
label: "PRÁTICAS",
14-
items: ["CI / CD", "Testes automatizados", "Git", "Metodologias ágeis"],
15-
},
16-
];
3+
import Reveal from "./Reveal";
4+
import { useLanguage } from "@/lib/useLanguage";
175

186
export default function About() {
7+
const { t } = useLanguage();
8+
199
return (
2010
<section id="sobre" className="scroll-mt-20 py-28 px-6 border-t border-line">
2111
<div className="max-w-[1120px] mx-auto">
2212
<Reveal>
23-
<p className="label-mono">Sobre</p>
13+
<p className="label-mono">{t.about.label}</p>
2414
</Reveal>
2515

2616
<Reveal delay={0.06} className="mt-7">
2717
<h2 className="text-[clamp(28px,4.2vw,48px)] font-semibold tracking-[-0.025em] leading-[1.14] max-w-[920px] text-fg text-balance">
28-
Construo aplicações fullstack do início ao fim — back-end robusto em
29-
.NET e front-end refinado em React, em ambientes ágeis com testes
30-
automatizados e CI/CD.
18+
{t.about.headline}
3119
</h2>
3220
</Reveal>
3321

3422
<div className="grid grid-cols-[repeat(auto-fit,minmax(240px,1fr))] gap-7 mt-[72px]">
35-
{groups.map((group, i) => (
23+
{t.about.groups.map((group, i) => (
3624
<Reveal key={group.label} delay={0.04 + i * 0.08}>
3725
<p className="font-mono text-xs tracking-[0.04em] text-muted mb-[18px]">
3826
{group.label}

components/Contact.tsx

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,38 @@
1-
import Reveal from "./Reveal";
1+
"use client";
22

3-
const socials = [
4-
{
5-
label: "LinkedIn ↗",
6-
href: "https://www.linkedin.com/in/matheus-louzadaa/",
7-
primary: true,
8-
},
9-
// TODO: trocar 55SEUNUMERO pelo teu número (DDI+DDD+número, só dígitos, ex: 5521999998888)
10-
{
11-
label: "WhatsApp ↗",
12-
href: "https://wa.me/55SEUNUMERO?text=Ol%C3%A1%20Matheus%2C%20vi%20seu%20portf%C3%B3lio!",
13-
primary: false,
14-
},
15-
{ label: "GitHub ↗", href: "https://github.com/mtlouzada", primary: false },
16-
];
3+
import Reveal from "./Reveal";
4+
import { useLanguage } from "@/lib/useLanguage";
175

186
export default function Contact() {
7+
const { t } = useLanguage();
8+
9+
const socials = [
10+
{
11+
label: "LinkedIn ↗",
12+
href: "https://www.linkedin.com/in/matheus-louzadaa/",
13+
primary: true,
14+
},
15+
{ label: "WhatsApp ↗", href: t.contact.whatsappHref, primary: false },
16+
{ label: "GitHub ↗", href: "https://github.com/mtlouzada", primary: false },
17+
];
18+
1919
return (
2020
<section
2121
id="contato"
2222
className="scroll-mt-20 py-[150px] px-6 border-t border-line text-center"
2323
>
2424
<Reveal className="max-w-[760px] mx-auto">
25-
<p className="label-mono">Contato</p>
25+
<p className="label-mono">{t.contact.label}</p>
2626
<h2 className="text-[clamp(40px,7.5vw,86px)] font-semibold tracking-[-0.035em] leading-[1.02] mt-6 text-fg">
27-
Vamos conversar.
27+
{t.contact.title}
2828
</h2>
2929
<p className="mt-7 text-[clamp(17px,2.4vw,21px)] leading-[1.55] text-muted max-w-[520px] mx-auto text-pretty">
30-
Me manda uma mensagem no LinkedIn ou no WhatsApp — respondo por lá. E se
31-
curtir o trabalho, bora trocar um follow no GitHub.
30+
{t.contact.description}
3231
</p>
3332
<div className="flex gap-3 justify-center flex-wrap mt-[46px]">
3433
{socials.map((s) => (
3534
<a
36-
key={s.href}
35+
key={s.label}
3736
href={s.href}
3837
target="_blank"
3938
rel="noopener noreferrer"

components/Footer.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
"use client";
2+
3+
import { useLanguage } from "@/lib/useLanguage";
4+
15
export default function Footer() {
6+
const { t } = useLanguage();
7+
28
return (
39
<footer className="border-t border-line py-[34px] px-6">
410
<div className="max-w-[1120px] mx-auto flex items-center justify-between flex-wrap gap-3 font-mono text-[13px] text-muted">
5-
<span>Matheus Louzada — Brasil</span>
11+
<span>{t.footer.tagline}</span>
612
<span>{new Date().getFullYear()}</span>
713
</div>
814
</footer>

components/Hero.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
"use client";
2+
13
import Image from "next/image";
24
import Reveal from "./Reveal";
5+
import { useLanguage } from "@/lib/useLanguage";
36

47
export default function Hero() {
8+
const { t } = useLanguage();
9+
510
return (
611
<section id="top" className="max-w-[1120px] mx-auto px-6 pt-36 pb-28">
712
<div className="flex flex-col md:flex-row-reverse items-center gap-12 md:gap-16">
813
{/* text — right on desktop */}
914
<div className="flex-1 min-w-0 text-center md:text-left">
1015
<Reveal delay={0.04}>
11-
<p className="label-mono">Desenvolvedor Fullstack</p>
16+
<p className="label-mono">{t.hero.role}</p>
1217
</Reveal>
1318

1419
<Reveal delay={0.1} className="mt-6">
@@ -21,9 +26,7 @@ export default function Hero() {
2126

2227
<Reveal delay={0.18} className="mt-7">
2328
<p className="max-w-[540px] mx-auto md:mx-0 text-[clamp(16px,2vw,20px)] leading-[1.55] text-muted text-pretty">
24-
Fullstack .NET com C# e ASP.NET Core no back-end — APIs REST
25-
escaláveis com SQL Server e Entity Framework. React e TypeScript no
26-
front-end, cobrindo o fluxo completo da interface à API e ao banco.
29+
{t.hero.description}
2730
</p>
2831
</Reveal>
2932

@@ -33,7 +36,7 @@ export default function Hero() {
3336
href="#projetos"
3437
className="px-7 py-3.5 rounded-pill bg-accent text-white font-medium text-[15px] transition-transform duration-300 hover:-translate-y-0.5 hover:shadow-[0_12px_28px_-8px_rgba(91,91,214,0.55)]"
3538
>
36-
Ver projetos
39+
{t.hero.viewProjects}
3740
</a>
3841
<a
3942
href="https://github.com/mtlouzada"
@@ -55,15 +58,15 @@ export default function Hero() {
5558
</Reveal>
5659
</div>
5760

58-
{/* photo — left on desktop */}
59-
<Reveal delay={0.34} className="w-full max-w-[420px] md:max-w-[460px] shrink-0">
60-
<div className="relative w-full aspect-[4/5] rounded-[28px] overflow-hidden shadow-elevated">
61+
{/* photo — GitHub-style circular avatar, left on desktop */}
62+
<Reveal delay={0.34} className="shrink-0">
63+
<div className="relative w-[220px] sm:w-[260px] md:w-[300px] aspect-square rounded-full overflow-hidden ring-1 ring-line shadow-elevated">
6164
<Image
6265
src="/imgs/newphoto.jpg"
6366
alt="Matheus Louzada"
6467
fill
6568
priority
66-
sizes="(max-width: 768px) 100vw, 460px"
69+
sizes="(max-width: 768px) 260px, 300px"
6770
className="object-cover"
6871
/>
6972
</div>

0 commit comments

Comments
 (0)