Add partners section

This commit is contained in:
2025-11-02 17:26:51 -05:00
parent 602eabc7ba
commit c63b15d5d6
9 changed files with 212 additions and 15 deletions

View File

@ -1,3 +1,5 @@
import { Navbar } from "./components/navbar/navbar";
import { PartnersMarquee } from "./components/partners-marquee/partners-marquee";
import { AuroraText } from "./components/ui/aurora-text";
import { DotPattern } from "./components/ui/dot-pattern";
import { RainbowButton } from "./components/ui/rainbow-button";
@ -5,18 +7,8 @@ import { TextAnimate } from "./components/ui/text-animate";
export function App() {
return (
<div className="h-screen w-screen flex flex-col">
<nav className="flex justify-between items-center p-4 px-6 shadow-md">
<h1 className="text-2xl font-bold">Great Music LLM</h1>
<div className="hidden sm:flex gap-2">
<button className="bg-blue-500 text-white px-4 py-2 rounded">
Button 1
</button>
<button className="bg-green-500 text-white px-4 py-2 rounded">
Button 2
</button>
</div>
</nav>
<div className="h-screen w-screen flex flex-col font-merriweather">
<Navbar />
<main className="flex-1 overflow-auto">
<div
className="h-full bg-cover bg-center
@ -42,9 +34,18 @@ export function App() {
</div>
</div>
</div>
<div className="relative overflow-hidden">
<DotPattern />
Section 2 coming soon...
<div className="relative overflow-hidden py-5 flex flex-col gap-5">
<TextAnimate
animation="blurInUp"
by="character"
as="h3"
className="text-xl font-bold text-center"
>
Our Partners
</TextAnimate>
<PartnersMarquee />
<span></span> {/* Spacer for DotPattern */}
<DotPattern className="-z-10" />
</div>
</main>
</div>

View File

@ -0,0 +1,15 @@
export function Navbar() {
return (
<nav className="flex justify-between items-center p-4 px-6 shadow-md">
<h1 className="text-2xl font-bold font-alex-brush">Great Music LLM</h1>
<div className="hidden sm:flex gap-2">
<button className="bg-blue-500 text-white px-4 py-2 rounded">
Button 1
</button>
<button className="bg-green-500 text-white px-4 py-2 rounded">
Button 2
</button>
</div>
</nav>
);
}

View File

@ -0,0 +1,48 @@
import { Marquee } from "../ui/marquee";
export function PartnersMarquee() {
const partners = [
{
name: "Conductor Orchestra",
logo: "https://t3.ftcdn.net/jpg/05/71/43/76/360_F_571437617_ZNppyF5qpbJn9dYifhjWEQkgjbZNBXP9.jpg",
},
{
name: "Chicago Symphony Orchestra",
logo: "https://upload.wikimedia.org/wikipedia/commons/1/1f/Wiki-CSO_logo2024_stacked-whitebg.png",
},
{
name: "Toronto Symphony Orchestra",
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSfThsC3B2BGCKjnyr_IMiJmp-0jI9I9blZrw&s",
},
{
name: "Los Angeles Chamber Orchestra",
logo: "https://admin.itsnicethat.com/images/TOHFR2DIydoDTaGM6NbfVRFZfJU=/168760/format-webp%7Cwidth-2880/5d947a047fa44cbd2200fd0f.jpg",
},
{
name: "Richmond Symphony Orchestra",
logo: "https://richmondsymphony.org/wp-content/uploads/2021/07/rso-logo-2023.png",
},
];
return (
<div className="relative flex w-full flex-col items-center justify-center overflow-hidden">
<Marquee>
{partners.map((partner) => (
<div
key={partner.name}
className="flex flex-col items-center justify-center p-4 bg-white border-2 border-gray-300 rounded-lg shadow-md"
>
<img
src={partner.logo}
alt={`${partner.name} logo`}
className="max-h-24"
/>
<p>{partner.name}</p>
</div>
))}
</Marquee>
<div className="from-background pointer-events-none absolute inset-y-0 left-0 w-4 bg-linear-to-r"></div>
<div className="from-background pointer-events-none absolute inset-y-0 right-0 w-4 bg-linear-to-l"></div>
</div>
);
}

View File

@ -0,0 +1,74 @@
import type { ComponentPropsWithoutRef } from "react";
import { cn } from "@/lib/utils";
interface MarqueeProps extends ComponentPropsWithoutRef<"div"> {
/**
* Optional CSS class name to apply custom styles
*/
className?: string;
/**
* Whether to reverse the animation direction
* @default false
*/
reverse?: boolean;
/**
* Whether to pause the animation on hover
* @default false
*/
pauseOnHover?: boolean;
/**
* Content to be displayed in the marquee
*/
children: React.ReactNode;
/**
* Whether to animate vertically instead of horizontally
* @default false
*/
vertical?: boolean;
/**
* Number of times to repeat the content
* @default 4
*/
repeat?: number;
}
export function Marquee({
className,
reverse = false,
pauseOnHover = false,
children,
vertical = false,
repeat = 4,
...props
}: MarqueeProps) {
return (
<div
{...props}
className={cn(
"group flex [gap:var(--gap)] overflow-hidden p-2 [--duration:40s] [--gap:1rem]",
{
"flex-row": !vertical,
"flex-col": vertical,
},
className,
)}
>
{Array(repeat)
.fill(0)
.map((_, i) => (
<div
key={i}
className={cn("flex shrink-0 justify-around [gap:var(--gap)]", {
"animate-marquee flex-row": !vertical,
"animate-marquee-vertical flex-col": vertical,
"group-hover:[animation-play-state:paused]": pauseOnHover,
"[animation-direction:reverse]": reverse,
})}
>
{children}
</div>
))}
</div>
);
}

3
src/globals.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
declare module "*.css";
declare module "@fontsource/*" {}
declare module "@fontsource-variable/*" {}

View File

@ -4,6 +4,9 @@
@custom-variant dark (&:is(.dark *));
@theme inline {
--font-alex-brush: "Alex Brush", cursive;
--font-merriweather: "Merriweather Variable", serif;
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
@ -40,42 +43,70 @@
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--animate-aurora: aurora 8s ease-in-out infinite alternate;
@keyframes aurora {
0% {
background-position: 0% 50%;
transform: rotate(-5deg) scale(0.9);
}
25% {
background-position: 50% 100%;
transform: rotate(5deg) scale(1.1);
}
50% {
background-position: 100% 50%;
transform: rotate(-3deg) scale(0.95);
}
75% {
background-position: 50% 0%;
transform: rotate(3deg) scale(1.05);
}
100% {
background-position: 0% 50%;
transform: rotate(-5deg) scale(0.9);
}
}
--animate-rainbow: rainbow var(--speed, 2s) infinite linear;
--color-color-5: var(--color-5);
--color-color-4: var(--color-4);
--color-color-3: var(--color-3);
--color-color-2: var(--color-2);
--color-color-1: var(--color-1);
@keyframes rainbow {
0% {
background-position: 0%;
}
100% {
background-position: 200%;
}
}
--animate-marquee: marquee var(--duration) infinite linear;
--animate-marquee-vertical: marquee-vertical var(--duration) linear infinite;
@keyframes marquee {
from {
transform: translateX(0);
}
to {
transform: translateX(calc(-100% - var(--gap)));
}
}
@keyframes marquee-vertical {
from {
transform: translateY(0);
}
to {
transform: translateY(calc(-100% - var(--gap)));
}
}
}
:root {
@ -161,6 +192,7 @@
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}

View File

@ -2,6 +2,8 @@ import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import { App } from "./app";
import "@fontsource/alex-brush";
import "@fontsource-variable/merriweather";
createRoot(document.getElementById("root")!).render(
<StrictMode>