diff --git a/packages/app/src/app/globals.css b/packages/app/src/app/globals.css index 01b78fe8..64bdd538 100644 --- a/packages/app/src/app/globals.css +++ b/packages/app/src/app/globals.css @@ -510,3 +510,33 @@ animation: star-glow 2s ease-in-out infinite; pointer-events: none; } + +/* Trusted-by logo strip: infinite horizontal marquee. + The strip renders the logo set twice; translating the inner row by -50% + slides the first copy off-screen exactly as the second copy moves into + its place, producing a seamless loop. Each set carries pr-5 so the + trailing gap is baked into the 50% math. */ +@keyframes marquee { + from { + transform: translateX(0); + } + to { + transform: translateX(-50%); + } +} + +.animate-marquee { + animation: marquee 50s linear infinite; + will-change: transform; +} + +.animate-marquee:hover, +.animate-marquee:focus-within { + animation-play-state: paused; +} + +@media (prefers-reduced-motion: reduce) { + .animate-marquee { + animation: none; + } +} diff --git a/packages/app/src/components/intro-section.tsx b/packages/app/src/components/intro-section.tsx index 2c8f8e37..6450f2da 100644 --- a/packages/app/src/components/intro-section.tsx +++ b/packages/app/src/components/intro-section.tsx @@ -1,5 +1,3 @@ -import { Quote } from 'lucide-react'; - import { Card } from '@/components/ui/card'; import { MinecraftSplash } from '@/components/minecraft/minecraft-splash'; import { QuoteCarousel } from '@/components/quote-carousel'; @@ -17,7 +15,6 @@ export function IntroSection() {
-

Open Source Continuous Inference Benchmark Trusted by GigaWatt Token Factories

diff --git a/packages/app/src/components/quote-carousel.tsx b/packages/app/src/components/quote-carousel.tsx index 926118d1..37033853 100644 --- a/packages/app/src/components/quote-carousel.tsx +++ b/packages/app/src/components/quote-carousel.tsx @@ -2,6 +2,7 @@ import Link from 'next/link'; import { useCallback, useEffect, useRef, useState } from 'react'; +import { Quote } from 'lucide-react'; import { track } from '@/lib/analytics'; import { ExternalLinkIcon } from '@/components/ui/external-link-icon'; @@ -66,36 +67,42 @@ function buildCompanyQuotes(quotes: CarouselQuote[], order?: string[]): CompanyE return shuffleArray(entries); } -function QuoteBlock({ quote }: { quote: CarouselQuote }) { +function QuoteText({ quote }: { quote: CarouselQuote }) { return ( -
-

- “{highlightBrand(quote.text)}” +

+

+

-
); } +function QuoteAuthor({ quote }: { quote: CarouselQuote }) { + return ( +
+ +
+
+ {quote.link ? ( + + {quote.name} + + + ) : ( + {quote.name} + )} + {quote.title} +
+
+ ); +} + export function QuoteCarousel({ quotes, overrides = {}, @@ -160,7 +167,7 @@ export function QuoteCarousel({ return (
{ hovering.current = true; }} @@ -168,24 +175,61 @@ export function QuoteCarousel({ hovering.current = false; }} > - {/* Org name strip */} -
- {entries.map((e, i) => ( - - ))} + {/* Org logo strip — infinite marquee carousel; clickable, active is highlighted. + Each set carries `pr-5` so the trailing gap is baked into the 50% + translate, keeping the loop seamless. */} +
+
+ {[0, 1].map((copy) => ( +
+ {entries.map((e, i) => { + const isActive = i === activeIndex; + return ( + + ); + })} +
+ ))} +
- {/* All quotes stacked in same grid cell — tallest sets height */} -
+ {/* Stacked quote texts — tallest sets the cell height. */} +
{entries.map((e, i) => { const isActive = i === activeIndex; return ( @@ -193,28 +237,52 @@ export function QuoteCarousel({ key={e.org} className={`col-start-1 row-start-1 ${ isActive - ? `transition-opacity duration-300 ease-in-out ${fading ? 'opacity-0' : 'opacity-100'}` + ? `transition-opacity duration-300 ease-in-out ${ + fading ? 'opacity-0' : 'opacity-100' + }` : 'opacity-0 invisible pointer-events-none' }`} aria-hidden={!isActive} > - +
); })}
- {moreHref && ( -
+ {/* Bottom row: active quote's author (left) and "See more" link (right), + aligned to the same bottom baseline via items-end. */} +
+
+ {entries.map((e, i) => { + const isActive = i === activeIndex; + return ( +
+ +
+ ); + })} +
+ {moreHref && ( track('quote_carousel_see_more_clicked')} > See more supporters → -
- )} + )} +
); } diff --git a/packages/app/src/components/quotes/quotes-content.tsx b/packages/app/src/components/quotes/quotes-content.tsx index 90052d6f..f2c2d4d6 100644 --- a/packages/app/src/components/quotes/quotes-content.tsx +++ b/packages/app/src/components/quotes/quotes-content.tsx @@ -34,7 +34,7 @@ function QuoteCard({ }) { const content = (
-

+

“{highlightBrand(text)}”