Skip to content

Commit 67c7333

Browse files
committed
Make the decoration look like on the design
1 parent b5ed3b4 commit 67c7333

File tree

6 files changed

+138
-73
lines changed

6 files changed

+138
-73
lines changed

src/app/conf/2025/components/footer/index.tsx

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ReactNode } from "react"
33
import { clsx } from "clsx"
44

55
import { SocialIcons } from "../../../_components/social-icons"
6+
import { StripesDecoration } from "../../../_design-system/stripes-decoration"
67

78
import blurBean from "./blur-bean.webp"
89

@@ -66,11 +67,6 @@ export function Footer({
6667
)
6768
}
6869

69-
const maskEven =
70-
"repeating-linear-gradient(to right, transparent, transparent 12px, black 12px, black 24px)"
71-
const maskOdd =
72-
"repeating-linear-gradient(to right, black, black 12px, transparent 12px, transparent 24px)"
73-
7470
function Stripes() {
7571
return (
7672
<div
@@ -104,19 +100,9 @@ function Stripes() {
104100
maskOrigin: "top",
105101
}}
106102
>
107-
<div
108-
className="absolute inset-0 bg-[linear-gradient(180deg,var(--start-1)_0%,var(--end-1)_200%)]"
109-
style={{
110-
maskImage: maskEven,
111-
WebkitMaskImage: maskEven,
112-
}}
113-
/>
114-
<div
115-
className="absolute inset-0 bg-[linear-gradient(180deg,var(--start-2)_0%,var(--end-2)_200%)]"
116-
style={{
117-
maskImage: maskOdd,
118-
WebkitMaskImage: maskOdd,
119-
}}
103+
<StripesDecoration
104+
evenClassName="bg-[linear-gradient(180deg,var(--start-1)_0%,var(--end-1)_200%)]"
105+
oddClassName="bg-[linear-gradient(180deg,var(--start-2)_0%,var(--end-2)_200%)]"
120106
/>
121107
</div>
122108
)

src/app/conf/2025/components/marquee-under-hero.tsx

Lines changed: 0 additions & 35 deletions
This file was deleted.
Binary file not shown.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Fragment } from "react"
2+
3+
import { Marquee } from "@/app/conf/_design-system/marquee"
4+
5+
import CodeIcon from "../../pixelarticons/code.svg?svgr"
6+
7+
import blurWave from "./blur.webp"
8+
import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
9+
10+
const keywords = [
11+
["COMMUNITY", "DEVELOPER EXPERIENCE", "APIs", "TOOLS & LIBRARIES"],
12+
["OPEN SOURCE", "FEDERATION", "ECOSYSTEMS", "TRACING & OBSERVABILITY"],
13+
["BEST PRACTICES", "WORKSHOPS", "SCHEMAS", "SECURITY"],
14+
]
15+
16+
export function MarqueeUnderHero() {
17+
return (
18+
<section className="relative pt-4 font-mono text-xl/none text-pri-base max-sm:pb-1 sm:pt-6 md:space-y-2 md:pt-12 md:text-[56px]/none xl:pt-16">
19+
<Stripes />
20+
{keywords.map((row, i) => (
21+
<Marquee
22+
key={i}
23+
gap={16}
24+
speed={35}
25+
speedOnHover={15}
26+
className="relative *:select-none"
27+
reverse={i % 2 === 1}
28+
drag
29+
>
30+
{row.map((keyword, j) => (
31+
<Fragment key={keyword}>
32+
<span>{keyword}</span>
33+
{j !== row.length - 1 && (
34+
<CodeIcon className="size-8 text-pri-dark dark:text-pri-light md:size-10" />
35+
)}
36+
</Fragment>
37+
))}
38+
</Marquee>
39+
))}
40+
</section>
41+
)
42+
}
43+
44+
function Stripes() {
45+
return (
46+
<div
47+
role="presentation"
48+
// prettier-ignore
49+
// false positive
50+
// eslint-disable-next-line tailwindcss/no-contradicting-classname
51+
className="pointer-events-none absolute inset-0 -bottom-1/2
52+
53+
[--start:hsl(var(--color-pri-light)/.6)]
54+
[--end:hsl(var(--color-pri-lighter)/.05)]
55+
dark:[--start:hsl(320_86_20/.6)]
56+
dark:[--end:hsl(var(--color-pri-base)/.025)]
57+
58+
[mask-size:400%_100%]
59+
sm:[mask-size:cover]
60+
"
61+
style={{
62+
maskImage: `url(${blurWave.src})`,
63+
WebkitMaskImage: `url(${blurWave.src})`,
64+
maskRepeat: "no-repeat",
65+
WebkitMaskRepeat: "no-repeat",
66+
}}
67+
>
68+
<StripesDecoration oddClassName="bg-[linear-gradient(180deg,var(--start)_0%,var(--end)_100%)]" />
69+
</div>
70+
)
71+
}

