Skip to content

Commit a4e5c6e

Browse files
committed
feat: add isolated onchain (/cripto) world and revamp navbar
- New /cripto route as a self-contained brutalist onchain portfolio with its own theme, retro-OS windows, marquees and CSS animations - Sections: hero, stats, contributions, disciplines, NFT gallery (placeholder data), contact; content driven by app/cripto/_data.ts - Redesign main navbar: ML monogram logo, centered links, refined Cripto portal link with live pulse; mobile menu adds Cripto + Email
1 parent f0b789d commit a4e5c6e

16 files changed

Lines changed: 1334 additions & 10 deletions
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { CSSProperties } from "react";
2+
import Reveal from "@/components/Reveal";
3+
import { contributions } from "../_data";
4+
5+
const fontClass: Record<string, string> = {
6+
display: "c-display",
7+
serif: "c-serif text-[clamp(24px,4vw,42px)]",
8+
mono: "c-mono font-semibold uppercase tracking-tight",
9+
};
10+
11+
export default function Contributions() {
12+
return (
13+
<section id="builds" className="scroll-mt-24 border-b-2 border-[var(--c-ink)]">
14+
<div className="max-w-[1160px] mx-auto px-5 py-20">
15+
<Reveal className="flex items-end justify-between mb-10 gap-4">
16+
<div>
17+
<p className="c-label mb-3">[ 02 — selected builds ]</p>
18+
<h2 className="c-display text-[clamp(30px,5vw,58px)]">
19+
O portfólio é o ponto.
20+
</h2>
21+
</div>
22+
<span className="c-mono text-[11px] text-[var(--c-ink-soft)] hidden sm:block">
23+
hover p/ abrir ↗
24+
</span>
25+
</Reveal>
26+
27+
<div className="border-t-2 border-[var(--c-ink)]">
28+
{contributions.map((c) => (
29+
<Reveal key={c.title}>
30+
<a
31+
href={c.href}
32+
target="_blank"
33+
rel="noopener noreferrer"
34+
className="row-link group flex items-center gap-4 md:gap-8 py-5 md:py-6 px-2 md:px-4 border-b-2 border-[var(--c-ink)]"
35+
style={
36+
{ ["--row-accent" as string]: `var(${c.accent})` } as CSSProperties
37+
}
38+
>
39+
<span className="c-mono text-[11px] w-7 shrink-0 group-hover:text-[var(--c-white)] transition-colors">
40+
{c.index}
41+
</span>
42+
<span
43+
className={`flex-1 min-w-0 text-[clamp(22px,4vw,42px)] leading-none group-hover:text-[var(--c-white)] transition-colors ${fontClass[c.font]}`}
44+
>
45+
{c.title}
46+
</span>
47+
<span className="c-mono text-[10px] tracking-[0.1em] uppercase text-right text-[var(--c-ink-soft)] group-hover:text-[var(--c-white)] transition-colors hidden sm:block">
48+
{c.role}
49+
<br />
50+
{c.meta}
51+
</span>
52+
<span className="row-arrow c-mono text-lg group-hover:text-[var(--c-white)] transition-colors">
53+
54+
</span>
55+
</a>
56+
</Reveal>
57+
))}
58+
</div>
59+
</div>
60+
</section>
61+
);
62+
}

