Compare commits

..

2 Commits

Author SHA1 Message Date
8714949289 chore: remove unnecessary "use client" directive from K-Suite page
All checks were successful
Build and Deploy Gabriel Kaszewski Portfolio / build-and-deploy-local (push) Successful in 1m3s
2025-12-31 00:34:41 +01:00
a0463d1db9 fix: update GitHub URL for K-Tuner project in data file 2025-12-31 00:33:33 +01:00
2 changed files with 408 additions and 401 deletions

View File

@@ -1,432 +1,439 @@
"use client";
import Image from "next/image"; import Image from "next/image";
import { ExternalLink, Github } from "lucide-react"; import { ExternalLink, Github } from "lucide-react";
interface KSuiteApp { interface KSuiteApp {
id: number; id: number;
name: string; name: string;
shortDescription: string; shortDescription: string;
description: string; description: string;
url: string; url: string;
githubUrl?: string | null; githubUrl?: string | null;
icon: string; icon: string;
technologies: string[]; technologies: string[];
color: string; color: string;
} }
const kSuiteApps: KSuiteApp[] = [ const kSuiteApps: KSuiteApp[] = [
{ {
id: 1, id: 1,
name: "K-Notes", name: "K-Notes",
shortDescription: "Google Keep replica", shortDescription: "Google Keep replica",
description: description:
"A full-featured note-taking app designed for speed and simplicity.", "A full-featured note-taking app designed for speed and simplicity.",
url: "https://knotes.gabrielkaszewski.dev/", url: "https://knotes.gabrielkaszewski.dev/",
githubUrl: "https://github.com/GKaszewski/k-notes", githubUrl: "https://github.com/GKaszewski/k-notes",
icon: "/images/k-notes.png", icon: "/images/k-notes.png",
technologies: ["Rust", "React", "TailwindCSS", "PWA"], technologies: ["Rust", "React", "TailwindCSS", "PWA"],
color: "from-amber-400 to-orange-500", color: "from-amber-400 to-orange-500",
}, },
{ {
id: 2, id: 2,
name: "Thoughts", name: "Thoughts",
shortDescription: "Microblogging platform", shortDescription: "Microblogging platform",
description: description:
"Nostalgic social platform with Frutiger Aero style. 128-char posts, custom CSS profiles.", "Nostalgic social platform with Frutiger Aero style. 128-char posts, custom CSS profiles.",
url: "https://thoughts.gabrielkaszewski.dev/", url: "https://thoughts.gabrielkaszewski.dev/",
githubUrl: "https://git.gabrielkaszewski.dev/GKaszewski/thoughts", githubUrl: "https://git.gabrielkaszewski.dev/GKaszewski/thoughts",
icon: "/images/thoughts.avif", icon: "/images/thoughts.avif",
technologies: ["Rust", "Next.js", "Axum"], technologies: ["Rust", "Next.js", "Axum"],
color: "from-cyan-400 to-blue-500", color: "from-cyan-400 to-blue-500",
}, },
{ {
id: 3, id: 3,
name: "K-Tuner", name: "K-Tuner",
shortDescription: "Instrument tuner", shortDescription: "Instrument tuner",
description: description:
"Tune guitar, ukulele, and piano with this Frutiger Aero styled PWA.", "Tune guitar, ukulele, and piano with this Frutiger Aero styled PWA.",
url: "https://tuner.gabrielkaszewski.dev/", url: "https://tuner.gabrielkaszewski.dev/",
githubUrl: "https://github.com/GKaszewski/aero-tuner", githubUrl: "https://github.com/GKaszewski/k-tuner",
icon: "/images/k-tuner.png", icon: "/images/k-tuner.png",
technologies: ["React", "PWA"], technologies: ["React", "PWA"],
color: "from-emerald-400 to-teal-500", color: "from-emerald-400 to-teal-500",
}, },
{ {
id: 4, id: 4,
name: "K-QR", name: "K-QR",
shortDescription: "QR code generator", shortDescription: "QR code generator",
description: description:
"High-performance QR generator. Single Rust executable serving clean HTML.", "High-performance QR generator. Single Rust executable serving clean HTML.",
url: "https://qr.gabrielkaszewski.dev/", url: "https://qr.gabrielkaszewski.dev/",
githubUrl: "https://github.com/GKaszewski/k-qr", githubUrl: "https://github.com/GKaszewski/k-qr",
icon: "/images/k-qr.png", icon: "/images/k-qr.png",
technologies: ["Rust", "HTML"], technologies: ["Rust", "HTML"],
color: "from-amber-400 to-orange-500" color: "from-amber-400 to-orange-500",
}, },
]; ];
// Connection definitions for the organism // Connection definitions for the organism
const connections = [ const connections = [
{ from: 0, to: 1 }, // K-Notes -> Thoughts { from: 0, to: 1 }, // K-Notes -> Thoughts
{ from: 1, to: 2 }, // Thoughts -> K-Tuner { from: 1, to: 2 }, // Thoughts -> K-Tuner
{ from: 2, to: 3 }, // K-Tuner -> K-QR { from: 2, to: 3 }, // K-Tuner -> K-QR
{ from: 3, to: 0 }, // K-QR -> K-Notes { from: 3, to: 0 }, // K-QR -> K-Notes
{ from: 0, to: 2 }, // K-Notes -> K-Tuner (cross) { from: 0, to: 2 }, // K-Notes -> K-Tuner (cross)
{ from: 1, to: 3 }, // Thoughts -> K-QR (cross) { from: 1, to: 3 }, // Thoughts -> K-QR (cross)
]; ];
const KSuiteOrganism = () => { const KSuiteOrganism = () => {
// Calculate positions for apps in a circular pattern // Calculate positions for apps in a circular pattern
const getPosition = (index: number, total: number, radius: number) => { const getPosition = (index: number, total: number, radius: number) => {
const angle = (index * 2 * Math.PI) / total - Math.PI / 2; const angle = (index * 2 * Math.PI) / total - Math.PI / 2;
return { return {
x: 50 + radius * Math.cos(angle), x: 50 + radius * Math.cos(angle),
y: 50 + radius * Math.sin(angle), y: 50 + radius * Math.sin(angle),
};
}; };
};
const radius = 35; const radius = 35;
const positions = kSuiteApps.map((_, i) => const positions = kSuiteApps.map((_, i) =>
getPosition(i, kSuiteApps.length, radius) getPosition(i, kSuiteApps.length, radius)
); );
return ( return (
<div className="relative w-full max-w-4xl mx-auto aspect-square"> <div className="relative w-full max-w-4xl mx-auto aspect-square">
{/* SVG Connection Lines */} {/* SVG Connection Lines */}
<svg <svg
className="absolute inset-0 w-full h-full pointer-events-none" className="absolute inset-0 w-full h-full pointer-events-none"
viewBox="0 0 100 100" viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid meet" preserveAspectRatio="xMidYMid meet"
>
<defs>
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="rgba(59, 130, 246, 0.6)" />
<stop offset="50%" stopColor="rgba(147, 51, 234, 0.6)" />
<stop offset="100%" stopColor="rgba(59, 130, 246, 0.6)" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="0.5" result="coloredBlur" />
<feMerge>
<feMergeNode in="coloredBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
{/* Connection lines */}
{connections.map((conn, i) => {
const from = positions[conn.from];
const to = positions[conn.to];
return (
<line
key={i}
x1={from.x}
y1={from.y}
x2={to.x}
y2={to.y}
stroke="url(#lineGradient)"
strokeWidth="0.3"
filter="url(#glow)"
className="animate-pulse"
style={{ animationDelay: `${i * 0.2}s` }}
/>
);
})}
{/* Lines from center to each app */}
{positions.map((pos, i) => (
<line
key={`center-${i}`}
x1={50}
y1={50}
x2={pos.x}
y2={pos.y}
stroke="url(#lineGradient)"
strokeWidth="0.2"
strokeDasharray="1 0.5"
filter="url(#glow)"
className="animate-pulse"
style={{ animationDelay: `${i * 0.3}s` }}
/>
))}
</svg>
{/* App Cards */}
{kSuiteApps.map((app, index) => {
const pos = positions[index];
return (
<div
key={app.id}
className="absolute transform -translate-x-1/2 -translate-y-1/2 w-32 md:w-40 lg:w-48"
style={{
left: `${pos.x}%`,
top: `${pos.y}%`,
}}
>
<div
className={`group relative p-3 md:p-4 rounded-2xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-xl hover:bg-white/20 hover:scale-105 transition-all duration-300 cursor-pointer`}
> >
<defs> {/* Glow effect on hover */}
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="100%" y2="100%"> <div
<stop offset="0%" stopColor="rgba(59, 130, 246, 0.6)" /> className={`absolute inset-0 rounded-2xl bg-gradient-to-br ${app.color} opacity-0 group-hover:opacity-20 transition-opacity duration-300 blur-xl`}
<stop offset="50%" stopColor="rgba(147, 51, 234, 0.6)" /> />
<stop offset="100%" stopColor="rgba(59, 130, 246, 0.6)" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="0.5" result="coloredBlur" />
<feMerge>
<feMergeNode in="coloredBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
{/* Connection lines */} {/* Content */}
{connections.map((conn, i) => { <div className="relative z-10 flex flex-col items-center text-center">
const from = positions[conn.from]; <div className="relative w-12 h-12 md:w-16 md:h-16 mb-2">
const to = positions[conn.to]; <Image
return ( src={app.icon}
<line alt={app.name}
key={i} fill
x1={from.x} className="object-contain rounded-lg"
y1={from.y} />
x2={to.x} </div>
y2={to.y} <h3 className="text-sm md:text-base font-bold text-white mb-1">
stroke="url(#lineGradient)" {app.name}
strokeWidth="0.3" </h3>
filter="url(#glow)" <p className="text-xs text-white/70 mb-2 hidden md:block">
className="animate-pulse" {app.shortDescription}
style={{ animationDelay: `${i * 0.2}s` }} </p>
/>
);
})}
{/* Links */}
<div className="flex gap-2">
{/* Lines from center to each app */} <a
{positions.map((pos, i) => ( href={app.url}
<line target="_blank"
key={`center-${i}`} rel="noopener noreferrer"
x1={50} className="p-1.5 rounded-full bg-white/10 hover:bg-white/30 transition-colors"
y1={50} title="Visit"
x2={pos.x} >
y2={pos.y} <ExternalLink size={14} className="text-white" />
stroke="url(#lineGradient)" </a>
strokeWidth="0.2" {app.githubUrl && (
strokeDasharray="1 0.5" <a
filter="url(#glow)" href={app.githubUrl}
className="animate-pulse" target="_blank"
style={{ animationDelay: `${i * 0.3}s` }} rel="noopener noreferrer"
/> className="p-1.5 rounded-full bg-white/10 hover:bg-white/30 transition-colors"
))} title="GitHub"
</svg>
{/* App Cards */}
{kSuiteApps.map((app, index) => {
const pos = positions[index];
return (
<div
key={app.id}
className="absolute transform -translate-x-1/2 -translate-y-1/2 w-32 md:w-40 lg:w-48"
style={{
left: `${pos.x}%`,
top: `${pos.y}%`,
}}
> >
<div <Github size={14} className="text-white" />
className={`group relative p-3 md:p-4 rounded-2xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-xl hover:bg-white/20 hover:scale-105 transition-all duration-300 cursor-pointer`} </a>
> )}
{/* Glow effect on hover */} </div>
<div </div>
className={`absolute inset-0 rounded-2xl bg-gradient-to-br ${app.color} opacity-0 group-hover:opacity-20 transition-opacity duration-300 blur-xl`} </div>
/> </div>
);
{/* Content */} })}
<div className="relative z-10 flex flex-col items-center text-center"> </div>
<div className="relative w-12 h-12 md:w-16 md:h-16 mb-2"> );
<Image
src={app.icon}
alt={app.name}
fill
className="object-contain rounded-lg"
/>
</div>
<h3 className="text-sm md:text-base font-bold text-white mb-1">
{app.name}
</h3>
<p className="text-xs text-white/70 mb-2 hidden md:block">
{app.shortDescription}
</p>
{/* Links */}
<div className="flex gap-2">
<a
href={app.url}
target="_blank"
rel="noopener noreferrer"
className="p-1.5 rounded-full bg-white/10 hover:bg-white/30 transition-colors"
title="Visit"
>
<ExternalLink size={14} className="text-white" />
</a>
{app.githubUrl && (
<a
href={app.githubUrl}
target="_blank"
rel="noopener noreferrer"
className="p-1.5 rounded-full bg-white/10 hover:bg-white/30 transition-colors"
title="GitHub"
>
<Github size={14} className="text-white" />
</a>
)}
</div>
</div>
</div>
</div>
);
})}
</div>
);
}; };
const KSuiteAppCard = ({ app }: { app: KSuiteApp }) => { const KSuiteAppCard = ({ app }: { app: KSuiteApp }) => {
return ( return (
<div className="group relative p-6 rounded-3xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-xl hover:bg-white/15 transition-all duration-300"> <div className="group relative p-6 rounded-3xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-xl hover:bg-white/15 transition-all duration-300">
{/* Gradient glow */} {/* Gradient glow */}
<div <div
className={`absolute inset-0 rounded-3xl bg-gradient-to-br ${app.color} opacity-0 group-hover:opacity-10 transition-opacity duration-300`} className={`absolute inset-0 rounded-3xl bg-gradient-to-br ${app.color} opacity-0 group-hover:opacity-10 transition-opacity duration-300`}
/>
<div className="relative z-10">
<div className="flex items-start gap-4 mb-4">
<div className="relative w-16 h-16 shrink-0">
<Image
src={app.icon}
alt={app.name}
fill
className="object-contain rounded-xl"
/> />
</div>
<div className="relative z-10"> <div>
<div className="flex items-start gap-4 mb-4"> <h3 className="text-xl font-bold text-white">{app.name}</h3>
<div className="relative w-16 h-16 shrink-0"> <p className="text-white/70">{app.shortDescription}</p>
<Image </div>
src={app.icon}
alt={app.name}
fill
className="object-contain rounded-xl"
/>
</div>
<div>
<h3 className="text-xl font-bold text-white">{app.name}</h3>
<p className="text-white/70">{app.shortDescription}</p>
</div>
</div>
<p className="text-white/80 mb-4">{app.description}</p>
<div className="flex flex-wrap gap-2 mb-4">
{app.technologies.map((tech) => (
<span
key={tech}
className="px-2 py-1 text-xs rounded-full bg-white/10 text-white/80"
>
{tech}
</span>
))}
</div>
<div className="flex gap-3">
<a
href={app.url}
target="_blank"
rel="noopener noreferrer"
className={`flex-1 flex items-center justify-center gap-2 px-4 py-2 rounded-xl bg-gradient-to-r ${app.color} text-white font-semibold hover:opacity-90 transition-opacity`}
>
<ExternalLink size={16} />
Visit
</a>
{app.githubUrl && (
<a
href={app.githubUrl}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-center px-4 py-2 rounded-xl border border-white/20 text-white hover:bg-white/10 transition-colors"
>
<Github size={16} />
</a>
)}
</div>
</div>
</div> </div>
);
<p className="text-white/80 mb-4">{app.description}</p>
<div className="flex flex-wrap gap-2 mb-4">
{app.technologies.map((tech) => (
<span
key={tech}
className="px-2 py-1 text-xs rounded-full bg-white/10 text-white/80"
>
{tech}
</span>
))}
</div>
<div className="flex gap-3">
<a
href={app.url}
target="_blank"
rel="noopener noreferrer"
className={`flex-1 flex items-center justify-center gap-2 px-4 py-2 rounded-xl bg-gradient-to-r ${app.color} text-white font-semibold hover:opacity-90 transition-opacity`}
>
<ExternalLink size={16} />
Visit
</a>
{app.githubUrl && (
<a
href={app.githubUrl}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-center px-4 py-2 rounded-xl border border-white/20 text-white hover:bg-white/10 transition-colors"
>
<Github size={16} />
</a>
)}
</div>
</div>
</div>
);
}; };
export default function KSuitePage() { export default function KSuitePage() {
return ( return (
<div className="min-h-screen pt-20"> <div className="min-h-screen pt-20">
{/* Hero Section */} {/* Hero Section */}
<section className="relative py-16 md:py-24 overflow-hidden"> <section className="relative py-16 md:py-24 overflow-hidden">
<div className="container mx-auto px-4 text-center"> <div className="container mx-auto px-4 text-center">
<h1 className="text-5xl md:text-7xl font-bold text-white mb-4 text-shadow-lg"> <h1 className="text-5xl md:text-7xl font-bold text-white mb-4 text-shadow-lg">
K-Suite K-Suite
</h1> </h1>
<p className="text-xl md:text-2xl text-white/80 max-w-3xl mx-auto mb-2"> <p className="text-xl md:text-2xl text-white/80 max-w-3xl mx-auto mb-2">
A cohesive ecosystem of open-source, self-hosted applications A cohesive ecosystem of open-source, self-hosted applications
designed to restore digital sovereignty to the user. designed to restore digital sovereignty to the user.
</p> </p>
<p className="text-base text-white/60 max-w-2xl mx-auto mb-12"> <p className="text-base text-white/60 max-w-2xl mx-auto mb-12">
A &quot;Personal Universe&quot; containing interconnected applications ranging A &quot;Personal Universe&quot; containing interconnected
from media playback to knowledge management. applications ranging from media playback to knowledge management.
</p> </p>
{/* Organism Visualization */} {/* Organism Visualization */}
<KSuiteOrganism /> <KSuiteOrganism />
</div>
</section>
{/* Origin Story Section */}
<section className="py-16">
<div className="container mx-auto px-4">
<div className="max-w-3xl mx-auto">
<div className="p-8 rounded-3xl bg-white/5 backdrop-blur-lg border border-white/10">
<h2 className="text-3xl font-bold text-white mb-6 flex items-center gap-3">
Origin Story
</h2>
<div className="space-y-4 text-white/80 leading-relaxed">
<p>
The concept of K-Suite was born in <span className="text-yellow-400 font-semibold">2017</span>.
As a middle school student, I envisioned a digital environment where every
tool I used was built by my own handsa space customized exactly to my needs.
However, my vision at the time far outpaced my technical abilities.
</p>
<p>
K-Suite is the realization of that long-standing dream. It bridges the gap
between the middle schooler who wanted to build, and the developer who now can.
</p>
</div>
</div>
</div>
</div>
</section>
{/* Engineering Mission Section */}
<section className="py-16">
<div className="container mx-auto px-4">
<div className="max-w-3xl mx-auto">
<div className="p-8 rounded-3xl bg-gradient-to-br from-purple-500/10 to-blue-500/10 backdrop-blur-lg border border-white/10">
<h2 className="text-3xl font-bold text-white mb-6 flex items-center gap-3">
Engineering Mission
</h2>
<div className="space-y-4 text-white/80 leading-relaxed">
<p>
This project represents my <span className="text-yellow-400 font-semibold">Magnum Opus</span>.
It is the most ambitious software engineering undertaking I have attempted to date.
Beyond simply providing privacy and utility, K-Suite serves as a rigorous testing
ground for advanced <span className="text-cyan-400">System Design</span> and{" "}
<span className="text-cyan-400">Software Architecture</span>.
</p>
</div>
{/* Core Goals */}
<div className="mt-8 space-y-6">
<h3 className="text-xl font-semibold text-white">Core Goals</h3>
<div className="p-4 rounded-2xl bg-white/5 border border-white/10">
<h4 className="text-lg font-bold text-amber-400 mb-2">
Architectural Mastery
</h4>
<p className="text-white/70">
To design a distributed system where independent modules (like K-Notes)
function flawlessly on their own but become exponentially more powerful when connected.
</p>
</div>
<div className="p-4 rounded-2xl bg-white/5 border border-white/10">
<h4 className="text-lg font-bold text-emerald-400 mb-2">
Digital Sovereignty
</h4>
<p className="text-white/70">
To create a viable, privacy-first alternative to commercial ecosystems
(Google/Apple), focused entirely on open-source principles and self-hosting.
</p>
</div>
<div className="p-4 rounded-2xl bg-white/5 border border-white/10">
<h4 className="text-lg font-bold text-blue-400 mb-2">
Seamless Integration
</h4>
<p className="text-white/70">
To solve the complex challenge of inter-app communication. In K-Suite,
a photo stored in K-Photos isn&apos;t just a file; it&apos;s an asset that can be
referenced in other apps or attached to an entry in the upcoming K-Mood.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Detailed Cards Section */}
<section className="py-16">
<div className="container mx-auto px-4">
<h2 className="text-3xl font-bold text-white text-center mb-4">
Explore the Suite
</h2>
<p className="text-white/60 text-center mb-12 max-w-xl mx-auto">
Each application is designed to work independently, but together they form
something greater.
</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
{kSuiteApps.map((app) => (
<KSuiteAppCard key={app.id} app={app} />
))}
</div>
</div>
</section>
{/* Coming Soon Section */}
<section className="py-16">
<div className="container mx-auto px-4 text-center">
<div className="max-w-2xl mx-auto p-8 rounded-3xl bg-white/5 backdrop-blur-lg border border-white/10">
<h2 className="text-2xl font-bold text-white mb-4">
More Apps Coming Soon
</h2>
<p className="text-white/70 mb-4">
K-Suite is still growing. The ecosystem will expand with more interconnected
applications including K-Photos, K-Mood, and more.
</p>
<p className="text-sm text-white/50">
Built with Rust, React, and modern web technologies.
</p>
</div>
</div>
</section>
</div> </div>
); </section>
{/* Origin Story Section */}
<section className="py-16">
<div className="container mx-auto px-4">
<div className="max-w-3xl mx-auto">
<div className="p-8 rounded-3xl bg-white/5 backdrop-blur-lg border border-white/10">
<h2 className="text-3xl font-bold text-white mb-6 flex items-center gap-3">
Origin Story
</h2>
<div className="space-y-4 text-white/80 leading-relaxed">
<p>
The concept of K-Suite was born in{" "}
<span className="text-yellow-400 font-semibold">2017</span>.
As a middle school student, I envisioned a digital environment
where every tool I used was built by my own handsa space
customized exactly to my needs. However, my vision at the time
far outpaced my technical abilities.
</p>
<p>
K-Suite is the realization of that long-standing dream. It
bridges the gap between the middle schooler who wanted to
build, and the developer who now can.
</p>
</div>
</div>
</div>
</div>
</section>
{/* Engineering Mission Section */}
<section className="py-16">
<div className="container mx-auto px-4">
<div className="max-w-3xl mx-auto">
<div className="p-8 rounded-3xl bg-gradient-to-br from-purple-500/10 to-blue-500/10 backdrop-blur-lg border border-white/10">
<h2 className="text-3xl font-bold text-white mb-6 flex items-center gap-3">
Engineering Mission
</h2>
<div className="space-y-4 text-white/80 leading-relaxed">
<p>
This project represents my{" "}
<span className="text-yellow-400 font-semibold">
Magnum Opus
</span>
. It is the most ambitious software engineering undertaking I
have attempted to date. Beyond simply providing privacy and
utility, K-Suite serves as a rigorous testing ground for
advanced <span className="text-cyan-400">System Design</span>{" "}
and{" "}
<span className="text-cyan-400">Software Architecture</span>.
</p>
</div>
{/* Core Goals */}
<div className="mt-8 space-y-6">
<h3 className="text-xl font-semibold text-white">Core Goals</h3>
<div className="p-4 rounded-2xl bg-white/5 border border-white/10">
<h4 className="text-lg font-bold text-amber-400 mb-2">
Architectural Mastery
</h4>
<p className="text-white/70">
To design a distributed system where independent modules
(like K-Notes) function flawlessly on their own but become
exponentially more powerful when connected.
</p>
</div>
<div className="p-4 rounded-2xl bg-white/5 border border-white/10">
<h4 className="text-lg font-bold text-emerald-400 mb-2">
Digital Sovereignty
</h4>
<p className="text-white/70">
To create a viable, privacy-first alternative to commercial
ecosystems (Google/Apple), focused entirely on open-source
principles and self-hosting.
</p>
</div>
<div className="p-4 rounded-2xl bg-white/5 border border-white/10">
<h4 className="text-lg font-bold text-blue-400 mb-2">
Seamless Integration
</h4>
<p className="text-white/70">
To solve the complex challenge of inter-app communication.
In K-Suite, a photo stored in K-Photos isn&apos;t just a
file; it&apos;s an asset that can be referenced in other
apps or attached to an entry in the upcoming K-Mood.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Detailed Cards Section */}
<section className="py-16">
<div className="container mx-auto px-4">
<h2 className="text-3xl font-bold text-white text-center mb-4">
Explore the Suite
</h2>
<p className="text-white/60 text-center mb-12 max-w-xl mx-auto">
Each application is designed to work independently, but together
they form something greater.
</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
{kSuiteApps.map((app) => (
<KSuiteAppCard key={app.id} app={app} />
))}
</div>
</div>
</section>
{/* Coming Soon Section */}
<section className="py-16">
<div className="container mx-auto px-4 text-center">
<div className="max-w-2xl mx-auto p-8 rounded-3xl bg-white/5 backdrop-blur-lg border border-white/10">
<h2 className="text-2xl font-bold text-white mb-4">
More Apps Coming Soon
</h2>
<p className="text-white/70 mb-4">
K-Suite is still growing. The ecosystem will expand with more
interconnected applications including K-Photos, K-Mood, and more.
</p>
<p className="text-sm text-white/50">
Built with Rust, React, and modern web technologies.
</p>
</div>
</div>
</section>
</div>
);
} }

View File

@@ -206,7 +206,7 @@ export const projects: Project[] = [
"short_description": "Web app to tune guitar, ukulele and piano.", "short_description": "Web app to tune guitar, ukulele and piano.",
"description": "A web application for tuning musical instruments including guitar, ukulele, and piano. It features a nostalgic Frutiger Aero style and is built as a Progressive Web App (PWA) for use on any device.\n\n**Technical details:**\n- **Frontend:** React PWA", "description": "A web application for tuning musical instruments including guitar, ukulele, and piano. It features a nostalgic Frutiger Aero style and is built as a Progressive Web App (PWA) for use on any device.\n\n**Technical details:**\n- **Frontend:** React PWA",
"category": "Web", "category": "Web",
"github_url": "https://github.com/GKaszewski/aero-tuner", "github_url": "https://github.com/GKaszewski/k-tuner",
"visit_url": "https://tuner.gabrielkaszewski.dev/", "visit_url": "https://tuner.gabrielkaszewski.dev/",
"download_url": null, "download_url": null,
"technologies": [ "technologies": [