@@ -6,42 +6,41 @@ import { SocialIcons } from "../../../_components/social-icons"
6
6
7
7
import blurBean from "./blur-bean.webp"
8
8
9
+ interface FooterLink {
10
+ href : string
11
+ children : ReactNode
12
+ disabled ?: boolean
13
+ }
14
+
9
15
export function Footer ( {
10
16
links,
11
17
logo,
12
18
} : {
13
- links : { href : string ; children : string ; "aria-disabled" ?: true } [ ] [ ]
19
+ links : ( FooterLink | FooterLink [ ] ) [ ]
14
20
logo : ReactNode
15
21
} ) {
16
22
return (
17
- < footer className = "gql-conf-section gql- all-anchors-focusable relative !bg-neu-100 py-10 text-neu-900 typography-menu dark:!bg-neu-0 max-md:px-0 max-md:pt-0 lg:py-20 " >
23
+ < footer className = "gql-all-anchors-focusable relative !bg-neu-100 text-neu-900 typography-menu dark:!bg-neu-0 max-md:px-0 max-md:pt-0" >
18
24
< Stripes />
19
- < div className = "mb-10 flex flex-wrap items-start justify-between xl:mb-32 xl:gap-10" >
20
- < div className = "border-neu-400 p-5 max-md:w-full max-md:border-b md:p-4" >
21
- { logo }
25
+ < div className = "flex flex-wrap justify-between gap-4 border-neu-400 p-4 max-md:w-full max-md:border-b lg:p-10" >
26
+ { logo }
27
+ < div className = "flex gap-x-4 gap-y-2 typography-body-lg" >
28
+ < p className = "flex items-center gap-2" >
29
+ < time dateTime = "2025-09-08" > September 08</ time >
30
+ < span > -</ span >
31
+ < time dateTime = "2025-09-10" > 10, 2025</ time >
32
+ </ p >
33
+ < address className = "not-italic" > Amsterdam, Netherlands</ address >
22
34
</ div >
23
- { links . map ( ( link , i ) => (
24
- < ul key = { i } className = "max-md:contents" >
25
- { link . map ( ( { "aria-disabled" : isDisabled , children, ...link } ) => (
26
- < li key = { link . href } className = "mb-3.5 max-md:w-1/2" >
27
- < NextLink
28
- { ...link }
29
- className = { clsx (
30
- "gql-focus-visible block p-5" ,
31
- isDisabled
32
- ? "pointer-events-none"
33
- : "underline-offset-4 hover:underline" ,
34
- ) }
35
- tabIndex = { isDisabled ? - 1 : undefined }
36
- >
37
- { children }
38
- </ NextLink >
39
- </ li >
40
- ) ) }
41
- </ ul >
42
- ) ) }
43
35
</ div >
44
- < div className = "relative flex justify-between gap-10 text-sm max-lg:flex-col max-md:px-5" >
36
+ < ul className = "grid grid-cols-2 gap-px bg-neu-400 py-px lg:grid-cols-4" >
37
+ { links . map ( ( box , i ) => (
38
+ < li className = "bg-neu-100 dark:bg-neu-0 lg:h-32" key = { i } >
39
+ < FooterBox box = { box } />
40
+ </ li >
41
+ ) ) }
42
+ </ ul >
43
+ < div className = "relative flex justify-between gap-10 px-6 py-4 text-sm max-lg:flex-col" >
45
44
< div className = "flex flex-col font-light max-md:gap-5" >
46
45
< p >
47
46
Copyright © { new Date ( ) . getFullYear ( ) } The GraphQL Foundation. All
@@ -89,14 +88,17 @@ function Stripes() {
89
88
[--end-2:hsl(var(--color-pri-dark)/0.8)]
90
89
dark:[--start-2:rgba(255,204,239,.1)]
91
90
dark:[--end-2:hsl(var(--color-pri-base)/.8)]
91
+
92
+ mix-blend-darken
93
+ dark:mix-blend-lighten
92
94
"
93
95
style = { {
94
96
maskImage : `url(${ blurBean . src } )` ,
95
97
WebkitMaskImage : `url(${ blurBean . src } )` ,
96
- maskPosition : "center 300px " ,
97
- WebkitMaskPosition : "center 300px " ,
98
- maskSize : "200% 110 %" ,
99
- WebkitMaskSize : "200% 110 %" ,
98
+ maskPosition : "center 200px " ,
99
+ WebkitMaskPosition : "center 200px " ,
100
+ maskSize : "200% 100 %" ,
101
+ WebkitMaskSize : "200% 100 %" ,
100
102
maskRepeat : "no-repeat" ,
101
103
WebkitMaskRepeat : "no-repeat" ,
102
104
maskOrigin : "top" ,
@@ -119,3 +121,44 @@ function Stripes() {
119
121
</ div >
120
122
)
121
123
}
124
+
125
+ function FooterBox ( { box } : { box : FooterLink | FooterLink [ ] } ) {
126
+ if ( Array . isArray ( box ) ) {
127
+ return (
128
+ < div className = "relative flex flex-col p-3" >
129
+ { box . map ( link => (
130
+ < NextLink
131
+ key = { link . href }
132
+ href = { link . href }
133
+ title = { link . disabled ? "Coming soon" : undefined }
134
+ className = { clsx (
135
+ "gql-focus-visible block h-full p-3 first:font-bold" ,
136
+ link . disabled
137
+ ? "pointer-events-none"
138
+ : "underline-offset-4 hover:underline" ,
139
+ ) }
140
+ tabIndex = { link . disabled ? - 1 : undefined }
141
+ >
142
+ { link . children }
143
+ </ NextLink >
144
+ ) ) }
145
+ </ div >
146
+ )
147
+ }
148
+
149
+ const { href, children, disabled } = box
150
+
151
+ return (
152
+ < NextLink
153
+ href = { href }
154
+ title = { disabled ? "Coming soon" : undefined }
155
+ className = { clsx (
156
+ "gql-focus-visible relative block h-full p-6" ,
157
+ disabled ? "pointer-events-none" : "underline-offset-4 hover:underline" ,
158
+ ) }
159
+ tabIndex = { disabled ? - 1 : undefined }
160
+ >
161
+ { children }
162
+ </ NextLink >
163
+ )
164
+ }
0 commit comments