src/app/conf/_design-system/marquee.tsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { clsx } from "clsx"
44
import { useMotionValue, animate, motion } from "motion/react"
5-
import { useState, useEffect } from "react"
5+
import { useState, useEffect, Fragment } from "react"
66
import useMeasure from "react-use-measure"
77

88
export interface MarqueeProps {
@@ -13,6 +13,7 @@ export interface MarqueeProps {
1313
direction?: "horizontal" | "vertical"
1414
reverse?: boolean
1515
className?: string
16+
drag?: boolean
1617
}
1718

1819
export function Marquee({
@@ -23,6 +24,7 @@ export function Marquee({
2324
direction = "horizontal",
2425
reverse = false,
2526
className,
27+
drag = false,
2628
}: MarqueeProps) {
2729
const [currentSpeed, setCurrentSpeed] = useState(speed)
2830
const [ref, { width, height }] = useMeasure()
@@ -89,20 +91,32 @@ export function Marquee({
8991
setIsTransitioning(true)
9092
setCurrentSpeed(speed)
9193
},
94+
onPointerUp: () => {
95+
if (window.matchMedia("(hover: none)").matches) {
96+
setIsTransitioning(true)
97+
setCurrentSpeed(speed)
98+
}
99+
},
92100
}
93101
: {}
94102

103+
const multiples = drag ? 12 : 2
104+
const dragProps = drag
105+
? {
106+
drag: "x" as const,
107+
onDragStart: () => {
108+
document.documentElement.style.cursor = "grabbing"
109+
},
110+
onDragEnd: () => {
111+
document.documentElement.style.cursor = "initial"
112+
},
113+
}
114+
: {}
115+
95116
return (
96117
<div className={clsx("overflow-hidden", className)}>
97118
<motion.div
98119
className="flex w-max"
99-
drag="x"
100-
onDragStart={() => {
101-
document.documentElement.style.cursor = "grabbing"
102-
}}
103-
onDragEnd={() => {
104-
document.documentElement.style.cursor = "initial"
105-
}}
106120
style={{
107121
...(direction === "horizontal"
108122
? { x: translation }
@@ -112,20 +126,12 @@ export function Marquee({
112126
alignItems: "center",
113127
}}
114128
ref={ref}
129+
{...dragProps}
115130
{...hoverProps}
116131
>
117-
{children}
118-
{children}
119-
{children}
120-
{children}
121-
{children}
122-
{children}
123-
{children}
124-
{children}
125-
{children}
126-
{children}
127-
{children}
128-
{children}
132+
{Array.from({ length: multiples }).map((_, i) => (
133+
<Fragment key={i}>{children}</Fragment>
134+
))}
129135
</motion.div>
130136
</div>
131137
)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import clsx from "clsx"
2+
3+
const maskEven =
4+
"repeating-linear-gradient(to right, transparent, transparent 12px, black 12px, black 24px)"
5+
6+
const maskOdd =
7+
"repeating-linear-gradient(to right, black, black 12px, transparent 12px, transparent 24px)"
8+
9+
export interface StripesDecorationProps {
10+
evenClassName?: string
11+
oddClassName?: string
12+
}
13+
14+
export function StripesDecoration(props: StripesDecorationProps) {
15+
return (
16+
<>
17+
{props.evenClassName && (
18+
<div
19+
className={clsx("absolute inset-0", props.evenClassName)}
20+
style={{
21+
maskImage: maskEven,
22+
WebkitMaskImage: maskEven,
23+
}}
24+
/>
25+
)}
26+
{props.oddClassName && (
27+
<div
28+
className={clsx("absolute inset-0", props.oddClassName)}
29+
style={{
30+
maskImage: maskOdd,
31+
WebkitMaskImage: maskOdd,
32+
}}
33+
/>
34+
)}
35+
</>
36+
)
37+
}

0 commit comments

Comments
 (0)