Optimized images and linting
This commit is contained in:
@@ -19,7 +19,6 @@ export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainPr
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
|
|
||||||
let intervalId: NodeJS.Timeout;
|
|
||||||
const fontSize = 16;
|
const fontSize = 16;
|
||||||
let columns = 0;
|
let columns = 0;
|
||||||
let drops: number[] = [];
|
let drops: number[] = [];
|
||||||
@@ -60,7 +59,7 @@ export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainPr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
intervalId = setInterval(draw, 1000 / fps);
|
const intervalId = setInterval(draw, 1000 / fps);
|
||||||
|
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
if (window.innerWidth !== lastWidth.current) {
|
if (window.innerWidth !== lastWidth.current) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
const [isExpanded, setIsExpanded] = useState(false);
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
@@ -17,7 +18,13 @@ export default function Navbar() {
|
|||||||
|
|
||||||
<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-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]/10 border border-[#84c0a0]/30 shadow-[0_0_15px_rgba(132,192,160,0.2)] group-hover:bg-[#84c0a0]/20 transition-all duration-300">
|
||||||
<img src="/assets/logos/logo.svg" alt="Wiking" className="w-8 h-8" />
|
<Image
|
||||||
|
src="/assets/logos/logo.svg"
|
||||||
|
alt="Wiking"
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
className="w-8 h-8 filter dark:invert-0 invert"
|
||||||
|
/>
|
||||||
</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 group-hover:text-white transition-colors">
|
||||||
SODERBERG TECH
|
SODERBERG TECH
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
// app/contact/page.tsx
|
// app/contact/page.tsx
|
||||||
|
|
||||||
import { FaInstagram, FaLinkedin, FaDiscord, FaEnvelope, FaMapMarkerAlt } from 'react-icons/fa';
|
import { FaInstagram, FaLinkedin, FaDiscord, FaEnvelope, FaMapMarkerAlt } from 'react-icons/fa';
|
||||||
|
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-[#0d1117] overflow-hidden">
|
||||||
|
|
||||||
{/* 1. Immersive Mountain Background */}
|
{/* 1. Immersive Mountain Background */}
|
||||||
<img
|
<Image
|
||||||
src="/assets/images/snowy_mountain_peaks.jpg"
|
src="/assets/images/snowy_mountain_peaks.jpg"
|
||||||
alt="Snowy Mountains"
|
alt="Snowy Mountains"
|
||||||
|
fill
|
||||||
|
priority
|
||||||
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 */}
|
||||||
|
|||||||
+9
-2
@@ -2,10 +2,17 @@
|
|||||||
|
|
||||||
import Navbar from './components/Navbar';
|
import Navbar from './components/Navbar';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: 'Soderberg Tech',
|
title: 'Soderberg Tech',
|
||||||
description: 'William Söderberg, Technical high school engineer from Höganäs, Sweden',
|
description: 'William Söderberg, Technical high school engineer from Höganäs, Sweden',
|
||||||
|
icons: {
|
||||||
|
icon: '/assets/logos/logo.svg',
|
||||||
|
shortcut: '/assets/logos/logo.svg',
|
||||||
|
apple: '/assets/logos/logo.svg',
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
@@ -24,9 +31,9 @@ export default function RootLayout({
|
|||||||
|
|
||||||
<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-white/5">
|
||||||
<div className="bg-[#0d1117] flex justify-center items-center h-10">
|
<div className="bg-[#0d1117] flex justify-center items-center h-10">
|
||||||
<a className="text-[#a0aab6] no-underline flex font-medium items-center hover:text-white transition-colors text-sm tracking-widest uppercase" href="/">
|
<Link className="text-[#a0aab6] no-underline flex font-medium items-center hover:text-white transition-colors text-sm tracking-widest uppercase" href="/">
|
||||||
© William Söderberg {new Date().getFullYear()}
|
© William Söderberg {new Date().getFullYear()}
|
||||||
</a>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+15
-13
@@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import MatrixRain from '@/app/components/MatrixRain';
|
import { FaCamera, FaCode, FaTree, FaVolleyballBall } from 'react-icons/fa';
|
||||||
import { FaInstagram, FaLinkedin, FaDiscord, FaEnvelope, FaCamera, FaVolleyballBall, FaTree, FaCode } from 'react-icons/fa';
|
|
||||||
import { TbCube3dSphere } from 'react-icons/tb';
|
import { TbCube3dSphere } from 'react-icons/tb';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ export default function Home() {
|
|||||||
|
|
||||||
<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]">
|
||||||
<img src="/assets/logos/logo.svg" alt="Logo" className="h-[60%]" />
|
<Image src="/assets/logos/logo.svg" alt="Logo" width={130} height={130} className="w-[60%] h-[60%]" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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">
|
||||||
@@ -69,9 +68,11 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* Left Column: Profile with "Scanning" Effect */}
|
{/* Left Column: Profile with "Scanning" Effect */}
|
||||||
<div className="lg:w-2/5 relative group border-b lg:border-b-0 lg:border-r border-white/10">
|
<div className="lg:w-2/5 relative group border-b lg:border-b-0 lg:border-r border-white/10">
|
||||||
<img
|
<Image
|
||||||
src="/assets/images/profile_picture.jpg"
|
src="/assets/images/profile_picture.jpg"
|
||||||
alt="William Söderberg"
|
alt="William Söderberg"
|
||||||
|
width={800}
|
||||||
|
height={1000}
|
||||||
className="w-full h-full object-cover"
|
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 inset-0 bg-linear-to-t from-[#0d1117] via-transparent to-transparent opacity-60"></div>
|
||||||
@@ -88,7 +89,7 @@ export default function Home() {
|
|||||||
<h2 className="text-white text-3xl font-bold uppercase tracking-widest">DATA CARD</h2>
|
<h2 className="text-white text-3xl font-bold uppercase tracking-widest">DATA CARD</h2>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-gray-300 text-lg leading-relaxed font-light">
|
<p className="text-gray-300 text-lg leading-relaxed font-light">
|
||||||
My name is William Söderberg and I'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'm {calculateAge("2002-07-17")} years old. I have a degree in technical high school engineering specialized in design and industrial manufacturing, with heavy influence from IT and coding. I love problem solving and finding new ways to solve the most complicated problems.
|
||||||
</p>
|
</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-white/10 pt-10">
|
||||||
<div>
|
<div>
|
||||||
@@ -108,7 +109,7 @@ 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 */}
|
{/* Subtle Background Image Integration */}
|
||||||
<img src="/assets/images/leaves.jpg" alt="Leaves" className="absolute inset-0 w-full h-full object-cover z-0" />
|
<Image src="/assets/images/leaves.jpg" alt="Leaves" fill className="object-cover z-0" />
|
||||||
<div className="absolute inset-0 bg-[#0d1117]/50 z-0"></div>
|
<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">
|
||||||
@@ -147,7 +148,7 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* My Photos (Ynni Image) */}
|
{/* My Photos (Ynni Image) */}
|
||||||
<div className="relative w-full lg:w-1/2">
|
<div className="relative w-full lg:w-1/2">
|
||||||
<img src="/assets/images/ynni.jpg" alt="My Photos" className="w-full rounded-4xl shadow-2xl object-cover lg:h-160" />
|
<Image src="/assets/images/ynni.jpg" alt="My Photos" width={800} height={800} className="w-full rounded-4xl shadow-2xl object-cover lg:h-125" />
|
||||||
<div className="absolute top-[10%] -left-4 lg:-left-12 bg-white/10 backdrop-blur-xl border border-white/20 py-6 px-10 shadow-2xl rounded-2xl">
|
<div className="absolute top-[10%] -left-4 lg:-left-12 bg-white/10 backdrop-blur-xl border border-white/20 py-6 px-10 shadow-2xl rounded-2xl">
|
||||||
<h2 className="text-[30px] lg:text-[40px] text-white font-black whitespace-nowrap uppercase tracking-wider">My Photos</h2>
|
<h2 className="text-[30px] lg:text-[40px] text-white font-black whitespace-nowrap uppercase tracking-wider">My Photos</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -155,7 +156,7 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* Night Sky Collection */}
|
{/* 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">
|
||||||
<img src="/assets/images/night_sky.jpg" alt="Night Sky" className="w-full max-w-125 rounded-3xl shadow-xl border 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-gray-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-white text-[26px] mt-8 font-bold uppercase tracking-wide">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-gray-400 text-[18px] font-light leading-relaxed">
|
||||||
@@ -169,7 +170,7 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* Singapore Full Width wrapper */}
|
{/* Singapore Full Width wrapper */}
|
||||||
<div className="w-full mt-32 relative h-125 md:h-175 rounded-[40px] overflow-hidden shadow-2xl border border-white/10 group">
|
<div className="w-full mt-32 relative h-125 md:h-175 rounded-[40px] overflow-hidden shadow-2xl border border-white/10 group">
|
||||||
<img src="/assets/images/singapore.jpg" alt="Singapore" className="absolute inset-0 w-full h-full object-cover transition-transform duration-2000 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-[#0d1117]/90 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">
|
||||||
@@ -190,10 +191,11 @@ export default function Home() {
|
|||||||
{/* 5. CONTACT CALL-TO-ACTION (Compact Banner) */}
|
{/* 5. CONTACT CALL-TO-ACTION (Compact Banner) */}
|
||||||
<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-white/5">
|
||||||
{/* Immersive Mountain Background */}
|
{/* Immersive Mountain Background */}
|
||||||
<img
|
<Image
|
||||||
src="/assets/images/snowy_mountain_peaks.jpg"
|
src="/assets/images/snowy_mountain_peaks.jpg"
|
||||||
alt="Snowy Mountains"
|
alt="Snowy Mountains"
|
||||||
className="absolute inset-0 w-full h-full object-cover z-0"
|
fill
|
||||||
|
className="object-cover z-0"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Dark overlay */}
|
{/* Dark overlay */}
|
||||||
@@ -204,7 +206,7 @@ export default function Home() {
|
|||||||
|
|
||||||
<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-white text-3xl md:text-4xl font-black uppercase tracking-tighter mb-2">
|
||||||
Let's Connect
|
Let'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
|
Transmission & Socials
|
||||||
|
|||||||
+12
-11
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import MatrixRain from '@/app/components/MatrixRain';
|
import MatrixRain from '@/app/components/MatrixRain';
|
||||||
import { FaCodeBranch, FaGithub, FaGitlab, FaGlobe, FaStar } from 'react-icons/fa';
|
import { FaCodeBranch, FaGithub, FaGitlab, FaGlobe, FaStar } from 'react-icons/fa';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
interface GithubProfile {
|
interface GithubProfile {
|
||||||
html_url: string;
|
html_url: string;
|
||||||
@@ -38,7 +39,7 @@ async function getProfile(): Promise<GithubProfile | null> {
|
|||||||
const res = await fetch('https://api.github.com/users/WilliamSoderberg', { next: { revalidate: 60 } });
|
const res = await fetch('https://api.github.com/users/WilliamSoderberg', { next: { revalidate: 60 } });
|
||||||
if (!res.ok) return null;
|
if (!res.ok) return null;
|
||||||
return res.json();
|
return res.json();
|
||||||
} catch (e) {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +49,7 @@ async function getGithubRepos(): Promise<GithubRepo[]> {
|
|||||||
const res = await fetch('https://api.github.com/users/WilliamSoderberg/repos?sort=updated', { next: { revalidate: 60 } });
|
const res = await fetch('https://api.github.com/users/WilliamSoderberg/repos?sort=updated', { next: { revalidate: 60 } });
|
||||||
if (!res.ok) return [];
|
if (!res.ok) return [];
|
||||||
return res.json();
|
return res.json();
|
||||||
} catch (e) {
|
} catch {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +74,7 @@ async function getGitlabRepos(): Promise<GitlabRepo[]> {
|
|||||||
const topLanguage = Object.keys(languages).sort((a, b) => languages[b] - languages[a])[0];
|
const topLanguage = Object.keys(languages).sort((a, b) => languages[b] - languages[a])[0];
|
||||||
return { ...repo, language: topLanguage };
|
return { ...repo, language: topLanguage };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch {
|
||||||
console.error(`Failed to fetch language for GitLab repo: ${repo.id}`);
|
console.error(`Failed to fetch language for GitLab repo: ${repo.id}`);
|
||||||
}
|
}
|
||||||
return repo;
|
return repo;
|
||||||
@@ -81,7 +82,7 @@ async function getGitlabRepos(): Promise<GitlabRepo[]> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return projectsWithLanguages;
|
return projectsWithLanguages;
|
||||||
} catch (e) {
|
} catch {
|
||||||
console.error("GitLab fetch failed, returning empty array");
|
console.error("GitLab fetch failed, returning empty array");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -122,7 +123,7 @@ export default async function CodePage() {
|
|||||||
</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">
|
||||||
<img src={profile.avatar_url} alt="Avatar" className="h-full w-full rounded-full object-cover border-4 border-[#84c0a0] 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-[#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)]" />
|
||||||
</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-white text-[26px] font-bold tracking-wide no-underline hover:text-[#84c0a0] transition-colors" href={profile.html_url} target="_blank" rel="noopener noreferrer">
|
||||||
@@ -257,16 +258,16 @@ export default async function CodePage() {
|
|||||||
|
|
||||||
{/* Changed from Flex to Grid for perfect centering! */}
|
{/* Changed from Flex to Grid for perfect centering! */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 max-w-5xl mx-auto justify-items-center items-center py-6">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 max-w-5xl mx-auto justify-items-center items-center py-6">
|
||||||
<a className="no-underline text-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">
|
||||||
<img src="/assets/logos/logo.svg" alt="Soderberg Tech" className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all" />
|
<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-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://lirkab.se">
|
<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">
|
||||||
<img src="/assets/logos/lirkab.svg" alt="Lirkab" className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all" />
|
<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" />
|
||||||
<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-white text-[22px] flex flex-col items-center hover:scale-105 transition-transform group" href="https://lerbergetsvolleyboll.se">
|
<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">
|
||||||
<img src="/assets/logos/lvs.svg" alt="Lerbergets Volleyboll" className="w-22.5 h-16.25 object-contain mb-5 drop-shadow-md group-hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.5)] transition-all" />
|
<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" />
|
||||||
<span className="font-bold tracking-wide text-center">Lerbergets Volleyboll</span>
|
<span className="font-bold tracking-wide text-center">Lerbergets Volleyboll</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Canvas, useThree } from '@react-three/fiber';
|
|||||||
import { Suspense, useEffect, useState, useTransition } from 'react';
|
import { Suspense, useEffect, useState, useTransition } from 'react';
|
||||||
import { TbCube3dSphere } from 'react-icons/tb';
|
import { TbCube3dSphere } from 'react-icons/tb';
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
const models = [
|
const models = [
|
||||||
{ name: 'Wallet', src: 'Wallet' },
|
{ name: 'Wallet', src: 'Wallet' },
|
||||||
@@ -122,7 +123,13 @@ export default function DesignPage() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<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-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">
|
||||||
<img src={`/models/${activeModel}.png`} alt="AR Preview" className="w-5 h-5 rounded-full object-cover" />
|
<Image
|
||||||
|
src={`/models/${activeModel}.png`}
|
||||||
|
alt="AR Preview"
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
className="w-5 h-5 rounded-full object-cover"
|
||||||
|
/>
|
||||||
View in AR
|
View in AR
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+8
-1
@@ -4,7 +4,14 @@ import type { NextConfig } from "next";
|
|||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
images: {
|
images: {
|
||||||
qualities: [75, 80, 85, 90, 95, 100], // Add 90 here!
|
qualities: [75, 80, 85, 90, 95, 100],
|
||||||
|
remotePatterns: [
|
||||||
|
{
|
||||||
|
protocol: 'https',
|
||||||
|
hostname: 'avatars.githubusercontent.com',
|
||||||
|
pathname: '/**',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user