Light mode

This commit is contained in:
2026-03-11 23:27:19 +01:00 Verified
parent 658a8edf15
commit 3cda989390
16 changed files with 345 additions and 237 deletions
+17 -5
View File
@@ -2,8 +2,10 @@
'use client';
import { useState, useEffect } from 'react';
import { useTheme } from 'next-themes';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { oneDark, oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
const pythonCode = `import quantum_entanglement
import neural_net_vibes
@@ -44,16 +46,26 @@ if __name__ == "__main__":
analyzer.check_is_sandwich(target="glizzy")`;
export default function BlurredCode() {
const { resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
const timer = setTimeout(() => setMounted(true), 0);
return () => clearTimeout(timer);
}, []);
return (
<div className="absolute inset-0 overflow-hidden bg-[#0d1117] z-0 pointer-events-none flex justify-center">
<div className="relative w-full h-full text-left p-8 opacity-40 blur-[2px] group-hover:blur-none group-hover:opacity-100 transition-all duration-700 animate-[scrollUp_40s_linear_infinite]">
<div className="absolute inset-0 overflow-hidden bg-slate-50 dark:bg-[#0d1117] transition-colors duration-300 z-0 pointer-events-none flex justify-center">
<div className="relative w-full h-full text-left p-8 opacity-40 blur-[3px] group-hover:blur-[2px] group-hover:opacity-100 transition-all duration-700 animate-[scrollUp_40s_linear_infinite] [&_pre]:bg-transparent! [&_code]:bg-transparent!">
{mounted && (
<SyntaxHighlighter
language="python"
style={vscDarkPlus}
customStyle={{ background: 'transparent', margin: 0, padding: 0, fontSize: '14px' }}
style={resolvedTheme === 'light' ? oneLight : oneDark}
customStyle={{ margin: 0, padding: 0, fontSize: '14px' }}
>
{pythonCode + '\n\n\n' + pythonCode + '\n\n\n' + pythonCode}
</SyntaxHighlighter>
)}
</div>
</div>
);
+28 -8
View File
@@ -2,23 +2,41 @@
'use client';
import { useEffect, useRef } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useTheme } from 'next-themes';
interface MatrixRainProps {
color?: string;
fps?: number;
}
export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainProps) {
export default function MatrixRain({ color, fps = 15 }: MatrixRainProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
const lastWidth = useRef<number>(0);
const { resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
const timer = setTimeout(() => setMounted(true), 0);
return () => clearTimeout(timer);
}, []);
useEffect(() => {
if (!mounted) return;
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
const isLight = resolvedTheme === 'light';
// Use slate-50 (#f8fafc) for light mode, #0d1117 for dark mode
const bgColor = isLight ? '#f8fafc' : '#0d1117';
// The semi-transparent overlay that creates the fading trail effect
const fadeColor = isLight ? 'rgba(248, 250, 252, 0.2)' : 'rgba(13, 17, 23, 0.2)';
// A darker green for light mode to maintain contrast, or the default/prop color for dark mode
const textColor = color || (isLight ? '#1c2d25' : '#84c0a0');
const fontSize = 16;
let columns = 0;
let drops: number[] = [];
@@ -26,7 +44,7 @@ export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainPr
const setCanvasSize = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight + 120;
ctx.fillStyle = '#0d1117';
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
};
@@ -43,13 +61,13 @@ export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainPr
initDrops();
const draw = () => {
ctx.fillStyle = 'rgba(13, 17, 23, 0.2)';
ctx.fillStyle = fadeColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = `bold ${fontSize}px monospace`;
for (let i = 0; i < drops.length; i++) {
const text = Math.random() > 0.5 ? '0' : '1';
ctx.fillStyle = color;
ctx.fillStyle = textColor;
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
@@ -75,14 +93,16 @@ export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainPr
clearInterval(intervalId);
window.removeEventListener('resize', handleResize);
};
}, [color, fps]);
}, [color, fps, resolvedTheme, mounted]); // Re-run effect if theme changes
return (
<div className="fixed inset-0 pointer-events-none w-screen h-[110vh] bg-[#0d1117]" style={{ zIndex: -1 }}>
<div className="fixed inset-0 pointer-events-none w-screen h-[110vh] bg-slate-50 dark:bg-[#0d1117] transition-colors duration-300" style={{ zIndex: -1 }}>
{mounted && (
<canvas
ref={canvasRef}
className="absolute inset-0 w-full h-full opacity-[0.15] blur-[0.5px]"
className="absolute inset-0 w-full h-full opacity-[0.35] dark:opacity-[0.15] blur-[0.5px]"
/>
)}
</div>
);
}
+36 -14
View File
@@ -3,51 +3,61 @@
'use client';
import Link from 'next/link';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import Image from 'next/image';
import { useTheme } from 'next-themes';
import { FaSun, FaMoon } from 'react-icons/fa';
export default function Navbar() {
const [isExpanded, setIsExpanded] = useState(false);
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
const timer = setTimeout(() => setMounted(true), 0);
return () => clearTimeout(timer);
}, []);
const toggleMenu = () => setIsExpanded(!isExpanded);
const closeMenu = () => setIsExpanded(false);
return (
<header className="fixed h-25 bg-[#0d1117]/80 backdrop-blur-md border-b border-white/10 left-0 right-0 z-100 transition-all duration-300">
<nav className="flex justify-between h-full items-center max-w-400 px-8 mx-auto">
<header className="fixed h-25 bg-white/80 dark:bg-[#0d1117]/80 backdrop-blur-md border-b border-slate-200 dark:border-white/10 left-0 right-0 z-100 transition-colors duration-300">
<nav className="flex justify-between h-full items-center max-w-450 px-8 mx-auto">
<Link href="/" className="group text-white no-underline flex uppercase font-extrabold items-center tracking-[1px] transition-transform hover:scale-105" onClick={closeMenu}>
<div className="w-12 h-12 flex justify-center items-center rounded-full bg-[#84c0a0]/10 border border-[#84c0a0]/30 shadow-[0_0_15px_rgba(132,192,160,0.2)] group-hover:bg-[#84c0a0]/20 transition-all duration-300">
<Link href="/" className="group text-slate-900 dark:text-white no-underline flex uppercase font-extrabold items-center tracking-[1px] transition-transform hover:scale-105" onClick={closeMenu}>
<div className="w-12 h-12 flex justify-center items-center rounded-full bg-[#84c0a0] dark:bg-[#84c0a0]/10 border border-[#84c0a0]/30 shadow-[0_0_15px_rgba(132,192,160,0.2)] group-hover:bg-[#84c0a0]/80 group-hover:dark:bg-[#84c0a0]/20 transition-all duration-300">
<Image
src="/assets/logos/logo.svg"
alt="Wiking"
width={32}
height={32}
className="w-8 h-8 filter dark:invert-0 invert"
className="w-8 h-8"
/>
</div>
<span className="hidden md:block ml-4 text-sm tracking-widest text-[#84c0a0] font-mono group-hover:text-white transition-colors">
<span className="hidden md:block ml-4 text-sm tracking-widest text-[#84c0a0] font-mono transition">
SODERBERG TECH
</span>
</Link>
<button
type="button"
className="cursor-pointer border-none bg-transparent w-10 h-10 flex items-center justify-center flex-col md:hidden relative group"
className="cursor-pointer border-none bg-transparent w-10 h-10 flex items-center justify-center flex-col md:hidden relative group z-50"
aria-expanded={isExpanded}
onClick={toggleMenu}
>
<span className={`block h-0.5 bg-white transition-all duration-300 ease-in-out group-hover:bg-[#84c0a0] ${isExpanded ? 'absolute m-0 w-7 rotate-45' : 'w-6 m-0.75'}`}></span>
<span className={`block h-0.5 bg-white transition-all duration-300 ease-in-out group-hover:bg-[#84c0a0] ${isExpanded ? 'opacity-0 w-0' : 'w-6 m-0.75'}`}></span>
<span className={`block h-0.5 bg-white transition-all duration-300 ease-in-out group-hover:bg-[#84c0a0] ${isExpanded ? 'absolute m-0 w-7 -rotate-45' : 'w-6 m-0.75'}`}></span>
<span className={`block h-0.5 bg-slate-900 dark:bg-white transition-all duration-300 ease-in-out group-hover:bg-[#84c0a0] ${isExpanded ? 'absolute m-0 w-7 rotate-45' : 'w-6 m-0.75'}`}></span>
<span className={`block h-0.5 bg-slate-900 dark:bg-white transition-all duration-300 ease-in-out group-hover:bg-[#84c0a0] ${isExpanded ? 'opacity-0 w-0' : 'w-6 m-0.75'}`}></span>
<span className={`block h-0.5 bg-slate-900 dark:bg-white transition-all duration-300 ease-in-out group-hover:bg-[#84c0a0] ${isExpanded ? 'absolute m-0 w-7 -rotate-45' : 'w-6 m-0.75'}`}></span>
</button>
<div
className={`fixed top-25 bottom-0 left-0 right-0 transition-all duration-300 md:static md:block md:opacity-100 md:visible md:h-full ${isExpanded ? 'bg-[#0d1117]/60 backdrop-blur-sm opacity-100 visible' : 'opacity-0 invisible'}`}
className={`fixed top-25 bottom-0 left-0 right-0 transition-all duration-300 md:static md:block md:opacity-100 md:visible md:h-full ${isExpanded ? 'bg-white/90 dark:bg-[#0d1117]/60 backdrop-blur-sm opacity-100 visible' : 'opacity-0 invisible'}`}
onClick={closeMenu}
>
<ul
className={`list-none absolute flex flex-col items-center left-0 right-0 m-4 rounded-3xl bg-[#131920]/70 backdrop-blur-2xl md:backdrop-blur-none border border-white/10 shadow-2xl md:m-0 md:p-0 md:border-none md:shadow-none md:static md:flex-row md:w-full md:h-full md:bg-transparent md:justify-end gap-2 md:gap-8 transition-all duration-300 ${isExpanded ? 'p-8 translate-y-0 opacity-100' : '-translate-y-4 opacity-0 md:translate-y-0 md:opacity-100'}`}
// Added md:dark:bg-transparent and md:dark:border-none to clear the mobile dark mode styling on desktop!
className={`list-none absolute flex flex-col items-center left-0 right-0 m-4 rounded-3xl bg-white/90 dark:bg-[#0d1117]/90 backdrop-blur-2xl md:backdrop-blur-none border border-slate-200 dark:border-white/10 md:border-none md:dark:border-none shadow-2xl md:m-0 md:p-0 md:shadow-none md:static md:flex-row md:w-full md:h-full md:bg-transparent md:dark:bg-transparent md:justify-end gap-2 md:gap-8 transition-all duration-300 ${isExpanded ? 'p-8 translate-y-0 opacity-100' : '-translate-y-4 opacity-0 md:translate-y-0 md:opacity-100'}`}
onClick={(e) => e.stopPropagation()}
>
{[
@@ -58,7 +68,7 @@ export default function Navbar() {
].map((link) => (
<li key={link.name} className="w-full md:w-auto">
<Link
className="relative flex justify-center items-center text-gray-300 uppercase font-bold tracking-[2px] text-sm px-4 py-3 rounded-xl hover:text-white hover:bg-white/5 transition-all duration-300 group overflow-hidden"
className="relative flex justify-center items-center text-slate-600 dark:text-gray-300 uppercase font-bold tracking-[2px] text-sm px-4 py-3 rounded-xl hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all duration-300 group overflow-hidden"
href={link.path}
onClick={closeMenu}
>
@@ -67,6 +77,18 @@ export default function Navbar() {
</Link>
</li>
))}
<li className="w-full md:w-auto flex justify-center mt-4 md:mt-0 md:pl-2">
{mounted && (
<button
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
className="p-3 md:p-2.5 rounded-full bg-slate-100 dark:bg-white/10 text-slate-600 dark:text-white hover:bg-slate-200 dark:hover:bg-white/20 transition-all flex items-center justify-center"
aria-label="Toggle Theme"
>
{theme === 'dark' ? <FaSun size={18} /> : <FaMoon size={18} />}
</button>
)}
</li>
</ul>
</div>
</nav>
+8 -5
View File
@@ -15,7 +15,7 @@ interface GalleryImage {
export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
return (
<div className="bg-[#0a0d11] flex justify-center w-full min-h-screen border-t border-white/5">
<div className="bg-slate-100 dark:bg-[#0a0d11] flex justify-center w-full min-h-screen border-t border-slate-200 dark:border-white/5 transition-colors duration-300">
<Gallery>
<div className="grid grid-cols-2 lg:grid-cols-4 2xl:grid-cols-6 grid-flow-dense w-full">
{images.map((img, index) => {
@@ -24,7 +24,7 @@ export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
return (
<div
key={index}
className={`relative bg-[#0d1117] overflow-hidden group cursor-pointer border-[0.5px] border-white/5 ${isHorizontal ? 'col-span-2' : 'col-span-1'}`}
className={`relative bg-slate-200 dark:bg-[#0d1117] overflow-hidden group cursor-pointer transition-colors duration-300 ${isHorizontal ? 'col-span-2' : 'col-span-1'}`}
>
<Item
original={img.src}
@@ -39,8 +39,11 @@ export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
onClick={open}
className="w-full h-full relative block min-h-75"
>
<div className="absolute inset-0 border-8 border-[#0d1117]/50 transition-all duration-300 z-10 pointer-events-none"></div>
<div className="absolute inset-4 border-2 border-white/10 transition-all duration-500 z-10 pointer-events-none group-hover:scale-95 group-hover:border-[#84c0a0]/60 [clip-path:polygon(0_calc(100%-1rem),0_100%,1rem_100%,1rem_0,0_0,0_1rem,100%_1rem,100%_0,calc(100%-1rem)_0,calc(100%-1rem)_100%,100%_100%,100%_calc(100%-1rem))]"></div>
{/* Outer Frame - Light border in light mode, Dark in dark mode */}
<div className="absolute inset-0 border-8 border-slate-100/10 dark:border-[#0d1117]/40 transition-colors duration-300 z-10 pointer-events-none"></div>
{/* Inner Hover Frame */}
<div className="absolute inset-4 border-2 border-slate-300/50 dark:border-white/10 transition-all duration-500 z-10 pointer-events-none group-hover:scale-95 group-hover:border-[#84c0a0]/80 dark:group-hover:border-[#84c0a0]/60 [clip-path:polygon(0_calc(100%-1rem),0_100%,1rem_100%,1rem_0,0_0,0_1rem,100%_1rem,100%_0,calc(100%-1rem)_0,calc(100%-1rem)_100%,100%_100%,100%_calc(100%-1rem))]"></div>
<Image
src={img.src}
@@ -49,7 +52,7 @@ export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
height={isHorizontal ? 800 : 800}
quality={90}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="w-full h-full object-cover block opacity-80 transition-all duration-700 group-hover:scale-110 group-hover:opacity-100"
className="w-full h-full object-cover block transition-all duration-700 group-hover:scale-110 group-hover:opacity-100 dark:group-hover:opacity-100"
/>
</div>
)}
+14
View File
@@ -0,0 +1,14 @@
// app/components/ThemeProvider.tsx
'use client';
import { ThemeProvider as NextThemesProvider } from 'next-themes';
import { ReactNode } from 'react';
export function ThemeProvider({ children }: { children: ReactNode }) {
return (
<NextThemesProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</NextThemesProvider>
);
}
+20 -20
View File
@@ -5,7 +5,7 @@ import Image from 'next/image';
export default function ContactPage() {
return (
<main className="flex flex-col flex-1 relative bg-[#0d1117] overflow-hidden">
<main className="flex flex-col flex-1 relative bg-slate-50 dark:bg-[#0d1117] overflow-hidden transition-colors duration-300">
{/* 1. Immersive Mountain Background */}
<Image
@@ -16,14 +16,14 @@ export default function ContactPage() {
className="absolute inset-0 w-full h-full object-cover z-0"
/>
{/* Dark blur overlay so the text and cards remain perfectly readable */}
<div className="absolute inset-0 bg-[#0d1117]/85 backdrop-blur-md z-0"></div>
<div className="absolute inset-0 bg-slate-100/30 dark:bg-[#0d1117]/85 backdrop-blur-md z-0 transition-colors duration-300"></div>
<div className="h-25 shrink-0 z-10"></div>
<section className="relative z-10 flex-1 flex flex-col justify-center items-center py-12 px-6">
<div className="mb-12 text-center">
<h1 className="text-white text-[40px] md:text-[55px] uppercase font-black tracking-tighter drop-shadow-lg">
<h1 className="text-slate-900 dark:text-white text-[40px] md:text-[55px] uppercase font-black tracking-tighter drop-shadow-lg transition-colors">
Find me here!
</h1>
<p className="text-[#84c0a0] font-mono font-bold tracking-widest mt-2 uppercase">
@@ -31,20 +31,20 @@ export default function ContactPage() {
</p>
</div>
<div className="w-full max-w-3xl bg-white/5 backdrop-blur-xl rounded-4xl border border-white/10 shadow-[0_8px_32px_rgba(0,0,0,0.5)] p-8 md:p-12">
<div className="w-full max-w-3xl bg-white/80 dark:bg-white/5 backdrop-blur-xl rounded-4xl border border-slate-200 dark:border-white/10 shadow-xl dark:shadow-[0_8px_32px_rgba(0,0,0,0.5)] p-8 md:p-12 transition-colors duration-300">
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
<div className="flex flex-col gap-8">
<h3 className="text-white text-xl font-bold border-b border-white/10 pb-4 uppercase tracking-wider">Direct Info</h3>
<h3 className="text-slate-900 dark:text-white text-xl font-bold border-b border-slate-200 dark:border-white/10 pb-4 uppercase tracking-wider transition-colors">Direct Info</h3>
<div className="flex items-center gap-4 group">
<div className="w-12 h-12 rounded-2xl bg-[#84c0a0]/10 flex items-center justify-center border border-[#84c0a0]/30 group-hover:bg-[#84c0a0]/20 transition-all">
<FaEnvelope className="text-[#84c0a0] text-xl" />
</div>
<div>
<p className="text-gray-400 text-xs uppercase font-bold tracking-widest">Email</p>
<a href="mailto:support@soderberg.tech" className="text-white font-medium hover:text-[#84c0a0] transition-colors break-all">
<p className="text-slate-500 dark:text-gray-400 text-xs uppercase font-bold tracking-widest transition-colors">Email</p>
<a href="mailto:support@soderberg.tech" className="text-slate-900 dark:text-white font-medium hover:text-[#84c0a0] dark:hover:text-[#84c0a0] transition-colors break-all">
support@soderberg.tech
</a>
</div>
@@ -55,35 +55,35 @@ export default function ContactPage() {
<FaMapMarkerAlt className="text-[#84c0a0] text-xl" />
</div>
<div>
<p className="text-gray-400 text-xs uppercase font-bold tracking-widest">Location</p>
<p className="text-white font-medium">Höganäs, Sweden</p>
<p className="text-slate-500 dark:text-gray-400 text-xs uppercase font-bold tracking-widest transition-colors">Location</p>
<p className="text-slate-900 dark:text-white font-medium transition-colors">Höganäs, Sweden</p>
</div>
</div>
</div>
<div className="flex flex-col gap-4">
<h3 className="text-white text-xl font-bold border-b border-white/10 pb-4 uppercase tracking-wider">Networks</h3>
<h3 className="text-slate-900 dark:text-white text-xl font-bold border-b border-slate-200 dark:border-white/10 pb-4 uppercase tracking-wider transition-colors">Networks</h3>
<div className="grid grid-cols-1 gap-3">
<a href="https://www.linkedin.com/in/william-s%C3%B6derberg-5b79bb247" target="_blank" className="flex items-center justify-between p-4 rounded-2xl bg-white/5 border border-white/5 hover:border-[#0077b5]/50 hover:bg-[#0077b5]/10 transition-all group">
<div className="flex items-center gap-3 text-white font-bold">
<a href="https://www.linkedin.com/in/william-s%C3%B6derberg-5b79bb247" target="_blank" className="flex items-center justify-between p-4 rounded-2xl bg-white/50 dark:bg-white/5 border border-slate-200 dark:border-white/5 hover:border-[#0077b5]/50 hover:bg-[#0077b5]/10 transition-all group">
<div className="flex items-center gap-3 text-slate-900 dark:text-white font-bold transition-colors">
<FaLinkedin className="text-xl text-[#0077b5]" /> LinkedIn
</div>
<span className="text-gray-500 group-hover:text-[#0077b5] group-hover:translate-x-1 transition-all"></span>
<span className="text-slate-400 dark:text-gray-500 group-hover:text-[#0077b5] group-hover:translate-x-1 transition-all"></span>
</a>
<a href="https://discordapp.com/users/271290165106966528" target="_blank" className="flex items-center justify-between p-4 rounded-2xl bg-white/5 border border-white/5 hover:border-[#5865F2]/50 hover:bg-[#5865F2]/10 transition-all group">
<div className="flex items-center gap-3 text-white font-bold">
<a href="https://discordapp.com/users/271290165106966528" target="_blank" className="flex items-center justify-between p-4 rounded-2xl bg-white/50 dark:bg-white/5 border border-slate-200 dark:border-white/5 hover:border-[#5865F2]/50 hover:bg-[#5865F2]/10 transition-all group">
<div className="flex items-center gap-3 text-slate-900 dark:text-white font-bold transition-colors">
<FaDiscord className="text-xl text-[#5865F2]" /> Discord
</div>
<span className="text-gray-500 group-hover:text-[#5865F2] group-hover:translate-x-1 transition-all"></span>
<span className="text-slate-400 dark:text-gray-500 group-hover:text-[#5865F2] group-hover:translate-x-1 transition-all"></span>
</a>
<a href="https://www.instagram.com/will.i.am.soderberg/" target="_blank" className="flex items-center justify-between p-4 rounded-2xl bg-white/5 border border-white/5 hover:border-[#E1306C]/50 hover:bg-[#E1306C]/10 transition-all group">
<div className="flex items-center gap-3 text-white font-bold">
<a href="https://www.instagram.com/will.i.am.soderberg/" target="_blank" className="flex items-center justify-between p-4 rounded-2xl bg-white/50 dark:bg-white/5 border border-slate-200 dark:border-white/5 hover:border-[#E1306C]/50 hover:bg-[#E1306C]/10 transition-all group">
<div className="flex items-center gap-3 text-slate-900 dark:text-white font-bold transition-colors">
<FaInstagram className="text-xl text-[#E1306C]" /> Instagram
</div>
<span className="text-gray-500 group-hover:text-[#E1306C] group-hover:translate-x-1 transition-all"></span>
<span className="text-slate-400 dark:text-gray-500 group-hover:text-[#E1306C] group-hover:translate-x-1 transition-all"></span>
</a>
</div>
</div>
@@ -92,7 +92,7 @@ export default function ContactPage() {
<div className="mt-12">
<a
href="mailto:support@soderberg.tech?subject=Contact%20me"
className="w-full flex items-center justify-center gap-3 py-5 rounded-2xl bg-[#84c0a0] text-[#0d1117] font-bold text-lg hover:scale-[1.02] active:scale-[0.98] transition-all shadow-[0_0_20px_rgba(132,192,160,0.3)]"
className="w-full flex items-center justify-center gap-3 py-5 rounded-2xl bg-[#84c0a0] text-white dark:text-[#0d1117] font-bold text-lg hover:scale-[1.02] active:scale-[0.98] transition-all shadow-[0_0_20px_rgba(132,192,160,0.3)]"
>
<FaEnvelope /> Send an Email
</a>
+5 -5
View File
@@ -30,7 +30,7 @@ export default async function GalleryPage() {
const images = await getImages();
return (
<main className="flex flex-col flex-1 relative bg-[#0d1117] overflow-hidden">
<main className="flex flex-col flex-1 relative bg-slate-50 dark:bg-[#0d1117] overflow-hidden transition-colors duration-300">
{/* 1. Background Ambient Glow */}
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-150 h-150 bg-[#84c0a0]/10 blur-[150px] rounded-full pointer-events-none z-0"></div>
@@ -40,8 +40,8 @@ export default async function GalleryPage() {
{/* 2. Modernized Header */}
<section className="relative z-10 flex flex-col justify-center items-center py-20 px-6">
<div className="text-center">
<h1 className="text-white text-[40px] md:text-[55px] uppercase font-black tracking-tighter drop-shadow-lg mb-4">
Visual Archives
<h1 className="text-slate-900 dark:text-white text-[40px] md:text-[55px] uppercase font-black tracking-tighter drop-shadow-lg mb-4 transition-colors">
Gallery
</h1>
<div className="flex items-center justify-center gap-4 mb-6">
@@ -52,8 +52,8 @@ export default async function GalleryPage() {
<div className="w-12 h-px bg-[#84c0a0]"></div>
</div>
<p className="text-gray-400 font-light max-w-2xl mx-auto text-lg leading-relaxed">
A curated collection of photographic captures. Finding the best subjects to capture on film, from natural landscapes to the night sky.
<p className="text-slate-600 dark:text-gray-400 font-light max-w-2xl mx-auto text-lg leading-relaxed transition-colors">
A curated collection of photograps. Finding the best subjects to capture, from natural landscapes to the night sky.
</p>
</div>
</section>
+2
View File
@@ -2,6 +2,8 @@
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@keyframes zoomIn {
0% {
opacity: 0;
+11 -13
View File
@@ -1,8 +1,9 @@
// app/layout.tsx
import Navbar from './components/Navbar';
import './globals.css';
import Link from 'next/link';
import Navbar from './components/Navbar';
import { ThemeProvider } from './components/ThemeProvider';
import './globals.css';
export const metadata = {
title: 'Soderberg Tech',
@@ -12,30 +13,27 @@ export const metadata = {
shortcut: '/assets/logos/logo.svg',
apple: '/assets/logos/logo.svg',
},
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body className="flex flex-col min-h-screen m-0 p-0 font-sans bg-[#0d1117]">
<html lang="en" suppressHydrationWarning>
<body className="flex flex-col min-h-screen m-0 p-0 font-sans bg-slate-50 dark:bg-[#0d1117] transition-colors duration-300">
<ThemeProvider>
<Navbar />
<main className="flex flex-col flex-1">
{children}
</main>
<footer className="w-full relative z-50 mt-auto border-t border-white/5">
<div className="bg-[#0d1117] flex justify-center items-center h-10">
<Link className="text-[#a0aab6] no-underline flex font-medium items-center hover:text-white transition-colors text-sm tracking-widest uppercase" href="/">
<footer className="w-full relative z-50 mt-auto border-t border-slate-200 dark:border-white/5 transition-colors duration-300">
<div className="bg-slate-100 dark:bg-[#0d1117] flex justify-center items-center h-10 transition-colors duration-300">
<Link className="text-slate-500 dark:text-[#a0aab6] no-underline flex font-medium items-center hover:text-slate-900 dark:hover:text-white transition-colors text-sm tracking-widest uppercase" href="/">
© William Söderberg {new Date().getFullYear()}
</Link>
</div>
</footer>
</ThemeProvider>
</body>
</html>
);
+51 -86
View File
@@ -8,29 +8,24 @@ import { TbCube3dSphere } from 'react-icons/tb';
import Image from 'next/image';
export default function Home() {
const calculateAge = (birthDateString: string): number => {
const today = new Date();
const birthDate = new Date(birthDateString);
let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
};
return (
<div className="relative w-full bg-[#0d1117] text-white overflow-hidden font-sans">
<div className="relative w-full bg-slate-50 dark:bg-[#0d1117] text-slate-900 dark:text-white overflow-hidden font-sans transition-colors duration-300">
{/* 1. HERO SECTION */}
<section className="relative h-screen min-h-175 flex flex-col justify-center items-center overflow-hidden">
{/* Ambient Overlay for contrast */}
<div className="absolute inset-0 bg-linear-to-b from-transparent via-[#0d1117]/50 to-[#0d1117] z-1"></div>
<div className="absolute inset-0 bg-linear-to-b from-transparent via-slate-50/50 to-slate-50 dark:via-[#0d1117]/50 dark:to-[#0d1117] z-1 transition-colors duration-300"></div>
<div className="relative z-10 flex flex-col items-center px-4">
<div className="bg-[#84c0a0] rounded-full h-45 w-45 md:h-55 md:w-55 flex justify-center items-center shadow-[0_0_50px_rgba(132,192,160,0.3)] animate-[zoomIn_1000ms_ease-out]">
@@ -40,12 +35,12 @@ export default function Home() {
<h2 className="text-[#84c0a0] font-mono font-bold tracking-[0.3em] uppercase mt-12 text-sm md:text-xl text-center">
Technical High School Engineer
</h2>
<h1 className="text-white text-center uppercase text-[3rem] md:text-[6rem] font-black leading-none mt-4 drop-shadow-2xl">
<h1 className="text-slate-900 dark:text-white text-center uppercase text-[3rem] md:text-[6rem] font-black leading-none mt-4 drop-shadow-lg dark:drop-shadow-2xl transition-colors">
William Söderberg
</h1>
<div className="mt-10 flex gap-4">
<Link href="/projects" className="bg-[#84c0a0] text-[#0d1117] px-8 py-3 rounded-full font-bold uppercase tracking-wider hover:scale-105 transition-transform shadow-lg">
<Link href="/projects" className="bg-[#84c0a0] text-white dark:text-[#0d1117] px-8 py-3 rounded-full font-bold uppercase tracking-wider hover:scale-105 transition-transform shadow-lg">
View Portfolios
</Link>
</div>
@@ -54,51 +49,42 @@ export default function Home() {
{/* 2. ABOUT ME SECTION */}
<section className="relative py-24 px-6">
{/* Background Glow */}
<div className="absolute top-1/2 left-0 -translate-y-1/2 w-125 h-125 bg-[#84c0a0]/5 blur-[120px] rounded-full pointer-events-none"></div>
<div className="absolute top-1/2 left-0 -translate-y-1/2 w-125 h-125 bg-[#84c0a0]/10 dark:bg-[#84c0a0]/5 blur-[120px] rounded-full pointer-events-none"></div>
<div className="max-w-6xl mx-auto">
{/* Subtitle Header */}
<div className="max-w-6xl mx-auto relative z-10">
<div className="text-center mb-12">
<h2 className="text-white text-4xl md:text-5xl font-black uppercase tracking-tighter">About Me</h2>
<h2 className="text-slate-900 dark:text-white text-4xl md:text-5xl font-black uppercase tracking-tighter transition-colors">About Me</h2>
<p className="text-[#84c0a0] mt-4 font-mono uppercase text-sm tracking-widest font-bold">Identity & Background</p>
</div>
<div className="bg-white/5 backdrop-blur-xl border border-white/10 rounded-[40px] overflow-hidden flex flex-col lg:flex-row shadow-2xl">
{/* Left Column: Profile with "Scanning" Effect */}
<div className="lg:w-2/5 relative group border-b lg:border-b-0 lg:border-r border-white/10">
<Image
src="/assets/images/profile_picture.jpg"
alt="William Söderberg"
width={800}
height={1000}
className="w-full h-full object-cover"
/>
<div className="absolute inset-0 bg-linear-to-t from-[#0d1117] via-transparent to-transparent opacity-60"></div>
<div className="bg-white/80 dark:bg-white/5 backdrop-blur-xl border border-slate-200 dark:border-white/10 rounded-[40px] overflow-hidden flex flex-col lg:flex-row shadow-xl dark:shadow-2xl transition-colors duration-300">
<div className="lg:w-2/5 relative group border-b lg:border-b-0 lg:border-r border-slate-200 dark:border-white/10">
<Image src="/assets/images/profile_picture.jpg" alt="William Söderberg" width={800} height={1000} className="w-full h-full object-cover" />
<div className="absolute inset-0 bg-linear-to-t from-black/80 dark:from-[#0d1117] via-transparent to-transparent opacity-60"></div>
<div className="absolute bottom-8 left-8">
<h3 className="text-white text-2xl font-bold uppercase tracking-tight">William Söderberg</h3>
<p className="text-[#84c0a0] font-mono text-sm mt-1">EST. 2002 | SWEDEN</p>
</div>
</div>
{/* Right Column: Bio Content */}
<div className="lg:w-3/5 p-8 md:p-16 flex flex-col justify-center">
<div className="flex items-center gap-4 mb-8">
<div className="w-12 h-1 border-t-2 border-[#84c0a0]"></div>
<h2 className="text-white text-3xl font-bold uppercase tracking-widest">DATA CARD</h2>
<h2 className="text-slate-900 dark:text-white text-3xl font-bold uppercase tracking-widest transition-colors">DATA CARD</h2>
</div>
<p className="text-gray-300 text-lg leading-relaxed font-light">
My name is William Söderberg and I&apos;m {calculateAge("2002-07-17")} years old. I have a degree in technical high school engineering specialized in design and industrial manufacturing, with heavy influence from IT and coding. I love problem solving and finding new ways to solve the most complicated problems.
<p className="text-slate-600 dark:text-gray-300 text-lg leading-relaxed font-light transition-colors">
My name is William Söderberg and I&apos;m {calculateAge("2002-07-17")} years old. I have a degree in technical
high school engineering specialized in design and industrial manufacturing, with heavy influence from IT and coding.
I love problem solving and finding new ways to solve the most complicated problems. Currently studying Computer Science at LTH in Lund.
</p>
<div className="mt-10 grid grid-cols-2 gap-6 border-t border-white/10 pt-10">
<div className="mt-10 grid grid-cols-2 gap-6 border-t border-slate-200 dark:border-white/10 pt-10 transition-colors">
<div>
<p className="text-xs font-bold text-[#84c0a0] uppercase tracking-widest mb-1">Focus</p>
<p className="text-white font-medium text-sm">Industrial Design & IT</p>
<p className="text-slate-900 dark:text-white font-medium text-sm transition-colors">Industrial Design & IT</p>
</div>
<div>
<p className="text-xs font-bold text-[#84c0a0] uppercase tracking-widest mb-1">Passions</p>
<p className="text-white font-medium text-sm">Volleyball & Computers</p>
<p className="text-slate-900 dark:text-white font-medium text-sm transition-colors">Volleyball & Computers</p>
</div>
</div>
</div>
@@ -108,28 +94,27 @@ export default function Home() {
{/* 3. WHAT DO I DO SECTION */}
<section className="relative py-24 px-6 overflow-hidden">
{/* Subtle Background Image Integration */}
<Image src="/assets/images/leaves.jpg" alt="Leaves" fill className="object-cover z-0" />
<div className="absolute inset-0 bg-[#0d1117]/50 z-0"></div>
<Image src="/assets/images/leaves.jpg" alt="Leaves" fill className="object-cover z-0 opacity-80" />
<div className="absolute inset-0 bg-slate-50/20 dark:bg-[#0d1117]/50 z-0 transition-colors duration-300"></div>
<div className="relative z-10 max-w-6xl mx-auto">
<div className="text-center mb-16">
<h2 className="text-white text-4xl md:text-5xl font-black uppercase tracking-tighter">What do I do?</h2>
<h2 className="text-slate-900 dark:text-white text-4xl md:text-5xl font-black uppercase tracking-tighter transition-colors">What do I do?</h2>
<p className="text-[#84c0a0] mt-4 font-mono uppercase text-sm tracking-widest font-bold">A multidisciplinary engineer</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div className="flex flex-wrap justify-center gap-6">
{[
{ icon: <FaVolleyballBall />, title: 'Volleyball', desc: 'Played for over 5 years as a middle blocker with Lerbergets and Ängelholms clubs.' },
{ icon: <FaVolleyballBall />, title: 'Volleyball', desc: '8 Years going strong! Currently playing middle blocker with the Elite team in Lund. Mother club is Lerbergets volleybollsällskap.' },
{ icon: <FaTree />, title: 'Young Ranger', desc: 'Part of the Youth+ Network at Europarc Federation, working in management at Kullaberg.' },
{ icon: <FaCamera />, title: 'Photography', desc: 'Capturing nature and people, finding the best subjects on film.' },
{ icon: <FaCamera />, title: 'Photography', desc: 'Capturing nature and people, finding the best subjects to save.' },
{ icon: <TbCube3dSphere />, title: 'CAD', desc: 'Specialized in design and manufacturing, modeling everything from concepts to architecture.' },
{ icon: <FaCode />, title: 'Coding', desc: 'Developing automation scripts and custom programs to solve unique problems.' }
{ icon: <FaCode />, title: 'Coding', desc: 'Developing automation scripts and custom programs to solve unique problems. Check out my portfolio!' }
].map((item, idx) => (
<div key={idx} className="group p-8 rounded-3xl bg-white/5 backdrop-blur-md border border-white/10 hover:border-[#84c0a0]/40 hover:bg-white/10 transition-all duration-300">
<div className="text-[#84c0a0] text-4xl mb-6 w-fit group-hover:scale-110 transition-transform duration-300">{item.icon}</div>
<h3 className="text-white text-2xl font-bold mb-4">{item.title}</h3>
<p className="text-gray-400 text-sm leading-relaxed">{item.desc}</p>
<div key={idx} className="w-full md:w-[calc(50%-12px)] lg:w-[calc(33.333%-16px)] group p-8 rounded-3xl bg-white/30 dark:bg-white/5 backdrop-blur-md border border-slate-200 dark:border-white/10 hover:border-[#84c0a0]/40 dark:hover:border-[#84c0a0]/40 hover:bg-white/90 dark:hover:bg-white/10 transition-all duration-300 shadow-md dark:shadow-none">
<div className="text-slate-900 dark:text-[#84c0a0] text-4xl mb-6 w-fit group-hover:scale-110 transition-transform duration-300">{item.icon}</div>
<h3 className="text-slate-900 dark:text-white text-2xl font-bold mb-4 transition-colors">{item.title}</h3>
<p className="text-slate-600 dark:text-gray-400 text-sm leading-relaxed transition-colors">{item.desc}</p>
</div>
))}
</div>
@@ -137,44 +122,39 @@ export default function Home() {
</section>
{/* 4. PHOTO GALLERY SECTION */}
<section className="py-24 px-6 bg-[#0d1117]">
<section className="py-24 px-6 bg-slate-100 dark:bg-[#0d1117] transition-colors duration-300 border-t border-slate-200 dark:border-transparent">
<div className="max-w-6xl mx-auto">
<div className="text-center mb-16">
<h2 className="text-white text-4xl md:text-5xl font-black uppercase tracking-tighter">Photography</h2>
<h2 className="text-slate-900 dark:text-white text-4xl md:text-5xl font-black uppercase tracking-tighter transition-colors">Photography</h2>
<p className="text-[#84c0a0] mt-4 font-mono uppercase text-sm tracking-widest font-bold">Capturing the world</p>
</div>
<div className="flex flex-col lg:flex-row items-center lg:items-start gap-12 lg:gap-16">
{/* My Photos (Ynni Image) */}
<div className="relative w-full lg:w-1/2">
<Image src="/assets/images/ynni.jpg" alt="My Photos" width={800} height={800} className="w-full rounded-4xl shadow-2xl object-cover lg:h-125" />
<div className="absolute top-[10%] -left-4 lg:-left-12 bg-white/10 backdrop-blur-xl border border-white/20 py-6 px-10 shadow-2xl rounded-2xl">
<h2 className="text-[30px] lg:text-[40px] text-white font-black whitespace-nowrap uppercase tracking-wider">My Photos</h2>
<Image src="/assets/images/ynni.jpg" alt="My Photos" quality={90} width={800} height={1000} className="w-full rounded-4xl shadow-2xl object-cover lg:h-150" />
<div className="absolute top-[10%] -left-4 lg:-left-12 bg-white/20 dark:bg-white/10 backdrop-blur-xl border border-[#84c0a0]/40 dark:border-white/20 py-6 px-10 shadow-2xl rounded-2xl">
<h2 className="text-[30px] lg:text-[40px] text-slate-900 dark:text-white font-black whitespace-nowrap uppercase tracking-wider transition-colors">My Photos</h2>
</div>
</div>
{/* Night Sky Collection */}
<div className="flex flex-col items-start w-full lg:w-1/2 lg:pt-8">
<Image src="/assets/images/night_sky.jpg" alt="Night Sky" width={600} height={400} className="w-full max-w-125 rounded-3xl shadow-xl border border-gray-200 dark:border-white/10" />
<h3 className="text-white text-[26px] mt-8 font-bold uppercase tracking-wide">My Photography collection</h3>
<Image src="/assets/images/night_sky.jpg" alt="Night Sky" width={600} height={400} className="w-full max-w-125 rounded-3xl shadow-xl border border-slate-200 dark:border-white/10" />
<h3 className="text-slate-900 dark:text-white text-[26px] mt-8 font-bold uppercase tracking-wide transition-colors">My Photography collection</h3>
<div className="w-12 h-1 border-t-2 border-[#84c0a0] my-4"></div>
<p className="text-gray-400 text-[18px] font-light leading-relaxed">
Taking photos is just one of my many hobbies. Finding the best subjects to capture on film, from nature to the night skies.
<p className="text-slate-600 dark:text-gray-400 text-[18px] font-light leading-relaxed transition-colors">
Taking photos is just one of my many hobbies. Finding the best motives to capture, from nature to the night skies.
</p>
<Link href="/gallery" className="mt-8 bg-[#84c0a0] text-[#0d1117] px-8 py-3 rounded-full font-bold uppercase tracking-wider hover:scale-105 transition-transform shadow-[0_0_20px_rgba(132,192,160,0.3)]">
<Link href="/gallery" className="mt-8 bg-[#84c0a0] text-white dark:text-[#0d1117] px-8 py-3 rounded-full font-bold uppercase tracking-wider hover:scale-105 transition-transform shadow-[0_0_20px_rgba(132,192,160,0.3)]">
More photos
</Link>
</div>
</div>
{/* Singapore Full Width wrapper */}
<div className="w-full mt-32 relative h-125 md:h-175 rounded-[40px] overflow-hidden shadow-2xl border border-white/10 group">
<div className="w-full mt-32 relative h-125 md:h-175 rounded-[40px] overflow-hidden shadow-2xl border border-slate-200 dark:border-white/10 group">
<Image src="/assets/images/singapore.jpg" alt="Singapore" fill className="object-cover transition-transform duration-1000 group-hover:scale-105" />
<div className="absolute inset-0 bg-linear-to-t from-[#0d1117]/90 via-[#0d1117]/20 to-transparent"></div>
<div className="absolute inset-0 bg-linear-to-t from-black/80 dark:from-[#0d1117]/90 via-black/20 dark:via-[#0d1117]/20 to-transparent"></div>
<div className="relative z-10 w-full h-full p-8 md:p-16 flex items-end md:items-start">
<div className="bg-[#0d1117]/30 backdrop-blur-xl border border-white/10 p-8 max-w-87.5 rounded-3xl shadow-2xl">
<div className="bg-[#0d1117]/30 backdrop-blur-xl border border-white/20 dark:border-white/10 p-8 max-w-87.5 rounded-3xl shadow-2xl">
<p className="text-[18px] font-medium text-white leading-relaxed">
A cloudy day in Singapore, the New Zealand trip 2019.
</p>
@@ -188,38 +168,23 @@ export default function Home() {
</div>
</section>
{/* 5. CONTACT CALL-TO-ACTION (Compact Banner) */}
<section className="relative py-16 px-6 overflow-hidden border-t border-white/5">
{/* Immersive Mountain Background */}
<Image
src="/assets/images/snowy_mountain_peaks.jpg"
alt="Snowy Mountains"
fill
className="object-cover z-0"
/>
{/* Dark overlay */}
<div className="absolute inset-0 bg-[#0d1117]/80 backdrop-blur-[2px] z-0"></div>
{/* Compact Glassmorphic CTA Banner */}
<div className="relative z-10 max-w-5xl mx-auto bg-white/5 backdrop-blur-xl border border-white/10 rounded-3xl p-8 md:px-12 md:py-10 shadow-2xl flex flex-col md:flex-row items-center justify-between gap-6">
{/* 5. CONTACT CALL-TO-ACTION */}
<section className="relative py-16 px-6 overflow-hidden border-t border-slate-200 dark:border-white/5 transition-colors duration-300">
<Image src="/assets/images/snowy_mountain_peaks.jpg" alt="Snowy Mountains" fill className="object-cover z-0" />
<div className="absolute inset-0 bg-slate-100/40 dark:bg-[#0d1117]/80 backdrop-blur-[2px] z-0 transition-colors duration-300"></div>
<div className="relative z-10 max-w-5xl mx-auto bg-white/70 dark:bg-white/5 backdrop-blur-xl border border-slate-200 dark:border-white/10 rounded-3xl p-8 md:px-12 md:py-10 shadow-xl dark:shadow-2xl flex flex-col md:flex-row items-center justify-between gap-6 transition-colors duration-300">
<div className="text-center md:text-left">
<h2 className="text-white text-3xl md:text-4xl font-black uppercase tracking-tighter mb-2">
<h2 className="text-slate-900 dark:text-white text-3xl md:text-4xl font-black uppercase tracking-tighter mb-2 transition-colors">
Let&apos;s Connect
</h2>
<p className="text-[#84c0a0] font-mono uppercase text-xs md:text-sm tracking-widest font-bold">
Transmission & Socials
Contact info & Socials
</p>
</div>
<Link
href="/contact"
className="shrink-0 inline-block bg-[#84c0a0] text-[#0d1117] px-8 py-4 rounded-full font-bold uppercase tracking-wider hover:scale-105 active:scale-95 transition-all shadow-[0_0_20px_rgba(132,192,160,0.3)]"
>
<Link href="/contact" className="shrink-0 inline-block bg-[#84c0a0] text-white dark:text-[#0d1117] px-8 py-4 rounded-full font-bold uppercase tracking-wider hover:scale-105 active:scale-95 transition-all shadow-[0_0_20px_rgba(132,192,160,0.3)]">
Contact Me
</Link>
</div>
</section>
</div>
+42 -41
View File
@@ -107,7 +107,7 @@ export default async function CodePage() {
]);
return (
<main className="flex flex-col flex-1 relative min-h-dvh">
<main className="flex flex-col flex-1 relative min-h-dvh bg-slate-50/50 dark:bg-transparent transition-colors duration-300">
<MatrixRain />
<div className="h-25 shrink-0"></div>
@@ -117,35 +117,35 @@ export default async function CodePage() {
{/* 2. Profile Card Section */}
{profile && (
<section className="flex justify-center mt-10">
<div className="relative flex flex-col justify-center items-center bg-linear-to-b from-[#333333]/90 to-[#2a2a2a]/90 backdrop-blur-lg rounded-3xl text-center p-8 shadow-[0_8px_32px_rgba(0,0,0,0.5)] w-full max-w-md border border-white/10">
<div className="relative flex flex-col justify-center items-center bg-white/90 dark:bg-linear-to-b dark:from-[#333333]/90 dark:to-[#2a2a2a]/90 backdrop-blur-lg rounded-3xl text-center p-8 shadow-xl dark:shadow-[0_8px_32px_rgba(0,0,0,0.5)] w-full max-w-md border border-slate-200 dark:border-white/10 transition-colors duration-300">
<a href={profile.html_url} target="_blank" rel="noopener noreferrer">
<FaGithub className="absolute text-white text-[28px] top-5 right-5 hover:text-[#84c0a0] transition-colors" />
<FaGithub className="absolute text-slate-800 dark:text-white text-[28px] top-5 right-5 hover:text-[#84c0a0] dark:hover:text-[#84c0a0] transition-colors" />
</a>
<div className="w-full">
<div className="relative h-37.5 w-37.5 mx-auto mb-5">
<Image src={profile.avatar_url} alt="Avatar" width={150} height={150} className="h-full w-full rounded-full object-cover border-4 border-[#58806a] dark:border-[#84c0a0] shadow-[0_0_15px_rgba(88,128,106,0.3)] dark:shadow-[0_0_15px_rgba(132,192,160,0.5)]" />
<Image src={profile.avatar_url} alt="Avatar" width={150} height={150} className="h-full w-full rounded-full object-cover border-4 border-[#84c0a0]/50 dark:border-[#84c0a0] shadow-[0_0_15px_rgba(132,192,160,0.3)] dark:shadow-[0_0_15px_rgba(132,192,160,0.5)]" />
</div>
<h1 className="mb-1">
<a className="text-white text-[26px] font-bold tracking-wide no-underline hover:text-[#84c0a0] transition-colors" href={profile.html_url} target="_blank" rel="noopener noreferrer">
<a className="text-slate-900 dark:text-white text-[26px] font-bold tracking-wide no-underline hover:text-[#84c0a0] dark:hover:text-[#84c0a0] transition-colors" href={profile.html_url} target="_blank" rel="noopener noreferrer">
{profile.name}
</a>
</h1>
<div className="mb-5">
<a className="text-[#a0aab6] font-medium no-underline hover:text-white transition-colors" href={profile.html_url} target="_blank" rel="noopener noreferrer">
<a className="text-slate-500 dark:text-[#a0aab6] font-medium no-underline hover:text-slate-800 dark:hover:text-white transition-colors" href={profile.html_url} target="_blank" rel="noopener noreferrer">
@{profile.login}
</a>
</div>
<p className="font-medium mx-auto text-[#84c0a0] mt-2.5 text-[15px] leading-relaxed">
{profile.bio}
</p>
<div className="mt-8 relative border-t border-white/10 pt-5 flex justify-around">
<div className="mt-8 relative border-t border-slate-200 dark:border-white/10 pt-5 flex justify-around transition-colors duration-300">
<div className="relative">
<div className="text-white text-[22px] font-bold">{profile.followers}</div>
<div className="text-[11px] font-bold text-[#a0aab6] tracking-widest uppercase mt-1">Followers</div>
<div className="text-slate-900 dark:text-white text-[22px] font-bold transition-colors">{profile.followers}</div>
<div className="text-[11px] font-bold text-slate-500 dark:text-[#a0aab6] tracking-widest uppercase mt-1 transition-colors">Followers</div>
</div>
<div className="relative">
<div className="text-white text-[22px] font-bold">{profile.public_repos}</div>
<div className="text-[11px] font-bold text-[#a0aab6] tracking-widest uppercase mt-1">Repositories</div>
<div className="text-slate-900 dark:text-white text-[22px] font-bold transition-colors">{profile.public_repos}</div>
<div className="text-[11px] font-bold text-slate-500 dark:text-[#a0aab6] tracking-widest uppercase mt-1 transition-colors">Repositories</div>
</div>
</div>
</div>
@@ -154,35 +154,34 @@ export default async function CodePage() {
)}
{/* 3. GitLab Repositories Section */}
<section className="bg-[#fc6d26]/10 backdrop-blur-lg rounded-3xl border border-[#fc6d26]/30 p-8 shadow-2xl">
<section className="bg-[#fc6d26]/15 dark:bg-[#fc6d26]/10 backdrop-blur-lg rounded-3xl border border-[#fc6d26]/20 dark:border-[#fc6d26]/30 p-8 shadow-xl dark:shadow-2xl transition-colors duration-300">
<div className="flex justify-center items-center flex-col mb-10">
<a href="https://gitlab.soderberg.tech/WilliamSoderberg" target="_blank" rel="noopener noreferrer">
<FaGitlab className="text-[#fc6d26] text-[55px] drop-shadow-[0_0_15px_rgba(252,109,38,0.4)] hover:scale-110 transition-transform cursor-pointer" />
</a>
<h2 className="text-white mt-3.75 text-[32px] md:text-[38px] uppercase font-bold text-center tracking-wider">
<h2 className="text-slate-900 dark:text-white mt-3.75 text-[32px] md:text-[38px] uppercase font-bold text-center tracking-wider transition-colors">
GitLab Projects
</h2>
<p className="text-gray-300 text-center max-w-2xl mt-3">Self-hosted infrastructure and private development.</p>
<p className="text-slate-600 dark:text-gray-300 text-center max-w-2xl mt-3 transition-colors">Self-hosted infrastructure and private development.</p>
</div>
{gitlabRepos.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 justify-center">
{gitlabRepos.map((repo) => (
<a key={repo.id} href={repo.web_url} target="_blank" rel="noopener noreferrer" className="group flex flex-col justify-between bg-linear-to-br from-[#2a2a2a]/90 to-[#222222]/90 border border-white/10 p-6 rounded-2xl hover:-translate-y-1 hover:border-[#fc6d26]/60 hover:shadow-[0_8px_24px_rgba(252,109,38,0.2)] transition-all duration-300 no-underline">
<a key={repo.id} href={repo.web_url} target="_blank" rel="noopener noreferrer" className="group flex flex-col justify-between bg-white/90 dark:bg-linear-to-br dark:from-[#2a2a2a]/90 dark:to-[#222222]/90 border border-slate-200 dark:border-white/10 p-6 rounded-2xl hover:-translate-y-1 hover:border-[#fc6d26]/60 dark:hover:border-[#fc6d26]/60 hover:shadow-[0_8px_24px_rgba(252,109,38,0.15)] dark:hover:shadow-[0_8px_24px_rgba(252,109,38,0.2)] transition-all duration-300 no-underline">
<div>
<h3 className="text-[#fc6d26] text-[19px] font-bold group-hover:text-white transition-colors truncate">
<h3 className="text-[#fc6d26] text-[19px] font-bold group-hover:text-slate-900 dark:group-hover:text-white transition-colors truncate">
{repo.name}
</h3>
<p className="text-[14px] mb-4 mt-2.5 text-gray-400 text-left line-clamp-3 leading-relaxed">
<p className="text-[14px] mb-4 mt-2.5 text-slate-500 dark:text-gray-400 text-left line-clamp-3 leading-relaxed transition-colors">
{repo.description || 'No description provided.'}
</p>
</div>
<div className="flex items-center text-[13px] text-[#8b949e] mt-4 font-medium">
{/* NEW: GitLab Language Badge */}
<div className="flex items-center text-[13px] text-slate-500 dark:text-[#8b949e] mt-4 font-medium transition-colors">
{repo.language && (
<div className="flex items-center mr-5">
<span className={`w-2.5 h-2.5 rounded-full mr-2 ${langColors[repo.language] || 'bg-gray-500'}`}></span>
<span className="text-gray-300">{repo.language}</span>
<span className="text-slate-600 dark:text-gray-300">{repo.language}</span>
</div>
)}
{repo.star_count > 0 && (
@@ -200,35 +199,35 @@ export default async function CodePage() {
))}
</div>
) : (
<div className="text-center text-gray-400 italic py-8 bg-black/20 rounded-xl">No public GitLab repositories found or API is restricted.</div>
<div className="text-center text-slate-500 dark:text-gray-400 italic py-8 bg-black/5 dark:bg-black/20 rounded-xl transition-colors">No public GitLab repositories found or API is restricted.</div>
)}
</section>
{/* 4. GitHub Repositories Section */}
<section className="bg-[#84c0a0]/10 backdrop-blur-lg rounded-3xl border border-[#84c0a0]/30 p-8 shadow-2xl">
<section className="bg-[#84c0a0]/15 dark:bg-[#84c0a0]/10 backdrop-blur-lg rounded-3xl border border-[#84c0a0]/20 dark:border-[#84c0a0]/30 p-8 shadow-xl dark:shadow-2xl transition-colors duration-300">
<div className="flex justify-center items-center flex-col mb-10">
<FaGithub className="text-white text-[55px] drop-shadow-[0_0_15px_rgba(255,255,255,0.2)]" />
<h2 className="text-white mt-3.75 text-[32px] md:text-[38px] uppercase font-bold text-center tracking-wider">
<FaGithub className="text-slate-900 dark:text-white text-[55px] drop-shadow-md dark:drop-shadow-[0_0_15px_rgba(255,255,255,0.2)] transition-colors" />
<h2 className="text-slate-900 dark:text-white mt-3.75 text-[32px] md:text-[38px] uppercase font-bold text-center tracking-wider transition-colors">
Public Repositories
</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 justify-center">
{githubRepos.map((repo) => (
<a key={repo.id} href={repo.html_url} target="_blank" rel="noopener noreferrer" className="group flex flex-col justify-between bg-linear-to-br from-[#2a2a2a]/90 to-[#222222]/90 border border-white/10 p-6 rounded-2xl hover:-translate-y-1 hover:border-[#84c0a0]/60 hover:shadow-[0_8px_24px_rgba(132,192,160,0.2)] transition-all duration-300 no-underline">
<a key={repo.id} href={repo.html_url} target="_blank" rel="noopener noreferrer" className="group flex flex-col justify-between bg-white/90 dark:bg-linear-to-br dark:from-[#2a2a2a]/90 dark:to-[#222222]/90 border border-slate-200 dark:border-white/10 p-6 rounded-2xl hover:-translate-y-1 hover:border-[#84c0a0]/60 hover:shadow-[0_8px_24px_rgba(132,192,160,0.15)] dark:hover:shadow-[0_8px_24px_rgba(132,192,160,0.2)] transition-all duration-300 no-underline">
<div>
<h3 className="text-[#4e9fff] text-[19px] font-bold group-hover:text-white transition-colors truncate">
<h3 className="text-[#4e9fff] text-[19px] font-bold group-hover:text-slate-900 dark:group-hover:text-white transition-colors truncate">
{repo.name}
</h3>
<p className="text-[14px] mb-4 mt-2.5 text-gray-400 text-left line-clamp-3 leading-relaxed">
<p className="text-[14px] mb-4 mt-2.5 text-slate-500 dark:text-gray-400 text-left line-clamp-3 leading-relaxed transition-colors">
{repo.description || 'No description provided.'}
</p>
</div>
<div className="flex items-center text-[13px] text-[#8b949e] mt-4 font-medium">
<div className="flex items-center text-[13px] text-slate-500 dark:text-[#8b949e] mt-4 font-medium transition-colors">
{repo.language && (
<div className="flex items-center mr-5">
<span className={`w-2.5 h-2.5 rounded-full mr-2 ${langColors[repo.language] || 'bg-gray-500'}`}></span>
<span className="text-gray-300">{repo.language}</span>
<span className="text-slate-600 dark:text-gray-300">{repo.language}</span>
</div>
)}
{repo.stargazers_count > 0 && (
@@ -248,31 +247,33 @@ export default async function CodePage() {
</section>
{/* 5. Hosted Websites Section */}
<section className="bg-white/5 backdrop-blur-lg rounded-3xl border border-white/10 p-10 shadow-2xl">
<section className="bg-white/80 dark:bg-white/5 backdrop-blur-lg rounded-3xl border border-slate-200 dark:border-white/10 p-10 shadow-xl dark:shadow-2xl transition-colors duration-300">
<div className="flex justify-center items-center flex-col mb-10">
<FaGlobe className="text-white text-[55px] drop-shadow-[0_0_15px_rgba(255,255,255,0.2)]" />
<h2 className="text-white mt-3.75 text-[32px] md:text-[38px] uppercase font-bold text-center tracking-wider">
<FaGlobe className="text-slate-900 dark:text-white text-[55px] drop-shadow-md dark:drop-shadow-[0_0_15px_rgba(255,255,255,0.2)] transition-colors" />
<h2 className="text-slate-900 dark:text-white mt-3.75 text-[32px] md:text-[38px] uppercase font-bold text-center tracking-wider transition-colors">
Hosted Websites
</h2>
</div>
{/* Changed from Flex to Grid for perfect centering! */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 max-w-5xl mx-auto justify-items-center items-center py-6">
<a className="no-underline text-gray-900 dark:text-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://soderberg.tech">
<Image src="/assets/logos/logo.svg" alt="Soderberg Tech" width={90} height={65} className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-[0_0_10px_rgba(0,0,0,0.2)] dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<div className="flex flex-wrap justify-center gap-12 max-w-5xl mx-auto py-6">
<a className="w-full md:w-[calc(33.333%-32px)] no-underline text-slate-900 dark:text-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://soderberg.tech">
<Image src="/assets/logos/logo.svg" alt="Soderberg Tech" width={90} height={65} className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-lg dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<span className="font-bold tracking-wide text-center">Soderberg Tech</span>
</a>
<a className="no-underline text-gray-900 dark:text-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://lirkab.se">
<Image src="/assets/logos/lirkab.svg" alt="Lirkab" width={90} height={65} className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-[0_0_10px_rgba(0,0,0,0.2)] dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<a className="w-full md:w-[calc(33.333%-32px)] no-underline text-slate-900 dark:text-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://lirkab.se">
<Image src="/assets/logos/lirkab.svg" alt="Lirkab" width={90} height={65} className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-lg dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<span className="font-bold tracking-wide text-center">Lirkab</span>
</a>
<a className="no-underline text-gray-900 dark:text-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://lerbergetsvolleyboll.se">
<Image src="/assets/logos/lvs.svg" alt="Lerbergets Volleyboll" width={90} height={65} className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-[0_0_10px_rgba(0,0,0,0.2)] dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<a className="w-full md:w-[calc(33.333%-32px)] no-underline text-slate-900 dark:text-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://lerbergetsvolleyboll.se">
<Image src="/assets/logos/lvs.svg" alt="Lerbergets Volleyboll" width={90} height={65} className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-lg dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<span className="font-bold tracking-wide text-center">Lerbergets Volleyboll</span>
</a>
<a className="w-full md:w-[calc(33.333%-32px)] no-underline text-slate-900 dark:text-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://naturvardarna.com">
<Image src="/assets/logos/naturvardarna.svg" alt="Naturvärdarna Kullaberg" width={90} height={65} className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-lg dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<span className="font-bold tracking-wide text-center">Naturvärdarna Kullaberg</span>
</a>
</div>
</section>
</div>
</main>
);
+21 -13
View File
@@ -60,22 +60,30 @@ export default function DesignPage() {
const showOverlay = isPending || !isSceneReady;
return (
<main className="flex flex-col flex-1 relative bg-[#0d1117] overflow-hidden">
<main className="flex flex-col flex-1 relative bg-slate-50 dark:bg-[#0d1117] overflow-hidden transition-colors duration-300">
{/* Background Glow */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-200 h-200 bg-[#84c0a0]/10 blur-[150px] rounded-full pointer-events-none z-0"></div>
<div className="h-25 shrink-0"></div>
<div className="relative z-10 w-full max-w-350 mx-auto px-4 pb-20 flex flex-col gap-10">
<div className="pt-5 flex justify-center items-center flex-col text-center">
<TbCube3dSphere className="text-white text-[80px] drop-shadow-[0_0_15px_rgba(255,255,255,0.2)]" />
<h2 className="text-white text-[32px] md:text-[45px] uppercase mt-3.75 font-bold tracking-wider">CAD Library</h2>
{/* Changed from flex-col to lg:flex-row for side-by-side layout on desktop */}
<div className="relative z-10 w-full max-w-450 mx-auto px-4 lg:px-12 pb-20 flex flex-col lg:flex-row gap-10 lg:gap-16 items-center lg:items-start pt-10">
{/* 1. Title Section (Now on the left and sticky!) */}
<div className="w-full lg:w-1/3 flex flex-col justify-center items-center lg:items-start text-center lg:text-left pt-5 lg:sticky lg:top-40">
<TbCube3dSphere className="text-slate-900 dark:text-white text-[80px] drop-shadow-md dark:drop-shadow-[0_0_15px_rgba(255,255,255,0.2)] transition-colors" />
<h2 className="text-slate-900 dark:text-white text-[32px] md:text-[45px] uppercase mt-4 font-bold tracking-wider transition-colors leading-tight">CAD Library</h2>
<p className="text-slate-500 dark:text-gray-400 mt-4 text-base md:text-lg leading-relaxed transition-colors">
Explore my 3D modeling and design work. Interact with the models using your mouse or touch screen.
</p>
</div>
<section className="w-full flex justify-center">
<div className="w-full relative bg-white/5 backdrop-blur-xl rounded-4xl border border-white/10 shadow-[0_8px_32px_rgba(0,0,0,0.5)] p-4 md:p-8 flex flex-col">
<div className="w-full h-[50vh] md:h-[65vh] rounded-[20px] overflow-hidden relative bg-linear-to-br from-[#1a1a1a] to-[#0f0f0f] shadow-inner border border-white/5 cursor-grab active:cursor-grabbing">
{/* 2. Viewer Section (Now taking up the right side) */}
<section className="w-full lg:w-2/3 flex justify-center">
<div className="w-full relative bg-white/80 dark:bg-white/5 backdrop-blur-xl rounded-4xl border border-slate-200 dark:border-white/10 shadow-xl dark:shadow-[0_8px_32px_rgba(0,0,0,0.5)] p-4 md:p-8 flex flex-col transition-colors duration-300">
<div className="w-full h-[50vh] md:h-[60vh] rounded-[20px] overflow-hidden relative bg-slate-200 dark:bg-linear-to-br dark:from-[#1a1a1a] dark:to-[#0f0f0f] shadow-inner border border-slate-300 dark:border-white/5 cursor-grab active:cursor-grabbing transition-colors duration-300">
{showOverlay && (
<div className="absolute inset-0 z-20 flex flex-col items-center justify-center bg-[#0d1117]/80 backdrop-blur-md transition-all duration-500">
<div className="absolute inset-0 z-20 flex flex-col items-center justify-center bg-slate-100/80 dark:bg-[#0d1117]/80 backdrop-blur-md transition-all duration-500">
<div className="w-12 h-12 border-4 border-[#84c0a0]/20 border-t-[#84c0a0] rounded-full animate-spin mb-4"></div>
<p className="text-[#84c0a0] font-mono text-xs uppercase tracking-[0.2em] font-bold">
{isPending ? "Fetching Data..." : "Compiling Materials..."}
@@ -122,7 +130,7 @@ export default function DesignPage() {
innerStyles={{ display: 'none' }}
/>
<a href={`/models/${activeModel}.usdz`} rel="ar" className="absolute top-4 right-4 bg-black/50 backdrop-blur-md text-white text-sm px-4 py-2 rounded-full border border-white/10 hover:bg-white/20 transition-colors md:hidden z-10 flex items-center gap-2">
<a href={`/models/${activeModel}.usdz`} rel="ar" className="absolute top-4 right-4 bg-white/80 dark:bg-black/50 text-slate-900 dark:text-white backdrop-blur-md text-sm px-4 py-2 rounded-full border border-slate-300 dark:border-white/10 hover:bg-slate-100 dark:hover:bg-white/20 transition-colors md:hidden z-10 flex items-center gap-2">
<Image
src={`/models/${activeModel}.png`}
alt="AR Preview"
@@ -140,15 +148,15 @@ export default function DesignPage() {
<button
key={model.name}
className={`shrink-0 w-20 h-20 md:w-25 md:h-25 bg-contain bg-no-repeat bg-center rounded-2xl transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#84c0a0] relative group ${activeModel === model.src
? 'bg-[#2a2a2a] border-2 border-[#84c0a0] scale-110 shadow-[0_0_20px_rgba(132,192,160,0.3)]'
: 'bg-[#1a1a1a] border border-white/10 hover:bg-[#252525] hover:-translate-y-1'
? 'bg-white dark:bg-[#2a2a2a] border-2 border-[#84c0a0] scale-110 shadow-[0_0_20px_rgba(132,192,160,0.3)]'
: 'bg-slate-100 dark:bg-[#1a1a1a] border border-slate-200 dark:border-white/10 hover:bg-slate-200 dark:hover:bg-[#252525] hover:-translate-y-1'
}`}
style={{ backgroundImage: `url('/models/${model.src}.png')` }}
onClick={() => handleModelChange(model.src)}
onMouseEnter={() => useGLTF.preload(`/models/${model.src}.glb`)}
aria-label={`View ${model.name} model`}
>
<span className="absolute -bottom-8 left-1/2 -translate-x-1/2 text-xs font-semibold text-white opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap bg-black/80 px-2 py-1 rounded">
<span className="absolute -bottom-8 left-1/2 -translate-x-1/2 text-xs font-semibold text-white opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap bg-slate-800/90 dark:bg-black/80 px-2 py-1 rounded">
{model.name}
</span>
</button>
+11 -11
View File
@@ -7,17 +7,17 @@ import { FaCode } from 'react-icons/fa';
export default function ProjectsPage() {
return (
<main className="flex flex-col flex-1 relative bg-[#0d1117] overflow-x-hidden">
<main className="flex flex-col flex-1 relative bg-slate-50 dark:bg-[#0d1117] overflow-x-hidden transition-colors duration-300">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-150 md:w-250 h-150 md:h-250 bg-[#84c0a0]/10 blur-[150px] rounded-full pointer-events-none z-0"></div>
<div className="h-25 shrink-0"></div>
<div className="relative z-10 flex-1 flex flex-col justify-center items-center py-10 md:py-20 px-6">
<div className="mb-12 text-center">
<h1 className="text-white text-[32px] md:text-[55px] uppercase font-extrabold tracking-wider drop-shadow-lg">
<h1 className="text-slate-900 dark:text-white text-[32px] md:text-[55px] uppercase font-extrabold tracking-wider drop-shadow-lg transition-colors">
My Portfolios
</h1>
<p className="text-[#a0aab6] mt-2 text-base md:text-xl max-w-md mx-auto">
<p className="text-slate-600 dark:text-[#a0aab6] mt-2 text-base md:text-xl max-w-md mx-auto transition-colors">
Choose a discipline to explore my work.
</p>
</div>
@@ -26,12 +26,12 @@ export default function ProjectsPage() {
<Link
href="/projects/code"
className="relative flex-1 group min-h-75 md:h-125 rounded-4xl overflow-hidden border border-white/10 shadow-[0_8px_32px_rgba(0,0,0,0.5)] transition-all duration-500 hover:-translate-y-2 hover:border-[#84c0a0]/60 no-underline"
className="relative flex-1 group min-h-75 md:h-125 rounded-4xl overflow-hidden border border-slate-300 dark:border-white/10 shadow-xl dark:shadow-[0_8px_32px_rgba(0,0,0,0.5)] transition-all duration-500 hover:-translate-y-2 hover:border-[#84c0a0]/60 no-underline"
>
<BlurredCode />
<div className="absolute inset-0 z-10 bg-[#0d1117]/60 backdrop-blur-[2px] group-hover:bg-[#0d1117]/20 group-hover:backdrop-blur-[1px] transition-all duration-500 flex flex-col justify-center items-center p-8">
<FaCode className="text-white text-[50px] md:text-[80px] mb-4 md:mb-6 opacity-80 group-hover:opacity-100 group-hover:scale-110 group-hover:text-[#84c0a0] transition-all duration-500" />
<h2 className="text-white text-[32px] md:text-[50px] font-bold text-center tracking-wide">
<div className="absolute inset-0 z-10 bg-slate-50/10 dark:bg-[#0d1117]/60 backdrop-blur-[1px] group-hover:bg-slate-50/20 dark:group-hover:bg-[#0d1117]/20 group-hover:backdrop-blur-[2px] transition-all duration-500 flex flex-col justify-center items-center p-8">
<FaCode className="text-slate-900 dark:text-white text-[50px] md:text-[80px] mb-4 md:mb-6 opacity-80 group-hover:opacity-100 group-hover:scale-110 group-hover:text-[#84c0a0] dark:group-hover:text-[#84c0a0] transition-all duration-500" />
<h2 className="text-slate-900 dark:text-white text-[32px] md:text-[50px] font-bold text-center tracking-wide transition-colors">
Coding
</h2>
</div>
@@ -39,16 +39,16 @@ export default function ProjectsPage() {
<Link
href="/projects/design"
className="relative flex-1 group min-h-75 md:h-125 rounded-4xl overflow-hidden border border-white/10 shadow-[0_8px_32px_rgba(0,0,0,0.5)] transition-all duration-500 hover:-translate-y-2 hover:border-[#84c0a0]/60 no-underline"
className="relative flex-1 group min-h-75 md:h-125 rounded-4xl overflow-hidden border border-slate-300 dark:border-white/10 shadow-xl dark:shadow-[0_8px_32px_rgba(0,0,0,0.5)] transition-all duration-500 hover:-translate-y-2 hover:border-[#84c0a0]/60 no-underline"
>
<div
className="absolute inset-0 z-0 bg-center bg-cover bg-no-repeat opacity-40 group-hover:opacity-100 group-hover:scale-105 transition-all duration-700"
style={{ backgroundImage: `url('/assets/images/CAD.png')` }}
></div>
<div className="absolute inset-0 z-10 bg-[#0d1117]/60 backdrop-blur-[2px] group-hover:bg-[#0d1117]/20 group-hover:backdrop-blur-[1px] transition-all duration-500 flex flex-col justify-center items-center p-8">
<TbCube3dSphere className="text-white text-[50px] md:text-[80px] mb-4 md:mb-6 opacity-80 group-hover:opacity-100 group-hover:scale-110 group-hover:text-[#84c0a0] transition-all duration-500" />
<h2 className="text-white text-[32px] md:text-[50px] font-bold text-center tracking-wide">
<div className="absolute inset-0 z-10 bg-slate-50/10 dark:bg-[#0d1117]/60 backdrop-blur-[3px] group-hover:bg-slate-50/20 dark:group-hover:bg-[#0d1117]/20 group-hover:backdrop-blur-[2px] transition-all duration-500 flex flex-col justify-center items-center p-8">
<TbCube3dSphere className="text-slate-900 dark:text-white text-[50px] md:text-[80px] mb-4 md:mb-6 opacity-80 group-hover:opacity-100 group-hover:scale-110 group-hover:text-[#84c0a0] dark:group-hover:text-[#84c0a0] transition-all duration-500" />
<h2 className="text-slate-900 dark:text-white text-[32px] md:text-[50px] font-bold text-center tracking-wide transition-colors">
CAD & Design
</h2>
</div>
+11
View File
@@ -12,6 +12,7 @@
"@react-three/fiber": "^9.5.0",
"image-size": "^2.0.2",
"next": "16.1.6",
"next-themes": "^0.4.6",
"photoswipe": "^5.4.4",
"react": "19.2.3",
"react-dom": "19.2.3",
@@ -5664,6 +5665,16 @@
}
}
},
"node_modules/next-themes": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
"integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
}
},
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+1
View File
@@ -13,6 +13,7 @@
"@react-three/fiber": "^9.5.0",
"image-size": "^2.0.2",
"next": "16.1.6",
"next-themes": "^0.4.6",
"photoswipe": "^5.4.4",
"react": "19.2.3",
"react-dom": "19.2.3",
+51
View File
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160">
<defs>
<style>
.cls-1 {
fill: #fff;
}
</style>
</defs>
<polygon class="cls-1" points="100.54 88.73 117.62 78.86 117.62 67.01 117.62 67.01 107.35 61.08 90.27 70.94 90.27 51.21 80 45.29 69.73 51.21 69.73 70.94 52.65 61.08 42.38 67.01 42.38 67.01 42.38 78.86 59.46 88.73 42.38 98.59 42.38 110.45 52.65 116.38 69.73 106.51 69.73 126.24 80 132.17 90.27 126.24 90.27 106.51 107.35 116.38 117.62 110.45 117.62 98.59 100.54 88.73"/>
<g>
<path class="cls-1" d="M35,21.54h-3.59l-3.67-5.48c-.07-.11-.18-.34-.33-.69h-.04v6.17h-2.84v-12.6h2.84v5.96h.04c.07-.16.19-.4.35-.7l3.48-5.26h3.38l-4.39,6.01,4.77,6.59Z"/>
<path class="cls-1" d="M46.6,16.08c0,3.79-1.76,5.68-5.29,5.68s-5.13-1.85-5.13-5.55v-7.28h2.85v7.31c0,2.04.8,3.06,2.39,3.06s2.35-.98,2.35-2.95v-7.42h2.84v7.15Z"/>
<path class="cls-1" d="M56.98,21.54h-7.51v-12.6h2.84v10.3h4.67v2.3Z"/>
<path class="cls-1" d="M66.31,21.54h-7.51v-12.6h2.84v10.3h4.67v2.3Z"/>
<path class="cls-1" d="M79.21,21.54h-3.09l-.9-2.8h-4.48l-.89,2.8h-3.08l4.59-12.6h3.37l4.48,12.6ZM74.57,16.56l-1.35-4.24c-.1-.32-.17-.69-.21-1.13h-.07c-.03.37-.1.74-.22,1.1l-1.37,4.27h3.23Z"/>
<path class="cls-1" d="M80.91,21.54v-12.6h4.59c1.41,0,2.49.26,3.24.77s1.13,1.24,1.13,2.18c0,.68-.23,1.27-.69,1.78-.46.51-1.05.86-1.76,1.06v.04c.9.11,1.61.44,2.15.99.54.55.8,1.22.8,2.01,0,1.15-.41,2.07-1.24,2.75s-1.95,1.02-3.38,1.02h-4.84ZM83.75,11.03v2.99h1.25c.59,0,1.05-.14,1.38-.43.34-.28.51-.68.51-1.17,0-.93-.69-1.39-2.07-1.39h-1.06ZM83.75,16.13v3.32h1.54c.66,0,1.17-.15,1.54-.46.37-.3.56-.72.56-1.25s-.18-.9-.55-1.19c-.37-.29-.88-.43-1.53-.43h-1.55Z"/>
<path class="cls-1" d="M100.14,21.54h-7.56v-12.6h7.27v2.31h-4.43v2.8h4.12v2.3h-4.12v2.88h4.72v2.3Z"/>
<path class="cls-1" d="M112.86,21.54h-3.26l-1.96-3.24c-.15-.25-.29-.47-.42-.66s-.27-.36-.41-.5-.28-.24-.43-.32c-.15-.07-.31-.11-.49-.11h-.76v4.83h-2.84v-12.6h4.5c3.06,0,4.59,1.14,4.59,3.43,0,.44-.07.85-.2,1.22s-.33.71-.57,1.01-.54.56-.89.77-.74.39-1.16.51v.04c.19.06.37.15.54.29s.35.29.51.46.32.36.47.57c.15.2.29.4.41.59l2.38,3.73ZM105.12,11.07v3.51h1.23c.61,0,1.1-.18,1.47-.53.38-.36.56-.8.56-1.33,0-1.1-.66-1.65-1.98-1.65h-1.28Z"/>
<path class="cls-1" d="M124.5,20.7c-1.23.71-2.76,1.06-4.59,1.06-2.03,0-3.63-.56-4.79-1.68-1.17-1.12-1.75-2.67-1.75-4.64s.64-3.59,1.92-4.84,2.98-1.87,5.1-1.87c1.34,0,2.51.18,3.53.55v2.66c-.97-.56-2.16-.84-3.57-.84-1.18,0-2.14.38-2.88,1.15s-1.11,1.79-1.11,3.06.33,2.3,1,3.01c.66.71,1.56,1.06,2.69,1.06.68,0,1.22-.1,1.62-.29v-2.46h-2.52v-2.27h5.36v6.34Z"/>
<path class="cls-1" d="M126.5,21.06v-2.81c.51.43,1.06.75,1.66.96s1.2.32,1.81.32c.36,0,.67-.03.94-.1.27-.06.49-.15.67-.27.18-.11.31-.25.4-.4s.13-.32.13-.51c0-.25-.07-.47-.21-.66s-.33-.37-.58-.54-.53-.32-.87-.47-.69-.31-1.08-.47c-.98-.41-1.72-.91-2.2-1.5-.48-.59-.72-1.31-.72-2.14,0-.66.13-1.22.4-1.69s.62-.86,1.08-1.16c.45-.3.98-.53,1.58-.67s1.23-.22,1.9-.22,1.24.04,1.75.12c.51.08.97.2,1.4.36v2.63c-.21-.15-.44-.28-.69-.39s-.5-.2-.77-.28-.53-.13-.79-.16c-.26-.04-.51-.05-.74-.05-.32,0-.62.03-.88.09s-.49.15-.67.26-.32.24-.42.4-.15.33-.15.52c0,.21.06.4.17.57s.27.33.47.47.45.3.75.44.62.29.99.44c.5.21.96.44,1.36.67.4.24.75.51,1.03.8s.51.64.66,1.02.23.83.23,1.34c0,.7-.13,1.29-.4,1.77s-.63.86-1.08,1.16-.99.51-1.59.64c-.61.13-1.25.19-1.92.19s-1.35-.06-1.97-.18c-.62-.12-1.16-.29-1.62-.53Z"/>
<path class="cls-1" d="M16.35,40.54h-2.87l-5.19-7.92c-.3-.46-.52-.81-.63-1.05h-.04c.05.45.07,1.12.07,2.04v6.93h-2.68v-12.6h3.06l5,7.67c.23.35.44.69.63,1.03h.04c-.05-.29-.07-.87-.07-1.73v-6.97h2.68v12.6Z"/>
<path class="cls-1" d="M30.45,40.54h-3.09l-.9-2.8h-4.48l-.89,2.8h-3.08l4.59-12.6h3.37l4.48,12.6ZM25.81,35.56l-1.35-4.24c-.1-.32-.17-.69-.21-1.13h-.07c-.03.37-.1.74-.22,1.1l-1.37,4.27h3.23Z"/>
<path class="cls-1" d="M41,30.25h-3.59v10.29h-2.85v-10.29h-3.58v-2.31h10.02v2.31Z"/>
<path class="cls-1" d="M53.09,35.08c0,3.79-1.76,5.68-5.29,5.68s-5.13-1.85-5.13-5.55v-7.28h2.85v7.31c0,2.04.8,3.06,2.39,3.06s2.35-.98,2.35-2.95v-7.42h2.84v7.15Z"/>
<path class="cls-1" d="M66.53,40.54h-3.26l-1.96-3.24c-.15-.25-.29-.47-.42-.66s-.27-.36-.41-.5-.28-.24-.43-.32-.31-.11-.49-.11h-.76v4.83h-2.84v-12.6h4.5c3.06,0,4.59,1.14,4.59,3.43,0,.44-.07.85-.2,1.22s-.33.71-.57,1.01-.54.56-.89.77-.74.39-1.16.51v.04c.19.06.37.15.54.29s.35.29.51.46.32.36.47.57.29.4.41.59l2.38,3.73ZM58.8,30.07v3.51h1.23c.61,0,1.1-.18,1.47-.53.38-.36.56-.8.56-1.33,0-1.1-.66-1.65-1.98-1.65h-1.28Z"/>
<path class="cls-1" d="M78.41,40.54h-3.26l-1.96-3.24c-.15-.25-.29-.47-.42-.66s-.27-.36-.41-.5-.28-.24-.43-.32-.31-.11-.49-.11h-.76v4.83h-2.84v-12.6h4.5c3.06,0,4.59,1.14,4.59,3.43,0,.44-.07.85-.2,1.22s-.33.71-.57,1.01-.54.56-.89.77-.74.39-1.16.51v.04c.19.06.37.15.54.29s.35.29.51.46.32.36.47.57.29.4.41.59l2.38,3.73ZM70.68,30.07v3.51h1.23c.61,0,1.1-.18,1.47-.53.38-.36.56-.8.56-1.33,0-1.1-.66-1.65-1.98-1.65h-1.28Z"/>
<path class="cls-1" d="M87.27,40.54h-7.56v-12.6h7.27v2.31h-4.43v2.8h4.12v2.3h-4.12v2.88h4.72v2.3Z"/>
<path class="cls-1" d="M88.84,40.06v-2.81c.51.43,1.06.75,1.66.96s1.2.32,1.81.32c.36,0,.67-.03.94-.1.27-.06.49-.15.67-.27.18-.11.31-.25.4-.4s.13-.32.13-.51c0-.25-.07-.47-.21-.66s-.33-.37-.58-.54-.53-.32-.87-.47-.69-.31-1.08-.47c-.98-.41-1.72-.91-2.2-1.5-.48-.59-.72-1.31-.72-2.14,0-.66.13-1.22.4-1.69s.62-.86,1.08-1.16c.45-.3.98-.53,1.58-.67s1.23-.22,1.9-.22,1.24.04,1.75.12c.51.08.97.2,1.4.36v2.63c-.21-.15-.44-.28-.69-.39s-.5-.2-.77-.28-.53-.13-.79-.16c-.26-.04-.51-.05-.74-.05-.32,0-.62.03-.88.09s-.49.15-.67.26-.32.24-.42.4-.15.33-.15.52c0,.21.06.4.17.57s.27.33.47.47.45.3.75.44.62.29.99.44c.5.21.96.44,1.36.67.4.24.75.51,1.03.8s.51.64.66,1.02.23.83.23,1.34c0,.7-.13,1.29-.4,1.77s-.63.86-1.08,1.16-.99.51-1.59.64c-.61.13-1.25.19-1.92.19s-1.35-.06-1.97-.18c-.62-.12-1.16-.29-1.62-.53Z"/>
<path class="cls-1" d="M107.19,40.54h-7.56v-12.6h7.27v2.31h-4.43v2.8h4.12v2.3h-4.12v2.88h4.72v2.3Z"/>
<path class="cls-1" d="M119.92,40.54h-3.26l-1.96-3.24c-.15-.25-.29-.47-.42-.66s-.27-.36-.41-.5-.28-.24-.43-.32c-.15-.07-.31-.11-.49-.11h-.76v4.83h-2.84v-12.6h4.5c3.06,0,4.59,1.14,4.59,3.43,0,.44-.07.85-.2,1.22s-.33.71-.57,1.01-.54.56-.89.77-.74.39-1.16.51v.04c.19.06.37.15.54.29s.35.29.51.46.32.36.47.57c.15.2.29.4.41.59l2.38,3.73ZM112.18,30.07v3.51h1.23c.61,0,1.1-.18,1.47-.53.38-.36.56-.8.56-1.33,0-1.1-.66-1.65-1.98-1.65h-1.28Z"/>
<path class="cls-1" d="M131.71,27.94l-4.34,12.6h-3.22l-4.29-12.6h3.06l2.63,8.77c.14.47.23.89.25,1.26h.05c.04-.39.13-.82.27-1.29l2.61-8.74h2.97Z"/>
<path class="cls-1" d="M144.43,40.54h-3.09l-.9-2.8h-4.48l-.89,2.8h-3.08l4.59-12.6h3.37l4.48,12.6ZM139.79,35.56l-1.35-4.24c-.1-.32-.17-.69-.21-1.13h-.07c-.03.37-.1.74-.22,1.1l-1.37,4.27h3.23Z"/>
<path class="cls-1" d="M154.98,30.25h-3.59v10.29h-2.85v-10.29h-3.58v-2.31h10.02v2.31Z"/>
</g>
<g>
<path class="cls-1" d="M18.5,151.08h-2.55l-4.62-7.04c-.27-.41-.46-.72-.56-.93h-.03c.04.4.06,1,.06,1.81v6.16h-2.38v-11.2h2.72l4.45,6.82c.2.31.39.61.56.91h.03c-.04-.26-.06-.77-.06-1.54v-6.2h2.38v11.2Z"/>
<path class="cls-1" d="M31.03,151.08h-2.75l-.8-2.49h-3.98l-.79,2.49h-2.73l4.08-11.2h2.99l3.98,11.2ZM26.9,146.65l-1.2-3.77c-.09-.28-.15-.62-.19-1.01h-.06c-.03.33-.09.65-.2.98l-1.22,3.8h2.87Z"/>
<path class="cls-1" d="M40.4,141.93h-3.2v9.15h-2.53v-9.15h-3.18v-2.05h8.91v2.05Z"/>
<path class="cls-1" d="M51.16,146.23c0,3.37-1.57,5.05-4.7,5.05s-4.56-1.64-4.56-4.93v-6.47h2.53v6.5c0,1.81.71,2.72,2.12,2.72s2.09-.88,2.09-2.62v-6.59h2.52v6.35Z"/>
<path class="cls-1" d="M63.1,151.08h-2.9l-1.74-2.88c-.13-.22-.26-.41-.38-.59-.12-.17-.24-.32-.36-.44-.12-.12-.25-.22-.38-.28-.13-.06-.28-.1-.43-.1h-.68v4.29h-2.52v-11.2h4c2.72,0,4.08,1.02,4.08,3.05,0,.39-.06.75-.18,1.08-.12.33-.29.63-.51.89s-.48.5-.79.69c-.31.19-.66.34-1.04.45v.03c.17.05.33.14.48.25s.31.25.45.41c.15.16.29.32.42.5s.25.36.36.53l2.12,3.31ZM56.23,141.76v3.12h1.09c.54,0,.98-.16,1.3-.47.33-.32.5-.71.5-1.18,0-.98-.59-1.47-1.76-1.47h-1.14Z"/>
<path class="cls-1" d="M73.59,139.87l-3.86,11.2h-2.86l-3.81-11.2h2.72l2.34,7.8c.12.42.2.79.23,1.12h.05c.04-.35.12-.73.24-1.15l2.32-7.77h2.64Z"/>
<path class="cls-1" d="M84.9,151.08h-2.75l-.8-2.49h-3.98l-.79,2.49h-2.73l4.08-11.2h2.99l3.98,11.2ZM77.57,138.83c-.35,0-.64-.1-.87-.31-.22-.21-.34-.46-.34-.76s.11-.57.34-.77c.23-.2.52-.3.86-.3s.64.1.86.3c.22.2.33.46.33.77s-.11.58-.33.77c-.22.2-.51.3-.86.3ZM80.77,146.65l-1.2-3.77c-.09-.28-.15-.62-.19-1.01h-.06c-.03.33-.09.65-.2.98l-1.22,3.8h2.87ZM81.15,138.83c-.35,0-.64-.1-.86-.3-.22-.2-.34-.46-.34-.77s.11-.58.34-.77c.22-.2.51-.3.86-.3s.64.1.86.3c.23.2.34.46.34.77s-.11.57-.34.77c-.22.2-.51.3-.87.3Z"/>
<path class="cls-1" d="M95.81,151.08h-2.9l-1.74-2.88c-.13-.22-.25-.41-.38-.59s-.24-.32-.36-.44c-.12-.12-.25-.22-.38-.28-.13-.06-.28-.1-.43-.1h-.68v4.29h-2.52v-11.2h4c2.72,0,4.08,1.02,4.08,3.05,0,.39-.06.75-.18,1.08-.12.33-.29.63-.51.89s-.48.5-.79.69c-.31.19-.66.34-1.04.45v.03c.17.05.33.14.48.25s.31.25.45.41.29.32.42.5.25.36.36.53l2.12,3.31ZM88.93,141.76v3.12h1.09c.54,0,.98-.16,1.3-.47.33-.32.5-.71.5-1.18,0-.98-.59-1.47-1.76-1.47h-1.14Z"/>
<path class="cls-1" d="M96.97,151.08v-11.2h3.97c3.98,0,5.97,1.82,5.97,5.46,0,1.75-.54,3.14-1.63,4.18-1.09,1.04-2.53,1.56-4.34,1.56h-3.97ZM99.49,141.93v7.1h1.25c1.09,0,1.95-.33,2.57-.98s.93-1.55.93-2.68c0-1.07-.31-1.91-.93-2.52-.62-.61-1.48-.92-2.6-.92h-1.23Z"/>
<path class="cls-1" d="M118.73,151.08h-2.75l-.8-2.49h-3.98l-.79,2.49h-2.73l4.08-11.2h2.99l3.98,11.2ZM114.6,146.65l-1.2-3.77c-.09-.28-.15-.62-.19-1.01h-.06c-.03.33-.09.65-.2.98l-1.22,3.8h2.87Z"/>
<path class="cls-1" d="M129.64,151.08h-2.9l-1.74-2.88c-.13-.22-.25-.41-.38-.59s-.24-.32-.36-.44c-.12-.12-.25-.22-.38-.28-.13-.06-.28-.1-.43-.1h-.68v4.29h-2.52v-11.2h4c2.72,0,4.08,1.02,4.08,3.05,0,.39-.06.75-.18,1.08-.12.33-.29.63-.51.89s-.48.5-.79.69c-.31.19-.66.34-1.04.45v.03c.17.05.33.14.48.25s.31.25.45.41.29.32.42.5.25.36.36.53l2.12,3.31ZM122.76,141.76v3.12h1.09c.54,0,.98-.16,1.3-.47.33-.32.5-.71.5-1.18,0-.98-.59-1.47-1.76-1.47h-1.14Z"/>
<path class="cls-1" d="M140.87,151.08h-2.55l-4.62-7.04c-.27-.41-.46-.72-.56-.93h-.03c.04.4.06,1,.06,1.81v6.16h-2.38v-11.2h2.72l4.45,6.82c.2.31.39.61.56.91h.03c-.04-.26-.06-.77-.06-1.54v-6.2h2.38v11.2Z"/>
<path class="cls-1" d="M153.4,151.08h-2.75l-.8-2.49h-3.98l-.79,2.49h-2.73l4.08-11.2h2.99l3.98,11.2ZM149.27,146.65l-1.2-3.77c-.09-.28-.15-.62-.19-1.01h-.06c-.03.33-.09.65-.2.98l-1.22,3.8h2.87Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB