@@ -6,23 +6,9 @@ import Link from "next/link"
66import { Button } from "../../_design-system/button"
77import ArrowDownIcon from "../pixelarticons/arrow-down.svg?svgr"
88
9- function TabHeading ( {
10- children,
11- className,
12- } : {
13- children : ReactNode
14- className ?: string
15- } ) {
16- return (
17- < h2 className = { clsx ( "mb-4 text-2xl font-semibold" , className ) } >
18- { children }
19- </ h2 >
20- )
21- }
22-
239function DatesTab ( ) {
2410 return (
25- < dl className = "divide-y divide-sec-dark border-neu-300 md:divide-neu-300 md:border" >
11+ < DefinitionListBox >
2612 < DefinitionListItem term = "CFP Opens" definition = "Tuesday, 4 February" />
2713 < DefinitionListItem
2814 term = "CFP Close"
@@ -44,7 +30,7 @@ function DatesTab() {
4430 term = "Event Dates"
4531 definition = "Monday, 8 September - Wednesday, 10 September, 2024"
4632 />
47- </ dl >
33+ </ DefinitionListBox >
4834 )
4935}
5036
@@ -58,21 +44,21 @@ function DefinitionListItem({
5844 definition : string
5945} ) {
6046 return (
61- < div className = { clsx ( className , "flex typography-body-md max-md :flex-col" ) } >
62- < dt className = "flex w-[184.5px] shrink-0 items-center whitespace-pre border-neu-300 bg-white/[0.79] px-3 py-2 max-md :w-full md :border-r md :p-4" >
47+ < div className = { clsx ( className , "flex typography-body-md max-sm :flex-col" ) } >
48+ < dt className = "flex w-[184.5px] shrink-0 items-center whitespace-pre border-neu-300 bg-white/[0.79] px-3 py-2 max-sm :w-full sm :border-r sm :p-4" >
6349 { term }
6450 </ dt >
65- < dd className = "flex flex-1 items-center bg-white/[0.48] px-3 py-2 backdrop-blur-[3px] md :p-4" >
51+ < dd className = "flex flex-1 items-center bg-white/[0.48] px-3 py-2 backdrop-blur-[3px] sm :p-4" >
6652 { definition }
6753 </ dd >
6854 </ div >
6955 )
7056}
7157function TopicsTab ( ) {
7258 return (
73- < div >
74- < TabHeading className = "mt-6 " > Suggested Topics</ TabHeading >
75- < ul className = "list-disc space-y-2 pl-6" >
59+ < div className = "bg-sec-light p-4" >
60+ < h3 className = "typography-h3 " > Suggested Topics</ h3 >
61+ < ul className = "mt-2 list-disc space-y-2 pl-6" >
7662 < li > GraphQL Working Group</ li >
7763 < ul className = "list-disc space-y-2 pl-6" >
7864 < li >
@@ -110,20 +96,20 @@ function TopicsTab() {
11096
11197function NotesTab ( ) {
11298 return (
113- < div >
114- < TabHeading className = "mt-6 " > Important Notes</ TabHeading >
115- < ul className = "list-disc space-y-2 pl-6" >
99+ < div className = "bg-sec-light p-4" >
100+ < h3 className = "typography-h3 " > Important Notes</ h3 >
101+ < ul className = "mt-2 list-disc space-y-2 pl-6" >
116102 < li >
117103 All speakers are required to adhere to our{ " " }
118104 < Link
119- className = "underline hover:text-primary "
105+ className = "text-neu-800 underline hover:no-underline dark: text-neu-50 "
120106 href = "/conf/2025/resources/#code-of-conduct"
121107 >
122108 Code of Conduct
123109 </ Link >
124110 . We also highly recommend that speakers take our online{ " " }
125111 < a
126- className = "underline hover:text-primary "
112+ className = "text-neu-800 underline hover:no-underline dark: text-neu-50 "
127113 target = "_blank"
128114 href = "https://training.linuxfoundation.org/linux-courses/open-source-compliance-courses/inclusive-speaker-orientation"
129115 >
@@ -153,10 +139,8 @@ function NotesTab() {
153139 event.
154140 </ li >
155141 </ ul >
156- < TabHeading className = "mt-6" >
157- Preparing to Submit Your Proposal
158- </ TabHeading >
159- < p className = "mb-4" >
142+ < h3 className = "mt-6 typography-h3" > Preparing to Submit Your Proposal</ h3 >
143+ < p className = "mt-2" >
160144 While it is not our intention to provide you with strict instructions on
161145 how to prepare your proposal, we hope you will take a moment to review
162146 the following guidelines that we have put together to help you prepare
@@ -176,22 +160,25 @@ function NotesTab() {
176160 letting you share your experiences, educate the community about an
177161 issue, or generate interest in a project.
178162 </ p >
179- < TabHeading className = "mt-6" > How to Give a Great Talk</ TabHeading >
180- < p >
163+ < h3 className = "mt-6 typography-h3 " > How to Give a Great Talk</ h3 >
164+ < p className = "mt-2" >
181165 We want to make sure submitters receive resources to help put together a
182166 great submission and if accepted, give the best presentation possible.
183167 To help with this, we recommend viewing seasoned speaker Dawn Foster's
184168 in-depth talk:{ " " }
185- < a href = "https://youtu.be/2I5fYBLCfUA" target = "_blank" >
186- Getting Over Your Imposter Syndrome to Become a Conference Speaker –
187- Dawn Foster, VMware
169+ < a
170+ href = "https://youtu.be/2I5fYBLCfUA"
171+ target = "_blank"
172+ className = "text-neu-800 underline hover:no-underline dark:text-neu-50"
173+ >
174+ Getting Over Your Imposter Syndrome to Become a Conference Speaker
188175 </ a >
189176 .
190177 </ p >
191- < TabHeading className = "mt-6" >
178+ < h3 className = "mt-6 typography-h3 " >
192179 Have More Questions? First Time Submitting? Don't Feel Intimidated
193- </ TabHeading >
194- < p >
180+ </ h3 >
181+ < p className = "mt-2" >
195182 Linux Foundation events are an excellent way to get to know the
196183 community and share your ideas and the work that you are doing and we
197184 strongly encourage first-time speakers to submit talks for our events.
@@ -205,30 +192,38 @@ function NotesTab() {
205192
206193function TypesTab ( ) {
207194 return (
208- < div >
209- < TabHeading className = "mt-6" > Submission Types</ TabHeading >
210- < ul className = "list-disc space-y-2 pl-6" >
211- < li >
212- Session Presentation: Typically 30 minutes in length, 1-2 speakers
213- presenting on a topic
214- </ li >
215- < li >
216- Panel Discussion: Typically 30 minutes in length, 3-4 speakers
217- presenting on a topic
218- </ li >
219- < li > Birds of a Feather: Typically 45 minutes to 1 hour in length</ li >
220- < li > Lightning Talk: Typically 5-10 minutes in length</ li >
221- < li > Workshop: Typically 1-2 hours in length</ li >
222- </ ul >
195+ < div className = "md:p-8 lg:p-16" >
196+ < dl className = "divide-y divide-sec-dark border-neu-300 md:divide-neu-300 md:border md:shadow-[0px_0px_20px_0px_rgba(133,185,19,0.20)]" >
197+ < DefinitionListItem
198+ term = "Session Presentation"
199+ definition = "Typically 30 minutes in length, 1-2 speakers presenting on a topic"
200+ />
201+ < DefinitionListItem
202+ term = "Panel Discussion"
203+ definition = "Typically 30 minutes in length, 3-4 speakers presenting on a topic"
204+ />
205+ < DefinitionListItem
206+ term = "Birds of a Feather"
207+ definition = "Typically 45 minutes to 1 hour in length"
208+ />
209+ < DefinitionListItem
210+ term = "Lightning Talk"
211+ definition = "Typically 5-10 minutes in length"
212+ />
213+ < DefinitionListItem
214+ term = "Workshop"
215+ definition = "Typically 1-2 hours in length"
216+ />
217+ </ dl >
223218 </ div >
224219 )
225220}
226221
227222function ProcessTab ( ) {
228223 return (
229- < div >
230- < TabHeading className = "mt-6 " > The Talk Selection Process</ TabHeading >
231- < p className = "mb-4 " >
224+ < div className = "bg-sec-light p-4" >
225+ < h3 className = "typography-h3 " > The Talk Selection Process</ h3 >
226+ < p className = "mt-2 " >
232227 The GraphQL Foundation strives to select conference talks based on fair
233228 criteria in a transparent manner. There are three groups involved in the
234229 selection process, each with their own focus to help create an engaging
@@ -239,36 +234,36 @@ function ProcessTab() {
239234 < li > The new Subject Matter Experts initiative (SMEs)</ li >
240235 < li > The Program Committee</ li >
241236 </ ul >
242- < TabHeading className = "mt-6" > The Technical Steering Committee</ TabHeading >
243- < p className = "mb-4 " >
237+ < h3 className = "mt-6 typography-h3 " > The Technical Steering Committee</ h3 >
238+ < p className = "mt-2 " >
244239 The TSC are a group of 11 individuals who are elected to serve a two
245240 year term to provide technical oversight of all GraphQL development
246241 efforts. When evaluating conference talks they{ " " }
247242 < strong > focus on quality</ strong > and use the following criteria:
248243 </ p >
249- < ul className = "list-disc space-y-2 pl-6" >
244+ < ul className = "mt-2 list-disc space-y-2 pl-6" >
250245 < li > Relevance</ li >
251246 < li > Originality</ li >
252247 < li > Soundness</ li >
253248 < li > Quality of Presentation</ li >
254249 < li > Importance</ li >
255250 </ ul >
256- < TabHeading className = "mt-6" > Subject Matter Experts</ TabHeading >
257- < p className = "mb-4 " >
251+ < h3 className = "mt-6 typography-h3 " > Subject Matter Experts</ h3 >
252+ < p className = "mt-2 " >
258253 The SME initiative is new for 2025. This will be a panel of volunteers
259254 drawn from industry experts, working group members, security and
260255 observability experts, and maintainers and contributors to open source
261256 GraphQL projects. When evaluating the talks, they will{ " " }
262257 < strong > focus on how exciting and engaging the talks are</ strong > and
263258 use the following criteria:
264259 </ p >
265- < ul className = "list-disc space-y-2 pl-6" >
260+ < ul className = "mt-2 list-disc space-y-2 pl-6" >
266261 < li > Subject Content</ li >
267262 < li > Originality</ li >
268263 < li > Audience Engagement</ li >
269264 </ ul >
270- < TabHeading className = "mt-6" > The Program Committee</ TabHeading >
271- < p >
265+ < h3 className = "mt-6 typography-h3 " > The Program Committee</ h3 >
266+ < p className = "mt-2" >
272267 The Program Committee is made up of representatives from the GraphQL
273268 Foundation board and interested members of the GraphQL community who
274269 have had experience organizing conferences. They shape the schedule from
@@ -277,10 +272,10 @@ function ProcessTab() {
277272 demographics, to ensure a varied and well-rounded representation of the
278273 GraphQL ecosystem.
279274 </ p >
280- < TabHeading className = "mt-6" >
275+ < h3 className = "mt-6 typography-h3 " >
281276 Have More Questions? First Time Submitting? Don't Feel Intimidated
282- </ TabHeading >
283- < p >
277+ </ h3 >
278+ < p className = "mt-2" >
284279 Linux Foundation events are an excellent way to get to know the
285280 community and share your ideas and the work that you are doing and we
286281 strongly encourage first-time speakers to submit talks for our events.
@@ -325,7 +320,11 @@ export function CallForProposals() {
325320 } , [ ] )
326321
327322 return (
328- < section id = "speakers" className = "gql-conf-section gql-conf-container" >
323+ < section
324+ id = "speakers"
325+ // todo: the part with `dark:` here is temporary until we have a dark mode version of this section
326+ className = "gql-conf-section gql-conf-container dark:text-neu-0"
327+ >
329328 < div className = "flex *:basis-1/2 max-md:flex-col" >
330329 < div className = "border-sec-dark bg-sec-light p-4 dark:border-sec-lighter md:border-r md:p-8 lg:p-16" >
331330 < h1 className = "typography-h2" > Call for Proposals</ h1 >
@@ -340,7 +339,7 @@ export function CallForProposals() {
340339 For any questions regarding the CFP process, please email{ " " }
341340 < a
342341 href = "mailto:cfp@linuxfoundation.org"
343- className = "text-neu-800 underline hover:no-underline"
342+ className = "text-neu-800 underline hover:no-underline dark:text-neu-50 "
344343 >
345344 cfp@linuxfoundation.org
346345 </ a >
@@ -354,7 +353,7 @@ export function CallForProposals() {
354353 < a
355354 target = "_blank"
356355 href = "https://sessionize.com/playbook/submit-your-session-for-an-event"
357- className = "text-neu-800 underline hover:no-underline"
356+ className = "text-neu-800 underline hover:no-underline dark:text-neu-50 "
358357 >
359358 how to submit your session
360359 </ a > { " " }
@@ -377,32 +376,81 @@ export function CallForProposals() {
377376 < article className = "flex h-auto flex-col bg-[#C6F267]" >
378377 < div
379378 role = "tablist"
380- className = "flex divide-sec-dark border-b border-sec-dark *:flex-1 md:divide-x"
379+ className = "flex divide-sec-dark border-b border-sec-dark *:flex-1 max-md:sr-only md:divide-x"
381380 >
382381 { tabsInOrder . map ( ( tab , i ) => (
383- < button
384- key = { tab }
382+ < TabButton
383+ tab = { tab }
385384 tabIndex = { i === 0 ? 0 : - 1 }
386- role = "tab"
387- aria-selected = { activeTab === tab }
388- className = "gql-focus-visible flex items-center justify-between px-3 py-4 typography-body-lg hover:bg-sec-light focus:outline-none aria-selected:bg-sec-light"
389- onFocus = { ( ) => setActiveTab ( tab ) }
390- onKeyDown = { arrowsMoveSideways }
391- >
392- { tab . charAt ( 0 ) . toUpperCase ( ) + tab . slice ( 1 ) }
393- < ArrowDownIcon className = "ml-2 size-6 text-sec-darker opacity-0 [[aria-selected=true]>&]:opacity-100" />
394- </ button >
385+ activeTab = { activeTab }
386+ setActiveTab = { setActiveTab }
387+ />
395388 ) ) }
396389 </ div >
397- < div className = "flex flex-1 items-center justify-center md:p-8 lg:p-16" >
398- { tabs [ activeTab ] }
390+ < div className = "flex flex-1 justify-center max-md:flex-col md:items-center" >
391+ { tabsInOrder . map ( tab => (
392+ < >
393+ < TabButton
394+ tab = { tab }
395+ activeTab = { activeTab }
396+ setActiveTab = { setActiveTab }
397+ className = "md:hidden"
398+ aria-hidden
399+ />
400+ < div
401+ role = "tabpanel"
402+ key = { tab }
403+ id = { `tabpanel-${ tab } ` }
404+ className = "flex-1"
405+ style = { {
406+ display : activeTab === tab ? "block" : "none" ,
407+ } }
408+ >
409+ { tabs [ tab ] }
410+ </ div >
411+ </ >
412+ ) ) }
399413 </ div >
400414 </ article >
401415 </ div >
402416 </ section >
403417 )
404418}
405419
420+ interface TabButtonProps
421+ extends Omit < React . HTMLAttributes < HTMLButtonElement > , "onFocus" > {
422+ tab : Tab
423+ tabIndex ?: number
424+ activeTab : Tab
425+ setActiveTab : ( tab : Tab ) => void
426+ }
427+
428+ function TabButton ( {
429+ tab,
430+ tabIndex,
431+ activeTab,
432+ setActiveTab,
433+ ...props
434+ } : TabButtonProps ) {
435+ return (
436+ < button
437+ key = { tab }
438+ tabIndex = { tabIndex }
439+ aria-selected = { activeTab === tab }
440+ className = "gql-focus-visible flex items-center justify-between px-3 py-4 typography-body-lg hover:bg-sec-light focus:outline-none max-md:border-b max-md:border-sec-dark max-md:first:border-t md:[--collapsible:1] md:aria-selected:bg-sec-light"
441+ onFocus = { event => {
442+ console . log ( "focus" )
443+ setActiveTab ( tab )
444+ } }
445+ onKeyDown = { arrowsMoveSideways }
446+ { ...props }
447+ >
448+ { tab . charAt ( 0 ) . toUpperCase ( ) + tab . slice ( 1 ) }
449+ < ArrowDownIcon className = "ml-2 size-6 text-sec-darker opacity-0 [[aria-selected=true]>&]:opacity-100" />
450+ </ button >
451+ )
452+ }
453+
406454function arrowsMoveSideways ( event : React . KeyboardEvent < HTMLButtonElement > ) {
407455 if ( event . key === "ArrowLeft" ) {
408456 const previousElement = event . currentTarget . previousElementSibling
@@ -416,3 +464,13 @@ function arrowsMoveSideways(event: React.KeyboardEvent<HTMLButtonElement>) {
416464 }
417465 }
418466}
467+
468+ function DefinitionListBox ( { children } : { children : React . ReactNode } ) {
469+ return (
470+ < div className = "md:p-8 lg:p-16" >
471+ < dl className = "divide-y divide-sec-dark border-neu-300 md:divide-neu-300 md:border md:shadow-[0px_0px_20px_0px_rgba(133,185,19,0.20)]" >
472+ { children }
473+ </ dl >
474+ </ div >
475+ )
476+ }
0 commit comments