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'; 'use client';
import { useState, useEffect } from 'react';
import { useTheme } from 'next-themes';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; 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 const pythonCode = `import quantum_entanglement
import neural_net_vibes import neural_net_vibes
@@ -44,16 +46,26 @@ if __name__ == "__main__":
analyzer.check_is_sandwich(target="glizzy")`; analyzer.check_is_sandwich(target="glizzy")`;
export default function BlurredCode() { export default function BlurredCode() {
const { resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
const timer = setTimeout(() => setMounted(true), 0);
return () => clearTimeout(timer);
}, []);
return ( return (
<div className="absolute inset-0 overflow-hidden bg-[#0d1117] z-0 pointer-events-none flex justify-center"> <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-[2px] group-hover:blur-none group-hover:opacity-100 transition-all duration-700 animate-[scrollUp_40s_linear_infinite]"> <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 <SyntaxHighlighter
language="python" language="python"
style={vscDarkPlus} style={resolvedTheme === 'light' ? oneLight : oneDark}
customStyle={{ background: 'transparent', margin: 0, padding: 0, fontSize: '14px' }} customStyle={{ margin: 0, padding: 0, fontSize: '14px' }}
> >
{pythonCode + '\n\n\n' + pythonCode + '\n\n\n' + pythonCode} {pythonCode + '\n\n\n' + pythonCode + '\n\n\n' + pythonCode}
</SyntaxHighlighter> </SyntaxHighlighter>
)}
</div> </div>
</div> </div>
); );
+28 -8
View File
@@ -2,23 +2,41 @@
'use client'; 'use client';
import { useEffect, useRef } from 'react'; import { useEffect, useRef, useState } from 'react';
import { useTheme } from 'next-themes';
interface MatrixRainProps { interface MatrixRainProps {
color?: string; color?: string;
fps?: number; 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 canvasRef = useRef<HTMLCanvasElement>(null);
const lastWidth = useRef<number>(0); const lastWidth = useRef<number>(0);
const { resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => { useEffect(() => {
const timer = setTimeout(() => setMounted(true), 0);
return () => clearTimeout(timer);
}, []);
useEffect(() => {
if (!mounted) return;
const canvas = canvasRef.current; const canvas = canvasRef.current;
if (!canvas) return; if (!canvas) return;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
if (!ctx) return; 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; const fontSize = 16;
let columns = 0; let columns = 0;
let drops: number[] = []; let drops: number[] = [];
@@ -26,7 +44,7 @@ export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainPr
const setCanvasSize = () => { const setCanvasSize = () => {
canvas.width = window.innerWidth; canvas.width = window.innerWidth;
canvas.height = window.innerHeight + 120; canvas.height = window.innerHeight + 120;
ctx.fillStyle = '#0d1117'; ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
}; };
@@ -43,13 +61,13 @@ export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainPr
initDrops(); initDrops();
const draw = () => { const draw = () => {
ctx.fillStyle = 'rgba(13, 17, 23, 0.2)'; ctx.fillStyle = fadeColor;
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = `bold ${fontSize}px monospace`; ctx.font = `bold ${fontSize}px monospace`;
for (let i = 0; i < drops.length; i++) { for (let i = 0; i < drops.length; i++) {
const text = Math.random() > 0.5 ? '0' : '1'; const text = Math.random() > 0.5 ? '0' : '1';
ctx.fillStyle = color; ctx.fillStyle = textColor;
ctx.fillText(text, i * fontSize, drops[i] * fontSize); ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) { 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); clearInterval(intervalId);
window.removeEventListener('resize', handleResize); window.removeEventListener('resize', handleResize);
}; };
}, [color, fps]); }, [color, fps, resolvedTheme, mounted]); // Re-run effect if theme changes
return ( 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 <canvas
ref={canvasRef} 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> </div>
); );
} }
+36 -14
View File
@@ -3,51 +3,61 @@
'use client'; 'use client';
import Link from 'next/link'; import Link from 'next/link';
import { useState } from 'react'; import { useState, useEffect } from 'react';
import Image from 'next/image'; import Image from 'next/image';
import { useTheme } from 'next-themes';
import { FaSun, FaMoon } from 'react-icons/fa';
export default function Navbar() { export default function Navbar() {
const [isExpanded, setIsExpanded] = useState(false); 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 toggleMenu = () => setIsExpanded(!isExpanded);
const closeMenu = () => setIsExpanded(false); const closeMenu = () => setIsExpanded(false);
return ( 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"> <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-400 px-8 mx-auto"> <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}> <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]/10 border border-[#84c0a0]/30 shadow-[0_0_15px_rgba(132,192,160,0.2)] group-hover:bg-[#84c0a0]/20 transition-all duration-300"> <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 <Image
src="/assets/logos/logo.svg" src="/assets/logos/logo.svg"
alt="Wiking" alt="Wiking"
width={32} width={32}
height={32} height={32}
className="w-8 h-8 filter dark:invert-0 invert" className="w-8 h-8"
/> />
</div> </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 SODERBERG TECH
</span> </span>
</Link> </Link>
<button <button
type="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} aria-expanded={isExpanded}
onClick={toggleMenu} 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-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-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 ? '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>
</button> </button>
<div <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} onClick={closeMenu}
> >
<ul <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()} onClick={(e) => e.stopPropagation()}
> >
{[ {[
@@ -58,7 +68,7 @@ export default function Navbar() {
].map((link) => ( ].map((link) => (
<li key={link.name} className="w-full md:w-auto"> <li key={link.name} className="w-full md:w-auto">
<Link <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} href={link.path}
onClick={closeMenu} onClick={closeMenu}
> >
@@ -67,6 +77,18 @@ export default function Navbar() {
</Link> </Link>
</li> </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> </ul>
</div> </div>
</nav> </nav>
+8 -5
View File
@@ -15,7 +15,7 @@ interface GalleryImage {
export default function PhotoGallery({ images }: { images: GalleryImage[] }) { export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
return ( 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> <Gallery>
<div className="grid grid-cols-2 lg:grid-cols-4 2xl:grid-cols-6 grid-flow-dense w-full"> <div className="grid grid-cols-2 lg:grid-cols-4 2xl:grid-cols-6 grid-flow-dense w-full">
{images.map((img, index) => { {images.map((img, index) => {
@@ -24,7 +24,7 @@ export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
return ( return (
<div <div
key={index} 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 <Item
original={img.src} original={img.src}
@@ -39,8 +39,11 @@ export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
onClick={open} onClick={open}
className="w-full h-full relative block min-h-75" 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> {/* Outer Frame - Light border in light mode, Dark in dark mode */}
<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> <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 <Image
src={img.src} src={img.src}
@@ -49,7 +52,7 @@ export default function PhotoGallery({ images }: { images: GalleryImage[] }) {
height={isHorizontal ? 800 : 800} height={isHorizontal ? 800 : 800}
quality={90} quality={90}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" 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> </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() { export default function ContactPage() {
return ( 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 */} {/* 1. Immersive Mountain Background */}
<Image <Image
@@ -16,14 +16,14 @@ export default function ContactPage() {
className="absolute inset-0 w-full h-full object-cover z-0" className="absolute inset-0 w-full h-full object-cover z-0"
/> />
{/* Dark blur overlay so the text and cards remain perfectly readable */} {/* 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> <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"> <section className="relative z-10 flex-1 flex flex-col justify-center items-center py-12 px-6">
<div className="mb-12 text-center"> <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! Find me here!
</h1> </h1>
<p className="text-[#84c0a0] font-mono font-bold tracking-widest mt-2 uppercase"> <p className="text-[#84c0a0] font-mono font-bold tracking-widest mt-2 uppercase">
@@ -31,20 +31,20 @@ export default function ContactPage() {
</p> </p>
</div> </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="grid grid-cols-1 md:grid-cols-2 gap-12">
<div className="flex flex-col gap-8"> <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="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"> <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" /> <FaEnvelope className="text-[#84c0a0] text-xl" />
</div> </div>
<div> <div>
<p className="text-gray-400 text-xs uppercase font-bold tracking-widest">Email</p> <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-white font-medium hover:text-[#84c0a0] transition-colors break-all"> <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 support@soderberg.tech
</a> </a>
</div> </div>
@@ -55,35 +55,35 @@ export default function ContactPage() {
<FaMapMarkerAlt className="text-[#84c0a0] text-xl" /> <FaMapMarkerAlt className="text-[#84c0a0] text-xl" />
</div> </div>
<div> <div>
<p className="text-gray-400 text-xs uppercase font-bold tracking-widest">Location</p> <p className="text-slate-500 dark:text-gray-400 text-xs uppercase font-bold tracking-widest transition-colors">Location</p>
<p className="text-white font-medium">Höganäs, Sweden</p> <p className="text-slate-900 dark:text-white font-medium transition-colors">Höganäs, Sweden</p>
</div> </div>
</div> </div>
</div> </div>
<div className="flex flex-col gap-4"> <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"> <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"> <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-white font-bold"> <div className="flex items-center gap-3 text-slate-900 dark:text-white font-bold transition-colors">
<FaLinkedin className="text-xl text-[#0077b5]" /> LinkedIn <FaLinkedin className="text-xl text-[#0077b5]" /> LinkedIn
</div> </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>
<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"> <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-white font-bold"> <div className="flex items-center gap-3 text-slate-900 dark:text-white font-bold transition-colors">
<FaDiscord className="text-xl text-[#5865F2]" /> Discord <FaDiscord className="text-xl text-[#5865F2]" /> Discord
</div> </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>
<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"> <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-white font-bold"> <div className="flex items-center gap-3 text-slate-900 dark:text-white font-bold transition-colors">
<FaInstagram className="text-xl text-[#E1306C]" /> Instagram <FaInstagram className="text-xl text-[#E1306C]" /> Instagram
</div> </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> </a>
</div> </div>
</div> </div>
@@ -92,7 +92,7 @@ export default function ContactPage() {
<div className="mt-12"> <div className="mt-12">
<a <a
href="mailto:support@soderberg.tech?subject=Contact%20me" 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 <FaEnvelope /> Send an Email
</a> </a>
+5 -5
View File
@@ -30,7 +30,7 @@ export default async function GalleryPage() {
const images = await getImages(); const images = await getImages();
return ( 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 */} {/* 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> <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 */} {/* 2. Modernized Header */}
<section className="relative z-10 flex flex-col justify-center items-center py-20 px-6"> <section className="relative z-10 flex flex-col justify-center items-center py-20 px-6">
<div className="text-center"> <div className="text-center">
<h1 className="text-white text-[40px] md:text-[55px] uppercase font-black tracking-tighter drop-shadow-lg mb-4"> <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">
Visual Archives Gallery
</h1> </h1>
<div className="flex items-center justify-center gap-4 mb-6"> <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 className="w-12 h-px bg-[#84c0a0]"></div>
</div> </div>
<p className="text-gray-400 font-light max-w-2xl mx-auto text-lg leading-relaxed"> <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 photographic captures. Finding the best subjects to capture on film, from natural landscapes to the night sky. A curated collection of photograps. Finding the best subjects to capture, from natural landscapes to the night sky.
</p> </p>
</div> </div>
</section> </section>
+2
View File
@@ -2,6 +2,8 @@
@import "tailwindcss"; @import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@keyframes zoomIn { @keyframes zoomIn {
0% { 0% {
opacity: 0; opacity: 0;
+11 -13
View File
@@ -1,8 +1,9 @@
// app/layout.tsx // app/layout.tsx
import Navbar from './components/Navbar';
import './globals.css';
import Link from 'next/link'; import Link from 'next/link';
import Navbar from './components/Navbar';
import { ThemeProvider } from './components/ThemeProvider';
import './globals.css';
export const metadata = { export const metadata = {
title: 'Soderberg Tech', title: 'Soderberg Tech',
@@ -12,30 +13,27 @@ export const metadata = {
shortcut: '/assets/logos/logo.svg', shortcut: '/assets/logos/logo.svg',
apple: '/assets/logos/logo.svg', apple: '/assets/logos/logo.svg',
}, },
}; };
export default function RootLayout({ export default function RootLayout({ children }: { children: React.ReactNode }) {
children,
}: {
children: React.ReactNode;
}) {
return ( return (
<html lang="en"> <html lang="en" suppressHydrationWarning>
<body className="flex flex-col min-h-screen m-0 p-0 font-sans bg-[#0d1117]"> <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 /> <Navbar />
<main className="flex flex-col flex-1"> <main className="flex flex-col flex-1">
{children} {children}
</main> </main>
<footer className="w-full relative z-50 mt-auto border-t border-white/5"> <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-[#0d1117] flex justify-center items-center h-10"> <div className="bg-slate-100 dark:bg-[#0d1117] flex justify-center items-center h-10 transition-colors duration-300">
<Link className="text-[#a0aab6] no-underline flex font-medium items-center hover:text-white transition-colors text-sm tracking-widest uppercase" href="/"> <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()} © William Söderberg {new Date().getFullYear()}
</Link> </Link>
</div> </div>
</footer> </footer>
</ThemeProvider>
</body> </body>
</html> </html>
); );
+51 -86
View File
@@ -8,29 +8,24 @@ import { TbCube3dSphere } from 'react-icons/tb';
import Image from 'next/image'; import Image from 'next/image';
export default function Home() { export default function Home() {
const calculateAge = (birthDateString: string): number => { const calculateAge = (birthDateString: string): number => {
const today = new Date(); const today = new Date();
const birthDate = new Date(birthDateString); const birthDate = new Date(birthDateString);
let age = today.getFullYear() - birthDate.getFullYear(); let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth(); const monthDiff = today.getMonth() - birthDate.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) { if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
age--; age--;
} }
return age; return age;
}; };
return ( 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 */} {/* 1. HERO SECTION */}
<section className="relative h-screen min-h-175 flex flex-col justify-center items-center overflow-hidden"> <section className="relative h-screen min-h-175 flex flex-col justify-center items-center overflow-hidden">
{/* Ambient Overlay for contrast */} {/* 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="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]"> <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"> <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 Technical High School Engineer
</h2> </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 William Söderberg
</h1> </h1>
<div className="mt-10 flex gap-4"> <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 View Portfolios
</Link> </Link>
</div> </div>
@@ -54,51 +49,42 @@ export default function Home() {
{/* 2. ABOUT ME SECTION */} {/* 2. ABOUT ME SECTION */}
<section className="relative py-24 px-6"> <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]/10 dark: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]/5 blur-[120px] rounded-full pointer-events-none"></div>
<div className="max-w-6xl mx-auto"> <div className="max-w-6xl mx-auto relative z-10">
{/* Subtitle Header */}
<div className="text-center mb-12"> <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> <p className="text-[#84c0a0] mt-4 font-mono uppercase text-sm tracking-widest font-bold">Identity & Background</p>
</div> </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"> <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">
{/* Left Column: Profile with "Scanning" Effect */} <Image src="/assets/images/profile_picture.jpg" alt="William Söderberg" width={800} height={1000} className="w-full h-full object-cover" />
<div className="lg:w-2/5 relative group border-b lg:border-b-0 lg:border-r border-white/10"> <div className="absolute inset-0 bg-linear-to-t from-black/80 dark:from-[#0d1117] via-transparent to-transparent opacity-60"></div>
<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="absolute bottom-8 left-8"> <div className="absolute bottom-8 left-8">
<h3 className="text-white text-2xl font-bold uppercase tracking-tight">William Söderberg</h3> <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> <p className="text-[#84c0a0] font-mono text-sm mt-1">EST. 2002 | SWEDEN</p>
</div> </div>
</div> </div>
{/* Right Column: Bio Content */}
<div className="lg:w-3/5 p-8 md:p-16 flex flex-col justify-center"> <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="flex items-center gap-4 mb-8">
<div className="w-12 h-1 border-t-2 border-[#84c0a0]"></div> <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> </div>
<p className="text-gray-300 text-lg leading-relaxed font-light"> <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. 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> </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> <div>
<p className="text-xs font-bold text-[#84c0a0] uppercase tracking-widest mb-1">Focus</p> <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>
<div> <div>
<p className="text-xs font-bold text-[#84c0a0] uppercase tracking-widest mb-1">Passions</p> <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> </div>
</div> </div>
@@ -108,28 +94,27 @@ export default function Home() {
{/* 3. WHAT DO I DO SECTION */} {/* 3. WHAT DO I DO SECTION */}
<section className="relative py-24 px-6 overflow-hidden"> <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 opacity-80" />
<Image src="/assets/images/leaves.jpg" alt="Leaves" fill className="object-cover z-0" /> <div className="absolute inset-0 bg-slate-50/20 dark:bg-[#0d1117]/50 z-0 transition-colors duration-300"></div>
<div className="absolute inset-0 bg-[#0d1117]/50 z-0"></div>
<div className="relative z-10 max-w-6xl mx-auto"> <div className="relative z-10 max-w-6xl mx-auto">
<div className="text-center mb-16"> <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> <p className="text-[#84c0a0] mt-4 font-mono uppercase text-sm tracking-widest font-bold">A multidisciplinary engineer</p>
</div> </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: <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: <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) => ( ].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 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-[#84c0a0] text-4xl mb-6 w-fit group-hover:scale-110 transition-transform duration-300">{item.icon}</div> <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-white text-2xl font-bold mb-4">{item.title}</h3> <h3 className="text-slate-900 dark:text-white text-2xl font-bold mb-4 transition-colors">{item.title}</h3>
<p className="text-gray-400 text-sm leading-relaxed">{item.desc}</p> <p className="text-slate-600 dark:text-gray-400 text-sm leading-relaxed transition-colors">{item.desc}</p>
</div> </div>
))} ))}
</div> </div>
@@ -137,44 +122,39 @@ export default function Home() {
</section> </section>
{/* 4. PHOTO GALLERY 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="max-w-6xl mx-auto">
<div className="text-center mb-16"> <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> <p className="text-[#84c0a0] mt-4 font-mono uppercase text-sm tracking-widest font-bold">Capturing the world</p>
</div> </div>
<div className="flex flex-col lg:flex-row items-center lg:items-start gap-12 lg:gap-16"> <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"> <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" /> <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/10 backdrop-blur-xl border border-white/20 py-6 px-10 shadow-2xl rounded-2xl"> <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-white font-black whitespace-nowrap uppercase tracking-wider">My Photos</h2> <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>
</div> </div>
{/* Night Sky Collection */}
<div className="flex flex-col items-start w-full lg:w-1/2 lg:pt-8"> <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" /> <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-white text-[26px] mt-8 font-bold uppercase tracking-wide">My Photography collection</h3> <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> <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"> <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 subjects to capture on film, from nature to the night skies. Taking photos is just one of my many hobbies. Finding the best motives to capture, from nature to the night skies.
</p> </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 More photos
</Link> </Link>
</div> </div>
</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-slate-200 dark:border-white/10 group">
<div className="w-full mt-32 relative h-125 md:h-175 rounded-[40px] overflow-hidden shadow-2xl border border-white/10 group">
<Image src="/assets/images/singapore.jpg" alt="Singapore" fill className="object-cover transition-transform duration-1000 group-hover:scale-105" /> <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="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"> <p className="text-[18px] font-medium text-white leading-relaxed">
A cloudy day in Singapore, the New Zealand trip 2019. A cloudy day in Singapore, the New Zealand trip 2019.
</p> </p>
@@ -188,38 +168,23 @@ export default function Home() {
</div> </div>
</section> </section>
{/* 5. CONTACT CALL-TO-ACTION (Compact Banner) */} {/* 5. CONTACT CALL-TO-ACTION */}
<section className="relative py-16 px-6 overflow-hidden border-t border-white/5"> <section className="relative py-16 px-6 overflow-hidden border-t border-slate-200 dark:border-white/5 transition-colors duration-300">
{/* Immersive Mountain Background */} <Image src="/assets/images/snowy_mountain_peaks.jpg" alt="Snowy Mountains" fill className="object-cover z-0" />
<Image <div className="absolute inset-0 bg-slate-100/40 dark:bg-[#0d1117]/80 backdrop-blur-[2px] z-0 transition-colors duration-300"></div>
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">
<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"> <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 Let&apos;s Connect
</h2> </h2>
<p className="text-[#84c0a0] font-mono uppercase text-xs md:text-sm tracking-widest font-bold"> <p className="text-[#84c0a0] font-mono uppercase text-xs md:text-sm tracking-widest font-bold">
Transmission & Socials Contact info & Socials
</p> </p>
</div> </div>
<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)]">
<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)]"
>
Contact Me Contact Me
</Link> </Link>
</div> </div>
</section> </section>
</div> </div>
+42 -41
View File
@@ -107,7 +107,7 @@ export default async function CodePage() {
]); ]);
return ( 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 /> <MatrixRain />
<div className="h-25 shrink-0"></div> <div className="h-25 shrink-0"></div>
@@ -117,35 +117,35 @@ export default async function CodePage() {
{/* 2. Profile Card Section */} {/* 2. Profile Card Section */}
{profile && ( {profile && (
<section className="flex justify-center mt-10"> <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"> <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> </a>
<div className="w-full"> <div className="w-full">
<div className="relative h-37.5 w-37.5 mx-auto mb-5"> <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> </div>
<h1 className="mb-1"> <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} {profile.name}
</a> </a>
</h1> </h1>
<div className="mb-5"> <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} @{profile.login}
</a> </a>
</div> </div>
<p className="font-medium mx-auto text-[#84c0a0] mt-2.5 text-[15px] leading-relaxed"> <p className="font-medium mx-auto text-[#84c0a0] mt-2.5 text-[15px] leading-relaxed">
{profile.bio} {profile.bio}
</p> </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="relative">
<div className="text-white text-[22px] font-bold">{profile.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-[#a0aab6] tracking-widest uppercase mt-1">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>
<div className="relative"> <div className="relative">
<div className="text-white text-[22px] font-bold">{profile.public_repos}</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-[#a0aab6] tracking-widest uppercase mt-1">Repositories</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> </div>
</div> </div>
@@ -154,35 +154,34 @@ export default async function CodePage() {
)} )}
{/* 3. GitLab Repositories Section */} {/* 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"> <div className="flex justify-center items-center flex-col mb-10">
<a href="https://gitlab.soderberg.tech/WilliamSoderberg" target="_blank" rel="noopener noreferrer"> <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" /> <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> </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 GitLab Projects
</h2> </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> </div>
{gitlabRepos.length > 0 ? ( {gitlabRepos.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 justify-center"> <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 justify-center">
{gitlabRepos.map((repo) => ( {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> <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} {repo.name}
</h3> </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.'} {repo.description || 'No description provided.'}
</p> </p>
</div> </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">
{/* NEW: GitLab Language Badge */}
{repo.language && ( {repo.language && (
<div className="flex items-center mr-5"> <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={`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> </div>
)} )}
{repo.star_count > 0 && ( {repo.star_count > 0 && (
@@ -200,35 +199,35 @@ export default async function CodePage() {
))} ))}
</div> </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> </section>
{/* 4. GitHub Repositories 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"> <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)]" /> <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-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">
Public Repositories Public Repositories
</h2> </h2>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 justify-center"> <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 justify-center">
{githubRepos.map((repo) => ( {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> <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} {repo.name}
</h3> </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.'} {repo.description || 'No description provided.'}
</p> </p>
</div> </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 && ( {repo.language && (
<div className="flex items-center mr-5"> <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={`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> </div>
)} )}
{repo.stargazers_count > 0 && ( {repo.stargazers_count > 0 && (
@@ -248,31 +247,33 @@ export default async function CodePage() {
</section> </section>
{/* 5. Hosted Websites 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"> <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)]" /> <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-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">
Hosted Websites Hosted Websites
</h2> </h2>
</div> </div>
{/* Changed from Flex to Grid for perfect centering! */} <div className="flex flex-wrap justify-center gap-12 max-w-5xl mx-auto py-6">
<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="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">
<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-lg dark:group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all dark:invert-0 filter invert" />
<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" />
<span className="font-bold tracking-wide text-center">Soderberg Tech</span> <span className="font-bold tracking-wide text-center">Soderberg Tech</span>
</a> </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"> <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-[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" /> <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> <span className="font-bold tracking-wide text-center">Lirkab</span>
</a> </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"> <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-[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" /> <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> <span className="font-bold tracking-wide text-center">Lerbergets Volleyboll</span>
</a> </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> </div>
</section> </section>
</div> </div>
</main> </main>
); );
+21 -13
View File
@@ -60,22 +60,30 @@ export default function DesignPage() {
const showOverlay = isPending || !isSceneReady; const showOverlay = isPending || !isSceneReady;
return ( 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="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="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"> {/* Changed from flex-col to lg:flex-row for side-by-side layout on desktop */}
<div className="pt-5 flex justify-center items-center flex-col text-center"> <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">
<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> {/* 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> </div>
<section className="w-full flex justify-center"> {/* 2. Viewer Section (Now taking up the right side) */}
<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"> <section className="w-full lg:w-2/3 flex justify-center">
<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"> <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 && ( {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> <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"> <p className="text-[#84c0a0] font-mono text-xs uppercase tracking-[0.2em] font-bold">
{isPending ? "Fetching Data..." : "Compiling Materials..."} {isPending ? "Fetching Data..." : "Compiling Materials..."}
@@ -122,7 +130,7 @@ export default function DesignPage() {
innerStyles={{ display: 'none' }} 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 <Image
src={`/models/${activeModel}.png`} src={`/models/${activeModel}.png`}
alt="AR Preview" alt="AR Preview"
@@ -140,15 +148,15 @@ export default function DesignPage() {
<button <button
key={model.name} 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 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-white dark: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-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')` }} style={{ backgroundImage: `url('/models/${model.src}.png')` }}
onClick={() => handleModelChange(model.src)} onClick={() => handleModelChange(model.src)}
onMouseEnter={() => useGLTF.preload(`/models/${model.src}.glb`)} onMouseEnter={() => useGLTF.preload(`/models/${model.src}.glb`)}
aria-label={`View ${model.name} model`} 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} {model.name}
</span> </span>
</button> </button>
+11 -11
View File
@@ -7,17 +7,17 @@ import { FaCode } from 'react-icons/fa';
export default function ProjectsPage() { export default function ProjectsPage() {
return ( 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="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="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="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"> <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 My Portfolios
</h1> </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. Choose a discipline to explore my work.
</p> </p>
</div> </div>
@@ -26,12 +26,12 @@ export default function ProjectsPage() {
<Link <Link
href="/projects/code" 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 /> <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"> <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-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" /> <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-white text-[32px] md:text-[50px] font-bold text-center tracking-wide"> <h2 className="text-slate-900 dark:text-white text-[32px] md:text-[50px] font-bold text-center tracking-wide transition-colors">
Coding Coding
</h2> </h2>
</div> </div>
@@ -39,16 +39,16 @@ export default function ProjectsPage() {
<Link <Link
href="/projects/design" 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 <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" 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')` }} style={{ backgroundImage: `url('/assets/images/CAD.png')` }}
></div> ></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"> <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-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" /> <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-white text-[32px] md:text-[50px] font-bold text-center tracking-wide"> <h2 className="text-slate-900 dark:text-white text-[32px] md:text-[50px] font-bold text-center tracking-wide transition-colors">
CAD & Design CAD & Design
</h2> </h2>
</div> </div>
+11
View File
@@ -12,6 +12,7 @@
"@react-three/fiber": "^9.5.0", "@react-three/fiber": "^9.5.0",
"image-size": "^2.0.2", "image-size": "^2.0.2",
"next": "16.1.6", "next": "16.1.6",
"next-themes": "^0.4.6",
"photoswipe": "^5.4.4", "photoswipe": "^5.4.4",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "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": { "node_modules/next/node_modules/postcss": {
"version": "8.4.31", "version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+1
View File
@@ -13,6 +13,7 @@
"@react-three/fiber": "^9.5.0", "@react-three/fiber": "^9.5.0",
"image-size": "^2.0.2", "image-size": "^2.0.2",
"next": "16.1.6", "next": "16.1.6",
"next-themes": "^0.4.6",
"photoswipe": "^5.4.4", "photoswipe": "^5.4.4",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "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