diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..2ef2d71
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,4 @@
+{
+ "trailingComma": "es5",
+ "tabWidth": 4
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 81d71e2..5477ed8 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,6 @@
My personal portfolio website hosted [here](https://rainnny.club)
## TODO
-- [ ] Mobile Responsiveness
+- [x] Mobile Responsiveness
- [ ] Discord Integration (Status, Activity, etc)
-- [ ] Add Configuration
+- [ ] Add Configuration
\ No newline at end of file
diff --git a/bun.lockb b/bun.lockb
index e8be417..37b4446 100644
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index 24195fe..68feea8 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18",
+ "sharp": "^0.33.5",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7"
},
diff --git a/src/app/(pages)/layout.tsx b/src/app/(pages)/layout.tsx
index f9255c4..f542699 100644
--- a/src/app/(pages)/layout.tsx
+++ b/src/app/(pages)/layout.tsx
@@ -11,33 +11,33 @@ const inter = Inter({ subsets: ["latin"] });
* The metadata for this app.
*/
export const metadata: Metadata = {
- title: "RainnnyCLUB",
- description:
- "My name is Braydon and I am a self-taught software engineer living in Canada.",
+ title: "RainnnyCLUB",
+ description:
+ "My name is Braydon and I am a self-taught software engineer living in Canada.",
};
export const viewport: Viewport = {
- themeColor: "#5555FF",
+ themeColor: "#5555FF",
};
/**
* The primary layout for this app.
*/
const RootLayout = ({
- children,
+ children,
}: Readonly<{
- children: React.ReactNode;
+ children: React.ReactNode;
}>): ReactElement => (
-
-
-
- {children}
-
-
-
+
+
+
+ {children}
+
+
+
);
export default RootLayout;
diff --git a/src/app/(pages)/page.tsx b/src/app/(pages)/page.tsx
index b327b78..0134554 100644
--- a/src/app/(pages)/page.tsx
+++ b/src/app/(pages)/page.tsx
@@ -3,17 +3,17 @@ import Navbar from "@/components/landing/navbar";
import { ReactElement } from "react";
const LandingPage = (): ReactElement => (
-
-
-
-
-
-
+
+
+
+
+
+
);
export default LandingPage;
diff --git a/src/app/globals.css b/src/app/globals.css
index a36413a..ebac54f 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -3,69 +3,70 @@
@tailwind utilities;
@layer base {
- :root {
- --background: 0 0% 100%;
- --foreground: 240 10% 3.9%;
- --card: 0 0% 100%;
- --card-foreground: 240 10% 3.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 240 10% 3.9%;
- --primary: 240 5.9% 10%;
- --primary-foreground: 0 0% 98%;
- --secondary: 240 4.8% 95.9%;
- --secondary-foreground: 240 5.9% 10%;
- --muted: 240 4.8% 95.9%;
- --muted-foreground: 240 3.8% 46.1%;
- --accent: 240 4.8% 95.9%;
- --accent-foreground: 240 5.9% 10%;
- --destructive: 0 72.22% 50.59%;
- --destructive-foreground: 0 0% 98%;
- --border: 240 5.9% 90%;
- --input: 240 5.9% 90%;
- --ring: 240 5% 64.9%;
- --radius: 0.5rem;
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 240 10% 3.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 240 10% 3.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 240 10% 3.9%;
+ --primary: 240 5.9% 10%;
+ --primary-foreground: 0 0% 98%;
+ --secondary: 240 4.8% 95.9%;
+ --secondary-foreground: 240 5.9% 10%;
+ --muted: 240 4.8% 95.9%;
+ --muted-foreground: 240 3.8% 46.1%;
+ --accent: 240 4.8% 95.9%;
+ --accent-foreground: 240 5.9% 10%;
+ --destructive: 0 72.22% 50.59%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 240 5.9% 90%;
+ --input: 240 5.9% 90%;
+ --ring: 240 5% 64.9%;
+ --radius: 0.5rem;
- --chart-1: 12 76% 61%;
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
- }
+ --chart-1: 12 76% 61%;
+ --chart-2: 173 58% 39%;
+ --chart-3: 197 37% 24%;
+ --chart-4: 43 74% 66%;
+ --chart-5: 27 87% 67%;
+ }
- .dark {
- --background: 0 0% 0%;
- --foreground: 0 0% 98%;
- --card: 240 10% 3.9%;
- --card-foreground: 0 0% 98%;
- --popover: 240 10% 3.9%;
- --popover-foreground: 0 0% 98%;
- --primary: 0 0% 98%;
- --primary-foreground: 240 5.9% 10%;
- --secondary: 240 3.7% 15.9%;
- --secondary-foreground: 0 0% 98%;
- --muted: 240 3.7% 15.9%;
- --muted-foreground: 240 5% 64.9%;
- --accent: 240 3.7% 15.9%;
- --accent-foreground: 0 0% 98%;
- --destructive: 0 62.8% 30.6%;
- --destructive-foreground: 0 85.7% 97.3%;
- --border: 240 3.7% 15.9%;
- --input: 240 3.7% 15.9%;
- --ring: 240 4.9% 83.9%;
+ .dark {
+ --background: 0 0% 0%;
+ --foreground: 0 0% 98%;
+ --card: 240 10% 3.9%;
+ --card-foreground: 0 0% 98%;
+ --popover: 240 10% 3.9%;
+ --popover-foreground: 0 0% 98%;
+ --primary: 0 0% 98%;
+ --primary-foreground: 240 5.9% 10%;
+ --secondary: 240 3.7% 15.9%;
+ --secondary-foreground: 0 0% 98%;
+ --muted: 240 3.7% 15.9%;
+ --muted-foreground: 240 5% 64.9%;
+ --accent: 240 3.7% 15.9%;
+ --accent-foreground: 0 0% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 0 85.7% 97.3%;
+ --border: 240 3.7% 15.9%;
+ --input: 240 3.7% 15.9%;
+ --ring: 240 4.9% 83.9%;
- --chart-1: 220 70% 50%;
- --chart-2: 160 60% 45%;
- --chart-3: 30 80% 55%;
- --chart-4: 280 65% 60%;
- --chart-5: 340 75% 55%;
- }
+ --chart-1: 220 70% 50%;
+ --chart-2: 160 60% 45%;
+ --chart-3: 30 80% 55%;
+ --chart-4: 280 65% 60%;
+ --chart-5: 340 75% 55%;
+ }
}
@layer base {
- * {
- @apply border-border;
- }
- body {
- @apply bg-background text-foreground;
- }
+ * {
+ @apply border-border;
+ }
+
+ body {
+ @apply bg-background text-foreground;
+ }
}
diff --git a/src/components/landing/greeting.tsx b/src/components/landing/greeting.tsx
index 4ec0381..9ed7e94 100644
--- a/src/components/landing/greeting.tsx
+++ b/src/components/landing/greeting.tsx
@@ -9,59 +9,59 @@ import { FlipWords } from "@/components/ui/flip-words";
import Navigation from "./navigation";
const Greeting = (): ReactElement => {
- const now: Moment = moment(Date.now());
- return (
-
-
-
-
+ const now: Moment = moment(Date.now());
+ return (
+
+
+
+
-
-
- Hello, I'm
-
- Braydon
-
-
-
-
-
-
+
+
+ Hello, I'm
+
+ Braydon
+
+
+
+
+
+
-
-
+
-
+ ]}
+ />
+
-
-
-
-
- );
+
+
+
+
+ );
};
export default Greeting;
diff --git a/src/components/landing/nav-content/homelab.tsx b/src/components/landing/nav-content/homelab.tsx
index 5256989..9a3eb80 100644
--- a/src/components/landing/nav-content/homelab.tsx
+++ b/src/components/landing/nav-content/homelab.tsx
@@ -1,32 +1,32 @@
import { ReactElement } from "react";
const HomelabContent = (): ReactElement => (
-
-
- Server Rack: 22U, 32" Depth
-
-
- Router: UDM Pro
-
-
- UPS: 1350VA
-
-
-
- Proxmox Node-01:
-
- - Motherboard: Prime B550-PLUS
-
-
- - CPU: Ryzen 5 5600G
-
-
- - RAM: 38GB of DDR4 @ 3200Mhz
-
-
- - Storage: 8TB (x2 4TB, x1 4TB Parity) Unraid Array
-
-
-
+
+
+ Server Rack: 22U, 32" Depth
+
+
+ Router: UDM Pro
+
+
+ UPS: 1350VA
+
+
+
+ Proxmox Node-01:
+
+ - Motherboard: Prime B550-PLUS
+
+
+ - CPU: Ryzen 5 5600G
+
+
+ - RAM: 38GB of DDR4 @ 3200Mhz
+
+
+ - Storage: 8TB (x2 4TB, x1 4TB Parity) Unraid Array
+
+
+
);
export default HomelabContent;
diff --git a/src/components/landing/nav-content/my-work.tsx b/src/components/landing/nav-content/my-work.tsx
index f12b9b5..b333550 100644
--- a/src/components/landing/nav-content/my-work.tsx
+++ b/src/components/landing/nav-content/my-work.tsx
@@ -1,7 +1,6 @@
"use client";
import { MagicCard } from "@/components/ui/magic-card";
-import { cn } from "@/lib/utils";
import moment, { Moment } from "moment";
import { useTheme } from "next-themes";
import { UseThemeProps } from "next-themes/dist/types";
@@ -9,102 +8,122 @@ import Link from "next/link";
import { ReactElement } from "react";
type Project = {
- name: string;
- link?: string | undefined;
- previewContent: ReactElement;
- startDate: Moment;
- endDate?: Moment | undefined;
+ name: string;
+ link?: string | undefined;
+ previewContent: ReactElement;
+ startDate: Moment;
+ endDate?: Moment | undefined;
};
const projects: Project[] = [
- {
- name: "This Website!",
- link: "https://github.com/Rainnny7/rainnny.club",
- previewContent: This website!
,
- startDate: moment([2024, 7, 29]),
- },
- {
- name: "WildNetwork",
- link: "https://discord.gg/WildPrison",
- previewContent: (
-
- WildNetwork is a Minecraft server that contains multiple gamemodes, one
- of which is Prison, which is the most popular. I first joined the server
- as a Developer where I would work behind the scenes to create new
- features, now I'm currently working as a System Administrator.
-
- ),
- startDate: moment([2020, 7, 1]),
- },
- {
- name: "Lucity",
- link: "https://youtube.com/@iamLucid",
- previewContent: (
-
- Lucity was a minigame network for the game Minecraft, and was owned by
- the YouTuber iamLucid. When I worked at Lucity, I was the development
- lead, I focused mainly on infrastructure, databases, and monitoring
- systems. A few things that I have made - a dynamically managed server
- system, proxy rotation via the TCPShield API, and an API that can
- interact with the entire network from a normal Java app.
-
- ),
- startDate: moment([2020, 7, 1]),
- endDate: moment([2022, 10, 30]),
- },
- {
- name: "Rainplex",
- previewContent: (
-
- Rainplex was a remake of the once popular Minecraft server, Mineplex.
- Rainplex initially came to light using the plugin, Skript where it just
- contained a Hub. After some time, the entirety of the network was
- re-coded in the Java programming from the ground up. Rainplex went
- through numerous re-codes over the time it was active, however I have
- since abandoned development due to lack of free time.
-
- ),
- startDate: moment([2018, 8, 1]),
- endDate: moment([2021, 6, 11]),
- },
- {
- name: "Arcane Client",
- link: "https://github.com/ArcaneClientNET",
- previewContent: (
-
- Arcane is the all-in-one Minecraft mod pack. This client was built to be
- similar to LunarClient for portfolio and experience sake. I have since
- abandoned development due to lack of free time.
-
- ),
- startDate: moment([2021, 6, 1]),
- endDate: moment([2021, 10, 1]),
- },
+ {
+ name: "This Website!",
+ link: "https://github.com/Rainnny7/rainnny.club",
+ previewContent: This website!
,
+ startDate: moment([2024, 7, 29]),
+ },
+ {
+ name: "WildNetwork",
+ link: "https://discord.gg/WildPrison",
+ previewContent: (
+
+ WildNetwork is a Minecraft server that contains multiple
+ gamemodes, one of which is Prison, which is the most popular. I
+ first joined the server as a Developer where I would work behind
+ the scenes to create new features, now I'm currently
+ working as a System Administrator.
+
+ ),
+ startDate: moment([2020, 7, 1]),
+ },
+ {
+ name: "Bonfire",
+ link: "https://bonfire.wtf",
+ previewContent: (
+
+ Bonfire is a platform similar to Discord that a friend and I are
+ working on together in our free time. Bonfire is perfect for
+ connecting with friends or building a global community.
+ Personalize your space to chat, and hang out.
+
+ ),
+ startDate: moment([2024, 3, 30]),
+ },
+ {
+ name: "Lucity",
+ link: "https://youtube.com/@iamLucid",
+ previewContent: (
+
+ Lucity was a minigame network for the game Minecraft, and was
+ owned by the YouTuber iamLucid. When I worked at Lucity, I was
+ the development lead, I focused mainly on infrastructure,
+ databases, and monitoring systems. A few things that I have made
+ - a dynamically managed server system, proxy rotation via the
+ TCPShield API, and an API that can interact with the entire
+ network from a normal Java app.
+
+ ),
+ startDate: moment([2020, 7, 1]),
+ endDate: moment([2022, 10, 30]),
+ },
+ {
+ name: "Rainplex",
+ previewContent: (
+
+ Rainplex was a remake of the once popular Minecraft server,
+ Mineplex. Rainplex initially came to light using the plugin,
+ Skript where it just contained a Hub. After some time, the
+ entirety of the network was re-coded in the Java programming
+ from the ground up. Rainplex went through numerous re-codes over
+ the time it was active, however I have since abandoned
+ development due to lack of free time.
+
+ ),
+ startDate: moment([2018, 8, 1]),
+ endDate: moment([2021, 6, 11]),
+ },
+ {
+ name: "Arcane Client",
+ link: "https://github.com/ArcaneClientNET",
+ previewContent: (
+
+ Arcane is the all-in-one Minecraft mod pack. This client was
+ built to be similar to LunarClient for portfolio and experience
+ sake. I have since abandoned development due to lack of free
+ time.
+
+ ),
+ startDate: moment([2021, 6, 1]),
+ endDate: moment([2021, 10, 1]),
+ },
];
const MyWork = (): ReactElement => {
- const { theme }: UseThemeProps = useTheme();
- return (
-
- {projects.map((project, index) => (
-
-
-
- {project.name}
-
+ const { theme }: UseThemeProps = useTheme();
+ return (
+
+ {projects.map((project, index) => (
+
+
+
+ {project.name}
+
- {/* Years Active */}
-
- {project.startDate.format("MMM YYYY")}
- {project.endDate && ` - ${project.endDate.format("MMM YYYY")}`}
-
-
-
- ))}
-
- );
+ {/* Years Active */}
+
+ {project.startDate.format("MMM YYYY")}
+ {project.endDate &&
+ ` - ${project.endDate.format("MMM YYYY")}`}
+
+
+
+ ))}
+
+ );
};
export default MyWork;
diff --git a/src/components/landing/nav-content/skills.tsx b/src/components/landing/nav-content/skills.tsx
index 0aff409..99b9f86 100644
--- a/src/components/landing/nav-content/skills.tsx
+++ b/src/components/landing/nav-content/skills.tsx
@@ -1,145 +1,145 @@
import Image from "next/image";
import Link from "next/link";
import { ReactElement } from "react";
-import {
- Tooltip,
- TooltipContent,
- TooltipTrigger,
-} from "@/components/ui/tooltip";
import SimpleTooltip from "@/components/ui/simple-tooltip";
type Skill = {
- name: string;
- icon: string;
- link: string;
+ name: string;
+ icon: string;
+ link: string;
};
const skillset: Skill[] = [
- // Languages
- {
- name: "Java",
- icon: "https://img.icons8.com/color/2x/java-coffee-cup-logo.png",
- link: "https://www.java.com",
- },
- {
- name: "JavaScript",
- icon: "https://img.icons8.com/fluent/2x/javascript.png",
- link: "https://developer.mozilla.org/en-US/docs/Web/JavaScript",
- },
- {
- name: "CSS",
- icon: "https://img.icons8.com/fluent/2x/css3.png",
- link: "https://www.w3schools.com/css",
- },
+ // Languages
+ {
+ name: "Java",
+ icon: "https://img.icons8.com/color/2x/java-coffee-cup-logo.png",
+ link: "https://www.java.com",
+ },
+ {
+ name: "JavaScript",
+ icon: "https://img.icons8.com/fluent/2x/javascript.png",
+ link: "https://developer.mozilla.org/en-US/docs/Web/JavaScript",
+ },
+ {
+ name: "CSS",
+ icon: "https://img.icons8.com/fluent/2x/css3.png",
+ link: "https://www.w3schools.com/css",
+ },
- // Operating Systems
- {
- name: "Linux",
- icon: "https://img.icons8.com/color/2x/linux.png",
- link: "https://www.linux.org",
- },
- {
- name: "Bash",
- icon: "https://img.icons8.com/color/2x/bash.png",
- link: "https://www.gnu.org/software/bash",
- },
+ // Operating Systems
+ {
+ name: "Linux",
+ icon: "https://img.icons8.com/color/2x/linux.png",
+ link: "https://www.linux.org",
+ },
+ {
+ name: "Bash",
+ icon: "https://img.icons8.com/color/2x/bash.png",
+ link: "https://www.gnu.org/software/bash",
+ },
- // Databases
- {
- name: "MariaDB",
- icon: "https://img.icons8.com/fluent/2x/maria-db.png",
- link: "https://mariadb.org",
- },
- {
- name: "MongoDB",
- icon: "https://img.icons8.com/color/2x/mongodb.png",
- link: "https://www.mongodb.com",
- },
- {
- name: "Redis",
- icon: "https://img.icons8.com/color/2x/redis.png",
- link: "https://redis.io",
- },
+ // Databases
+ {
+ name: "MariaDB",
+ icon: "https://img.icons8.com/fluent/2x/maria-db.png",
+ link: "https://mariadb.org",
+ },
+ {
+ name: "MongoDB",
+ icon: "https://img.icons8.com/color/2x/mongodb.png",
+ link: "https://www.mongodb.com",
+ },
+ {
+ name: "Redis",
+ icon: "https://img.icons8.com/color/2x/redis.png",
+ link: "https://redis.io",
+ },
- // Software
- {
- name: "Git",
- icon: "https://img.icons8.com/color/2x/git.png",
- link: "https://git-scm.com",
- },
- {
- name: "Docker",
- icon: "https://img.icons8.com/fluent/2x/docker.png",
- link: "https://www.docker.com",
- },
- {
- name: "Jenkins",
- icon: "https://img.icons8.com/color/2x/jenkins.png",
- link: "https://www.jenkins.io",
- },
- {
- name: "Figma",
- icon: "https://img.icons8.com/fluent/2x/figma.png",
- link: "https://www.figma.com",
- },
- {
- name: "Postman",
- icon: "https://img.icons8.com/dusk/2x/postman-api.png",
- link: "https://www.postman.com",
- },
+ // Software
+ {
+ name: "Git",
+ icon: "https://img.icons8.com/color/2x/git.png",
+ link: "https://git-scm.com",
+ },
+ {
+ name: "Docker",
+ icon: "https://img.icons8.com/fluent/2x/docker.png",
+ link: "https://www.docker.com",
+ },
+ {
+ name: "Jenkins",
+ icon: "https://img.icons8.com/color/2x/jenkins.png",
+ link: "https://www.jenkins.io",
+ },
+ {
+ name: "Figma",
+ icon: "https://img.icons8.com/fluent/2x/figma.png",
+ link: "https://www.figma.com",
+ },
+ {
+ name: "Postman",
+ icon: "https://img.icons8.com/dusk/2x/postman-api.png",
+ link: "https://www.postman.com",
+ },
- // Frameworks & Libraries
- {
- name: "Maven",
- icon: "/maven.png",
- link: "https://maven.apache.org",
- },
- {
- name: "NPM",
- icon: "https://img.icons8.com/color/2x/npm.png",
- link: "https://www.npmjs.com",
- },
- {
- name: "React",
- icon: "https://img.icons8.com/dusk/2x/react.png",
- link: "https://reactjs.org/",
- },
- {
- name: "NextJS",
- icon: "https://img.icons8.com/color/2x/nextjs.png",
- link: "https://nextjs.org/",
- },
- {
- name: "TailwindCSS",
- icon: "https://img.icons8.com/color/2x/tailwindcss.png",
- link: "https://tailwindcss.com",
- },
- {
- name: "Redux",
- icon: "https://img.icons8.com/color/2x/redux.png",
- link: "https://redux.js.org",
- },
- {
- name: "Nginx",
- icon: "https://img.icons8.com/color/2x/nginx.png",
- link: "https://www.nginx.com",
- },
+ // Frameworks & Libraries
+ {
+ name: "Maven",
+ icon: "/maven.png",
+ link: "https://maven.apache.org",
+ },
+ {
+ name: "NPM",
+ icon: "https://img.icons8.com/color/2x/npm.png",
+ link: "https://www.npmjs.com",
+ },
+ {
+ name: "React",
+ icon: "https://img.icons8.com/dusk/2x/react.png",
+ link: "https://reactjs.org/",
+ },
+ {
+ name: "NextJS",
+ icon: "https://img.icons8.com/color/2x/nextjs.png",
+ link: "https://nextjs.org/",
+ },
+ {
+ name: "TailwindCSS",
+ icon: "https://img.icons8.com/color/2x/tailwindcss.png",
+ link: "https://tailwindcss.com",
+ },
+ {
+ name: "Redux",
+ icon: "https://img.icons8.com/color/2x/redux.png",
+ link: "https://redux.js.org",
+ },
+ {
+ name: "Nginx",
+ icon: "https://img.icons8.com/color/2x/nginx.png",
+ link: "https://www.nginx.com",
+ },
];
const Skills = (): ReactElement => (
-
- {skillset.map((skill, index) => (
-
-
-
-
-
- ))}
-
+
+ {skillset.map((skill, index) => (
+
+
+
+
+
+ ))}
+
);
export default Skills;
diff --git a/src/components/landing/navbar.tsx b/src/components/landing/navbar.tsx
index fa020b8..2abb658 100644
--- a/src/components/landing/navbar.tsx
+++ b/src/components/landing/navbar.tsx
@@ -2,114 +2,115 @@ import Image from "next/image";
import Link from "next/link";
import { ReactElement } from "react";
import {
- NavigationMenu,
- NavigationMenuContent,
- NavigationMenuIndicator,
- NavigationMenuItem,
- NavigationMenuLink,
- NavigationMenuList,
- NavigationMenuTrigger,
- NavigationMenuViewport,
+ NavigationMenu,
+ NavigationMenuContent,
+ NavigationMenuItem,
+ NavigationMenuLink,
+ NavigationMenuList,
+ NavigationMenuTrigger,
+ navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";
-import { navigationMenuTriggerStyle } from "@/components/ui/navigation-menu";
import { HeartIcon } from "@heroicons/react/24/solid";
import { cn } from "@/lib/utils";
import ThemeSwitcher from "./theme-switcher";
import { Button } from "@/components/ui/button";
-import { BookOpenIcon } from "@heroicons/react/24/outline";
-import { SignalIcon } from "@heroicons/react/24/outline";
+import {
+ BookOpenIcon,
+ CodeBracketIcon,
+ SignalIcon,
+} from "@heroicons/react/24/outline";
import BlurFade from "@/components/ui/blur-fade";
-import { CodeBracketIcon } from "@heroicons/react/24/outline";
const Navbar = (): ReactElement => (
-
-
-
-
-
-
+
+
+
+
+
+
+
);
const Branding = (): ReactElement => (
-
-
- RainnnyCLUB
-
+
+
+ RainnnyCLUB
+
);
const Links = (): ReactElement => (
-
-
- {/* Useful Links */}
-
- Useful Links
-
-
-
-
-
-
+
+
+ {/* Useful Links */}
+
+ Useful Links
+
+
+
+
+
+
- {/* Donate */}
-
-
-
- Buy me a Coffee
-
-
-
-
-
- {/* Theme Switcher */}
-
-
-
-
-
+ {/* Donate */}
+
+
+
+ Buy me a Coffee
+ Donate
+
+
+
+
+
+
);
const UsefulLinksContent = (): ReactElement => (
-
- {/* Git */}
-
-
-
- Gitea
-
-
+
+ {/* Git */}
+
+
+
+ Gitea
+
+
- {/* Wiki */}
-
-
-
- Wiki
-
-
+ {/* Wiki */}
+
+
+
+ Wiki
+
+
- {/* Status Page */}
-
-
-
- Service Status
-
-
-
+ {/* Status Page */}
+
+
+
+ Service Status
+
+
+
);
export default Navbar;
diff --git a/src/components/landing/navigation.tsx b/src/components/landing/navigation.tsx
index c45c006..9d6f339 100644
--- a/src/components/landing/navigation.tsx
+++ b/src/components/landing/navigation.tsx
@@ -2,9 +2,11 @@
import { ReactElement, useState } from "react";
import { Button } from "@/components/ui/button";
-import { BriefcaseIcon } from "@heroicons/react/24/outline";
-import { WrenchIcon } from "@heroicons/react/24/outline";
-import { ServerStackIcon } from "@heroicons/react/24/outline";
+import {
+ BriefcaseIcon,
+ ServerStackIcon,
+ WrenchIcon,
+} from "@heroicons/react/24/outline";
import { cn } from "@/lib/utils";
import BlurFade from "@/components/ui/blur-fade";
import HomelabContent from "./nav-content/homelab";
@@ -12,64 +14,66 @@ import Skills from "./nav-content/skills";
import MyWork from "./nav-content/my-work";
type Item = {
- name: string;
- icon: ReactElement;
- content: ReactElement;
+ name: string;
+ icon: ReactElement;
+ content: ReactElement;
};
const items: Item[] = [
- {
- name: "My Work",
- icon: ,
- content: ,
- },
- {
- name: "Skills",
- icon: ,
- content: ,
- },
- {
- name: "Homelab",
- icon: ,
- content: ,
- },
+ {
+ name: "My Work",
+ icon: ,
+ content: ,
+ },
+ {
+ name: "Skills",
+ icon: ,
+ content: ,
+ },
+ {
+ name: "Homelab",
+ icon: ,
+ content: ,
+ },
];
const Navigation = (): ReactElement => {
- const [selected, setSelected] = useState- (undefined);
- return (
-
- {/* Selection Buttons */}
-
- {items.map((item, index) => {
- const active: boolean = selected === item;
- return (
-
-
- active ? setSelected(undefined) : setSelected(item)
- }
- >
- {item.icon}
- {item.name}
-
-
- );
- })}
-
+ const [selected, setSelected] = useState
- (undefined);
+ return (
+
+ {/* Selection Buttons */}
+
+ {items.map((item, index) => {
+ const active: boolean = selected === item;
+ return (
+
+
+ active
+ ? setSelected(undefined)
+ : setSelected(item)
+ }
+ >
+ {item.icon}
+ {item.name}
+
+
+ );
+ })}
+
- {/* Selected Content */}
- {selected && (
-
- {selected.content}
-
- )}
-
- );
+ {/* Selected Content */}
+ {selected && (
+
+ {selected.content}
+
+ )}
+
+ );
};
export default Navigation;
diff --git a/src/components/landing/theme-switcher.tsx b/src/components/landing/theme-switcher.tsx
index 73b626d..cfed50e 100644
--- a/src/components/landing/theme-switcher.tsx
+++ b/src/components/landing/theme-switcher.tsx
@@ -8,31 +8,31 @@ import { motion } from "framer-motion";
import { UseThemeProps } from "next-themes/dist/types";
const ThemeSwitcher = (): ReactElement => {
- const { theme, setTheme }: UseThemeProps = useTheme();
- const isLight = theme === "light";
- return (
- setTheme(isLight ? "dark" : "light")}
- >
-
-
-
-
-
-
-
- );
+ const { theme, setTheme }: UseThemeProps = useTheme();
+ const isLight = theme === "light";
+ return (
+ setTheme(isLight ? "dark" : "light")}
+ >
+
+
+
+
+
+
+
+ );
};
export default ThemeSwitcher;
diff --git a/src/components/theme-provider.tsx b/src/components/theme-provider.tsx
index c527cde..6b5fce1 100644
--- a/src/components/theme-provider.tsx
+++ b/src/components/theme-provider.tsx
@@ -5,5 +5,5 @@ import { ThemeProvider as NextThemesProvider } from "next-themes";
import { type ThemeProviderProps } from "next-themes/dist/types";
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
- return {children} ;
+ return {children} ;
}
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 0ba4277..cd7d5b9 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -1,56 +1,57 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { cva, type VariantProps } from "class-variance-authority"
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const buttonVariants = cva(
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
- {
- variants: {
- variant: {
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
- destructive:
- "bg-destructive text-destructive-foreground hover:bg-destructive/90",
- outline:
- "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
- secondary:
- "bg-secondary text-secondary-foreground hover:bg-secondary/80",
- ghost: "hover:bg-accent hover:text-accent-foreground",
- link: "text-primary underline-offset-4 hover:underline",
- },
- size: {
- default: "h-10 px-4 py-2",
- sm: "h-9 rounded-md px-3",
- lg: "h-11 rounded-md px-8",
- icon: "h-10 w-10",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- }
-)
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
+ {
+ variants: {
+ variant: {
+ default:
+ "bg-primary text-primary-foreground hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
+ outline:
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
+ secondary:
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-10 px-4 py-2",
+ sm: "h-9 rounded-md px-3",
+ lg: "h-11 rounded-md px-8",
+ icon: "h-10 w-10",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+);
export interface ButtonProps
- extends React.ButtonHTMLAttributes,
- VariantProps {
- asChild?: boolean
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean;
}
const Button = React.forwardRef(
- ({ className, variant, size, asChild = false, ...props }, ref) => {
- const Comp = asChild ? Slot : "button"
- return (
-
- )
- }
-)
-Button.displayName = "Button"
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button";
+ return (
+
+ );
+ }
+);
+Button.displayName = "Button";
-export { Button, buttonVariants }
+export { Button, buttonVariants };
diff --git a/src/components/ui/flip-words.tsx b/src/components/ui/flip-words.tsx
index ec3fe0a..c974ebd 100644
--- a/src/components/ui/flip-words.tsx
+++ b/src/components/ui/flip-words.tsx
@@ -1,99 +1,107 @@
"use client";
-import React, { useCallback, useEffect, useRef, useState } from "react";
-import { AnimatePresence, motion, LayoutGroup } from "framer-motion";
+import React, { useCallback, useEffect, useState } from "react";
+import { AnimatePresence, motion } from "framer-motion";
import { cn } from "@/lib/utils";
export const FlipWords = ({
- words,
- duration = 3000,
- className,
+ words,
+ duration = 3000,
+ className,
}: {
- words: string[];
- duration?: number;
- className?: string;
+ words: string[];
+ duration?: number;
+ className?: string;
}) => {
- const [currentWord, setCurrentWord] = useState(words[0]);
- const [isAnimating, setIsAnimating] = useState(false);
+ const [currentWord, setCurrentWord] = useState(words[0]);
+ const [isAnimating, setIsAnimating] = useState(false);
- // thanks for the fix Julian - https://github.com/Julian-AT
- const startAnimation = useCallback(() => {
- const word = words[words.indexOf(currentWord) + 1] || words[0];
- setCurrentWord(word);
- setIsAnimating(true);
- }, [currentWord, words]);
+ // thanks for the fix Julian - https://github.com/Julian-AT
+ const startAnimation = useCallback(() => {
+ const word = words[words.indexOf(currentWord) + 1] || words[0];
+ setCurrentWord(word);
+ setIsAnimating(true);
+ }, [currentWord, words]);
- useEffect(() => {
- if (!isAnimating)
- setTimeout(() => {
- startAnimation();
- }, duration);
- }, [isAnimating, duration, startAnimation]);
+ useEffect(() => {
+ if (!isAnimating)
+ setTimeout(() => {
+ startAnimation();
+ }, duration);
+ }, [isAnimating, duration, startAnimation]);
- return (
- {
- setIsAnimating(false);
- }}
- >
-
- {/* edit suggested by Sajal: https://x.com/DewanganSajal */}
- {currentWord.split(" ").map((word, wordIndex) => (
-
- {word.split("").map((letter, letterIndex) => (
-
- {letter}
-
- ))}
-
-
- ))}
-
-
- );
+ return (
+ {
+ setIsAnimating(false);
+ }}
+ >
+
+ {/* edit suggested by Sajal: https://x.com/DewanganSajal */}
+ {currentWord.split(" ").map((word, wordIndex) => (
+
+ {word.split("").map((letter, letterIndex) => (
+
+ {letter}
+
+ ))}
+
+
+ ))}
+
+
+ );
};
diff --git a/src/components/ui/magic-card.tsx b/src/components/ui/magic-card.tsx
index 4177af6..1651c77 100644
--- a/src/components/ui/magic-card.tsx
+++ b/src/components/ui/magic-card.tsx
@@ -6,59 +6,59 @@ import { motion, useMotionTemplate, useMotionValue } from "framer-motion";
import { cn } from "@/lib/utils";
export interface MagicCardProps extends React.HTMLAttributes {
- gradientSize?: number;
- gradientColor?: string;
- gradientOpacity?: number;
+ gradientSize?: number;
+ gradientColor?: string;
+ gradientOpacity?: number;
}
export function MagicCard({
- children,
- className,
- gradientSize = 200,
- gradientColor = "#262626",
- gradientOpacity = 0.8,
+ children,
+ className,
+ gradientSize = 200,
+ gradientColor = "#262626",
+ gradientOpacity = 0.8,
}: MagicCardProps) {
- const mouseX = useMotionValue(-gradientSize);
- const mouseY = useMotionValue(-gradientSize);
+ const mouseX = useMotionValue(-gradientSize);
+ const mouseY = useMotionValue(-gradientSize);
- const handleMouseMove = useCallback(
- (e: React.MouseEvent) => {
- const { left, top } = e.currentTarget.getBoundingClientRect();
- mouseX.set(e.clientX - left);
- mouseY.set(e.clientY - top);
- },
- [mouseX, mouseY],
- );
+ const handleMouseMove = useCallback(
+ (e: React.MouseEvent) => {
+ const { left, top } = e.currentTarget.getBoundingClientRect();
+ mouseX.set(e.clientX - left);
+ mouseY.set(e.clientY - top);
+ },
+ [mouseX, mouseY]
+ );
- const handleMouseLeave = useCallback(() => {
- mouseX.set(-gradientSize);
- mouseY.set(-gradientSize);
- }, [mouseX, mouseY, gradientSize]);
+ const handleMouseLeave = useCallback(() => {
+ mouseX.set(-gradientSize);
+ mouseY.set(-gradientSize);
+ }, [mouseX, mouseY, gradientSize]);
- useEffect(() => {
- mouseX.set(-gradientSize);
- mouseY.set(-gradientSize);
- }, [mouseX, mouseY, gradientSize]);
+ useEffect(() => {
+ mouseX.set(-gradientSize);
+ mouseY.set(-gradientSize);
+ }, [mouseX, mouseY, gradientSize]);
- return (
-
-
{children}
-
+ {children}
+
-
- );
+ opacity: gradientOpacity,
+ }}
+ />
+
+ );
}
diff --git a/src/components/ui/navigation-menu.tsx b/src/components/ui/navigation-menu.tsx
index ede85e0..7b792b6 100644
--- a/src/components/ui/navigation-menu.tsx
+++ b/src/components/ui/navigation-menu.tsx
@@ -6,123 +6,123 @@ import { ChevronDown } from "lucide-react";
import { cn } from "@/lib/utils";
const NavigationMenu = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, children, ...props }, ref) => (
-
- {children}
-
-
+
+ {children}
+
+
));
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
const NavigationMenuList = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
+
));
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
const NavigationMenuItem = NavigationMenuPrimitive.Item;
const navigationMenuTriggerStyle = cva(
- "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium cursor-default transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50",
+ "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium cursor-default transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
);
const NavigationMenuTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, children, ...props }, ref) => (
-
- {children}{" "}
-
-
+
+ {children}{" "}
+
+
));
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
const NavigationMenuContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
+
));
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
const NavigationMenuLink = NavigationMenuPrimitive.Link;
const NavigationMenuViewport = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-
-
+
+
+
));
NavigationMenuViewport.displayName =
- NavigationMenuPrimitive.Viewport.displayName;
+ NavigationMenuPrimitive.Viewport.displayName;
const NavigationMenuIndicator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
-
-
+
+
+
));
NavigationMenuIndicator.displayName =
- NavigationMenuPrimitive.Indicator.displayName;
+ NavigationMenuPrimitive.Indicator.displayName;
export {
- navigationMenuTriggerStyle,
- NavigationMenu,
- NavigationMenuList,
- NavigationMenuItem,
- NavigationMenuContent,
- NavigationMenuTrigger,
- NavigationMenuLink,
- NavigationMenuIndicator,
- NavigationMenuViewport,
+ navigationMenuTriggerStyle,
+ NavigationMenu,
+ NavigationMenuList,
+ NavigationMenuItem,
+ NavigationMenuContent,
+ NavigationMenuTrigger,
+ NavigationMenuLink,
+ NavigationMenuIndicator,
+ NavigationMenuViewport,
};
diff --git a/src/components/ui/simple-tooltip.tsx b/src/components/ui/simple-tooltip.tsx
index ce2be2e..5e0b07b 100644
--- a/src/components/ui/simple-tooltip.tsx
+++ b/src/components/ui/simple-tooltip.tsx
@@ -1,8 +1,8 @@
import { ReactElement, ReactNode } from "react";
import {
- Tooltip,
- TooltipContent,
- TooltipTrigger,
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
} from "@/components/ui/tooltip";
import { SIDE_OPTIONS } from "@radix-ui/react-popper";
@@ -10,20 +10,20 @@ import { SIDE_OPTIONS } from "@radix-ui/react-popper";
* The props for a simple tooltip.
*/
type SimpleTooltipProps = {
- /**
- * The content to display in the tooltip.
- */
- content: string | ReactElement;
+ /**
+ * The content to display in the tooltip.
+ */
+ content: string | ReactElement;
- /**
- * The side to display the tooltip on.
- */
- side?: (typeof SIDE_OPTIONS)[number];
+ /**
+ * The side to display the tooltip on.
+ */
+ side?: (typeof SIDE_OPTIONS)[number];
- /**
- * The children to render in this tooltip.
- */
- children: ReactNode;
+ /**
+ * The children to render in this tooltip.
+ */
+ children: ReactNode;
};
/**
@@ -33,13 +33,13 @@ type SimpleTooltipProps = {
* @return the tooltip jsx
*/
const SimpleTooltip = ({
- content,
- side,
- children,
+ content,
+ side,
+ children,
}: SimpleTooltipProps): ReactElement => (
-
- {children}
- {content}
-
+
+ {children}
+ {content}
+
);
export default SimpleTooltip;
diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx
index 30fc44d..0990b90 100644
--- a/src/components/ui/tooltip.tsx
+++ b/src/components/ui/tooltip.tsx
@@ -1,30 +1,30 @@
-"use client"
+"use client";
-import * as React from "react"
-import * as TooltipPrimitive from "@radix-ui/react-tooltip"
+import * as React from "react";
+import * as TooltipPrimitive from "@radix-ui/react-tooltip";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
-const TooltipProvider = TooltipPrimitive.Provider
+const TooltipProvider = TooltipPrimitive.Provider;
-const Tooltip = TooltipPrimitive.Root
+const Tooltip = TooltipPrimitive.Root;
-const TooltipTrigger = TooltipPrimitive.Trigger
+const TooltipTrigger = TooltipPrimitive.Trigger;
const TooltipContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
>(({ className, sideOffset = 4, ...props }, ref) => (
-
-))
-TooltipContent.displayName = TooltipPrimitive.Content.displayName
+
+));
+TooltipContent.displayName = TooltipPrimitive.Content.displayName;
-export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
+export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index d084cca..e644794 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -1,6 +1,6 @@
-import { type ClassValue, clsx } from "clsx"
-import { twMerge } from "tailwind-merge"
+import { type ClassValue, clsx } from "clsx";
+import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs))
+ return twMerge(clsx(inputs));
}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 84287e8..e7d28ca 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -1,80 +1,83 @@
-import type { Config } from "tailwindcss"
+import type {Config} from "tailwindcss"
+
+const defaultTheme = require('tailwindcss/defaultTheme')
const config = {
- darkMode: ["class"],
- content: [
- './pages/**/*.{ts,tsx}',
- './components/**/*.{ts,tsx}',
- './app/**/*.{ts,tsx}',
- './src/**/*.{ts,tsx}',
- ],
- prefix: "",
- theme: {
- container: {
- center: true,
- padding: "2rem",
- screens: {
- "2xl": "1400px",
- },
+ darkMode: ["class"],
+ content: [
+ "./src/**/*.{ts,tsx}",
+ ],
+ prefix: "",
+ theme: {
+ screens: {
+ 'xs': '475px',
+ ...defaultTheme.screens,
+ },
+ container: {
+ center: true,
+ padding: "2rem",
+ screens: {
+ "2xl": "1400px",
+ },
+ },
+ extend: {
+ colors: {
+ border: "hsl(var(--border))",
+ input: "hsl(var(--input))",
+ ring: "hsl(var(--ring))",
+ background: "hsl(var(--background))",
+ foreground: "hsl(var(--foreground))",
+ primary: {
+ DEFAULT: "hsl(var(--primary))",
+ foreground: "hsl(var(--primary-foreground))",
+ },
+ secondary: {
+ DEFAULT: "hsl(var(--secondary))",
+ foreground: "hsl(var(--secondary-foreground))",
+ },
+ destructive: {
+ DEFAULT: "hsl(var(--destructive))",
+ foreground: "hsl(var(--destructive-foreground))",
+ },
+ muted: {
+ DEFAULT: "hsl(var(--muted))",
+ foreground: "hsl(var(--muted-foreground))",
+ },
+ accent: {
+ DEFAULT: "hsl(var(--accent))",
+ foreground: "hsl(var(--accent-foreground))",
+ },
+ popover: {
+ DEFAULT: "hsl(var(--popover))",
+ foreground: "hsl(var(--popover-foreground))",
+ },
+ card: {
+ DEFAULT: "hsl(var(--card))",
+ foreground: "hsl(var(--card-foreground))",
+ },
+ },
+ borderRadius: {
+ lg: "var(--radius)",
+ md: "calc(var(--radius) - 2px)",
+ sm: "calc(var(--radius) - 4px)",
+ },
+ keyframes: {
+ "accordion-down": {
+ from: {height: "0"},
+ to: {height: "var(--radix-accordion-content-height)"},
+ },
+ "accordion-up": {
+ from: {height: "var(--radix-accordion-content-height)"},
+ to: {height: "0"},
+ },
+ },
+ animation: {
+ "accordion-down": "accordion-down 0.2s ease-out",
+ "accordion-up": "accordion-up 0.2s ease-out",
+ },
+ },
},
- extend: {
- colors: {
- border: "hsl(var(--border))",
- input: "hsl(var(--input))",
- ring: "hsl(var(--ring))",
- background: "hsl(var(--background))",
- foreground: "hsl(var(--foreground))",
- primary: {
- DEFAULT: "hsl(var(--primary))",
- foreground: "hsl(var(--primary-foreground))",
- },
- secondary: {
- DEFAULT: "hsl(var(--secondary))",
- foreground: "hsl(var(--secondary-foreground))",
- },
- destructive: {
- DEFAULT: "hsl(var(--destructive))",
- foreground: "hsl(var(--destructive-foreground))",
- },
- muted: {
- DEFAULT: "hsl(var(--muted))",
- foreground: "hsl(var(--muted-foreground))",
- },
- accent: {
- DEFAULT: "hsl(var(--accent))",
- foreground: "hsl(var(--accent-foreground))",
- },
- popover: {
- DEFAULT: "hsl(var(--popover))",
- foreground: "hsl(var(--popover-foreground))",
- },
- card: {
- DEFAULT: "hsl(var(--card))",
- foreground: "hsl(var(--card-foreground))",
- },
- },
- borderRadius: {
- lg: "var(--radius)",
- md: "calc(var(--radius) - 2px)",
- sm: "calc(var(--radius) - 4px)",
- },
- keyframes: {
- "accordion-down": {
- from: { height: "0" },
- to: { height: "var(--radix-accordion-content-height)" },
- },
- "accordion-up": {
- from: { height: "var(--radix-accordion-content-height)" },
- to: { height: "0" },
- },
- },
- animation: {
- "accordion-down": "accordion-down 0.2s ease-out",
- "accordion-up": "accordion-up 0.2s ease-out",
- },
- },
- },
- plugins: [require("tailwindcss-animate")],
+ plugins: [require("tailwindcss-animate")],
} satisfies Config
export default config
\ No newline at end of file