app/cripto/_components/CountUp.tsx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"use client";
2+
3+
import { useEffect, useRef, useState } from "react";
4+
5+
type CountUpProps = {
6+
value: number;
7+
suffix?: string;
8+
duration?: number; // ms
9+
};
10+
11+
/** Counts from 0 to `value` once it scrolls into view. */
12+
export default function CountUp({
13+
value,
14+
suffix = "",
15+
duration = 1400,
16+
}: CountUpProps) {
17+
const ref = useRef<HTMLSpanElement>(null);
18+
const [n, setN] = useState(0);
19+
const started = useRef(false);
20+
21+
useEffect(() => {
22+
const el = ref.current;
23+
if (!el) return;
24+
25+
const reduce =
26+
window.matchMedia &&
27+
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
28+
if (reduce) {
29+
setN(value);
30+
return;
31+
}
32+
33+
const run = () => {
34+
if (started.current) return;
35+
started.current = true;
36+
const start = performance.now();
37+
const tick = (now: number) => {
38+
const t = Math.min((now - start) / duration, 1);
39+
const eased = 1 - Math.pow(1 - t, 3);
40+
setN(Math.round(value * eased));
41+
if (t < 1) requestAnimationFrame(tick);
42+
};
43+
requestAnimationFrame(tick);
44+
};
45+
46+
const io = new IntersectionObserver(
47+
(entries) => {
48+
entries.forEach((e) => {
49+
if (e.isIntersecting) {
50+
run();
51+
io.disconnect();
52+
}
53+
});
54+
},
55+
{ threshold: 0.4 }
56+
);
57+
io.observe(el);
58+
return () => io.disconnect();
59+
}, [value, duration]);
60+
61+
return (
62+
<span ref={ref}>
63+
{n}
64+
{suffix}
65+
</span>
66+
);
67+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import Window from "./Window";
5+
6+
const EMAIL = "matheuslouzadaa@gmail.com";
7+
8+
export default function CriptoContact() {
9+
const [name, setName] = useState("");
10+
const [from, setFrom] = useState("");
11+
const [msg, setMsg] = useState("");
12+
13+
const submit = (e: React.FormEvent) => {
14+
e.preventDefault();
15+
const subject = encodeURIComponent(`Contato onchain — ${name || "sem nome"}`);
16+
const body = encodeURIComponent(
17+
`${msg}\n\n— ${name}\n${from}`
18+
);
19+
window.location.href = `mailto:${EMAIL}?subject=${subject}&body=${body}`;
20+
};
21+
22+
return (
23+
<section
24+
id="contato"
25+
className="scroll-mt-24 border-b-2 border-[var(--c-ink)] bg-[var(--c-teal)]"
26+
>
27+
<div className="max-w-[1160px] mx-auto px-5 py-20 grid md:grid-cols-[0.9fr_1.1fr] gap-10 items-center">
28+
<div className="text-[var(--c-white)]">
29+
<p className="c-label mb-3 !text-[var(--c-white)]/70">
30+
[ 05 — new_message.exe ]
31+
</p>
32+
<h2 className="c-display text-[clamp(30px,5.4vw,58px)]">
33+
Bora
34+
<br />
35+
construir?
36+
</h2>
37+
<p className="c-mono text-[13px] leading-[1.7] mt-5 max-w-[360px] text-[var(--c-white)]/80">
38+
Colaboração, contribuição ou uma ideia onchain — respondo tudo que
39+
for sério.
40+
</p>
41+
<div className="flex flex-wrap gap-3 mt-7">
42+
<a
43+
href="https://github.com/mtlouzada"
44+
target="_blank"
45+
rel="noopener noreferrer"
46+
className="c-tag !border-[var(--c-white)] !text-[var(--c-white)] !bg-transparent"
47+
>
48+
GITHUB
49+
</a>
50+
<a
51+
href="https://www.linkedin.com/in/matheus-louzadaa/"
52+
target="_blank"
53+
rel="noopener noreferrer"
54+
className="c-tag !border-[var(--c-white)] !text-[var(--c-white)] !bg-transparent"
55+
>
56+
LINKEDIN
57+
</a>
58+
<span className="c-tag !border-[var(--c-lime)] !text-[var(--c-lime)] !bg-transparent">
59+
LOUZOSHI.ETH
60+
</span>
61+
</div>
62+
</div>
63+
64+
<Window
65+
title="new_message.exe — LOUZOSHI"
66+
accent="--c-red"
67+
bodyClassName="p-6 bg-[var(--c-paper)]"
68+
>
69+
<form onSubmit={submit} className="flex flex-col gap-4">
70+
<div className="grid grid-cols-2 gap-4">
71+
<input
72+
className="c-field"
73+
placeholder="nome"
74+
value={name}
75+
onChange={(e) => setName(e.target.value)}
76+
/>
77+
<input
78+
className="c-field"
79+
type="email"
80+
placeholder="you@email.com"
81+
value={from}
82+
onChange={(e) => setFrom(e.target.value)}
83+
/>
84+
</div>
85+
<textarea
86+
className="c-field min-h-[110px] resize-y"
87+
placeholder="conta a ideia..."
88+
value={msg}
89+
onChange={(e) => setMsg(e.target.value)}
90+
/>
91+
<button type="submit" className="c-btn c-btn-red self-start">
92+
Enviar mensagem →
93+
</button>
94+
</form>
95+
</Window>
96+
</div>
97+
</section>
98+
);
99+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import Link from "next/link";
2+
import Ticker from "./Ticker";
3+
4+
const footerItems = [
5+
"LET'S BUILD SOMETHING",
6+
"MATHEUSLOUZADAA@GMAIL.COM",
7+
"LOUZOSHI.ETH",
8+
"ART",
9+
"TECH",
10+
"WEB3",
11+
];
12+
13+
export default function CriptoFooter() {
14+
return (
15+
<footer className="bg-[var(--c-ink)] text-[var(--c-white)]">
16+
<div className="border-b-2 border-[var(--c-white)]/20 py-3">
17+
<Ticker items={footerItems} duration={30} sep="+" />
18+
</div>
19+
<div className="max-w-[1160px] mx-auto px-5 py-10 flex flex-wrap items-center justify-between gap-6">
20+
<Link href="/cripto" className="c-display text-2xl flex items-center gap-2">
21+
<span className="text-[var(--c-red)]"></span>LOUZOSHI
22+
</Link>
23+
<div className="flex flex-wrap gap-5 c-mono text-[11px] tracking-[0.08em] uppercase">
24+
<Link href="/" className="hover:text-[var(--c-lime)] transition-colors">
25+
← Portfólio
26+
</Link>
27+
<a
28+
href="https://github.com/mtlouzada"
29+
target="_blank"
30+
rel="noopener noreferrer"
31+
className="hover:text-[var(--c-lime)] transition-colors"
32+
>
33+
GitHub
34+
</a>
35+
<a
36+
href="https://www.linkedin.com/in/matheus-louzadaa/"
37+
target="_blank"
38+
rel="noopener noreferrer"
39+
className="hover:text-[var(--c-lime)] transition-colors"
40+
>
41+
LinkedIn
42+
</a>
43+
</div>
44+
<p className="c-mono text-[10px] tracking-[0.1em] text-[var(--c-white)]/50 w-full md:w-auto">
45+
© {new Date().getFullYear()} MATHEUS LOUZADA · ONCHAIN MODE
46+
</p>
47+
</div>
48+
</footer>
49+
);
50+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"use client";
2+
3+
import Link from "next/link";
4+
5+
export default function CriptoHero() {
6+
return (
7+
<section className="relative border-b-2 border-[var(--c-ink)] overflow-hidden">
8+
{/* floating background shapes */}
9+
<div className="pointer-events-none absolute inset-0 -z-0">
10+
<div className="absolute top-[12%] left-[6%] w-16 h-16 border-2 border-[var(--c-ink)] rotate-12 float-y opacity-40" />
11+
<div
12+
className="absolute bottom-[18%] right-[10%] w-10 h-10 rounded-full bg-[var(--c-blue)] float-y opacity-60"
13+
style={{ animationDelay: "1.2s" }}
14+
/>
15+
<div
16+
className="absolute top-[30%] right-[24%] w-0 h-0 float-y opacity-50"
17+
style={{
18+
animationDelay: "0.6s",
19+
borderLeft: "14px solid transparent",
20+
borderRight: "14px solid transparent",
21+
borderBottom: "24px solid var(--c-lime)",
22+
}}
23+
/>
24+
</div>
25+
26+
<div className="relative max-w-[1160px] mx-auto px-5 py-16 md:py-24 grid md:grid-cols-[1.1fr_0.9fr] gap-12 items-center">
27+
{/* left: copy */}
28+
<div>
29+
<p className="c-label mb-6 flex items-center gap-2">
30+
<span className="text-[var(--c-red)]"></span> onchain builder ·
31+
open source
32+
</p>
33+
34+
<h1 className="c-display text-[clamp(44px,8.5vw,92px)]">
35+
I BUILD FOR
36+
<br />
37+
THE{" "}
38+
<span
39+
className="glitch"
40+
data-text="ONCHAIN"
41+
>
42+
ONCHAIN
43+
</span>
44+
<br />
45+
<span className="blink">UNDERGROUND</span>
46+
</h1>
47+
48+
<p className="c-mono text-[13px] leading-[1.7] mt-7 max-w-[440px] text-[var(--c-ink-soft)]">
49+
Dev fullstack contribuindo com projetos open-source de web3 e
50+
cultura digital — de plataformas de comunidade a ferramentas
51+
onchain. Aqui vive o lado cripto do meu trabalho.
52+
</p>
53+
54+
<div className="flex flex-wrap gap-3.5 mt-9">
55+
<a href="#builds" className="c-btn c-btn-red">
56+
Ver builds →
57+
</a>
58+
<a
59+
href="https://github.com/mtlouzada"
60+
target="_blank"
61+
rel="noopener noreferrer"
62+
className="c-btn"
63+
>
64+
GitHub ↗
65+
</a>
66+
</div>
67+
68+
<div className="flex flex-wrap gap-2.5 mt-8">
69+
{["SOLIDITY", "REACT", "WEB3", "NFTs"].map((t) => (
70+
<span key={t} className="c-tag">
71+
{t}
72+
</span>
73+
))}
74+
</div>
75+
</div>
76+
77+
{/* right: geometric halftone panel */}
78+
<div className="relative aspect-[5/4] w-full border-2 border-[var(--c-ink)] bg-[var(--c-red)] overflow-hidden shadow-[6px_6px_0_var(--c-ink)]">
79+
<div
80+
className="halftone absolute inset-0 opacity-40"
81+
style={{ ["--dot" as string]: "var(--c-ink)" }}
82+
/>
83+
{/* rotating dashed ring */}
84+
<div className="absolute inset-0 grid place-items-center">
85+
<div
86+
className="spin-slow w-[62%] aspect-square rounded-full border-2 border-dashed border-[var(--c-white)]/70"
87+
/>
88+
</div>
89+
{/* pulsing circle */}
90+
<div className="absolute inset-0 grid place-items-center">
91+
<div className="pulse-dot w-[42%] aspect-square rounded-full bg-[var(--c-white)]" />
92+
</div>
93+
{/* blue block */}
94+
<div className="absolute bottom-5 left-5 w-16 h-8 bg-[var(--c-blue)] border-2 border-[var(--c-ink)]" />
95+
{/* corner label */}
96+
<span className="absolute top-3 left-3 c-mono text-[10px] tracking-[0.14em] text-[var(--c-white)]">
97+
SYS://ONCHAIN
98+
</span>
99+
<Link
100+
href="#builds"
101+
className="absolute bottom-3 right-3 c-mono text-[10px] tracking-[0.14em] text-[var(--c-white)] hover:underline"
102+
>
103+
SCROLL ↓
104+
</Link>
105+
</div>
106+
</div>
107+
</section>
108+
);
109+
}

0 commit comments

Comments
 (0)