mirror of
https://github.com/System-End/site.git
synced 2026-04-19 20:55:09 +00:00
Add OnBoard marketing page (#795)
Co-authored-by: Max Wofford <max@maxwofford.com>
This commit is contained in:
parent
563565c47e
commit
a85b66453f
5 changed files with 778 additions and 6 deletions
|
|
@ -150,6 +150,9 @@ const Navigation = props => (
|
||||||
</NextLink>
|
</NextLink>
|
||||||
<Link href="https://scrapbook.hackclub.com/">Scrapbook</Link>
|
<Link href="https://scrapbook.hackclub.com/">Scrapbook</Link>
|
||||||
<Link href="https://workshops.hackclub.com/">Workshops</Link>
|
<Link href="https://workshops.hackclub.com/">Workshops</Link>
|
||||||
|
<NextLink href="/onboard" passHref>
|
||||||
|
<Link>OnBoard</Link>
|
||||||
|
</NextLink>
|
||||||
</NavBar>
|
</NavBar>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
"react-tooltip": "^4.5.1",
|
"react-tooltip": "^4.5.1",
|
||||||
"react-tsparticles": "^2.9.3",
|
"react-tsparticles": "^2.9.3",
|
||||||
"react-use-websocket": "^4.3.1",
|
"react-use-websocket": "^4.3.1",
|
||||||
"react-wrap-balancer": "^0.4.0",
|
"react-wrap-balancer": "^0.5.0",
|
||||||
"recharts": "2.1.12",
|
"recharts": "2.1.12",
|
||||||
"styled-components": "^5.3.9",
|
"styled-components": "^5.3.9",
|
||||||
"swr": "^2.1.2",
|
"swr": "^2.1.2",
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import Meta from '@hackclub/meta'
|
||||||
import '@hackclub/theme/fonts/reg-bold.css'
|
import '@hackclub/theme/fonts/reg-bold.css'
|
||||||
import theme from '../lib/theme'
|
import theme from '../lib/theme'
|
||||||
import { ThemeProvider } from 'theme-ui'
|
import { ThemeProvider } from 'theme-ui'
|
||||||
|
import { Provider as BalancerProvider } from 'react-wrap-balancer'
|
||||||
|
|
||||||
const App = ({ Component, pageProps }) => (
|
const App = ({ Component, pageProps }) => (
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
|
|
@ -16,7 +17,9 @@ const App = ({ Component, pageProps }) => (
|
||||||
content="7zE7h5foPaxIcnv5Frq6BkcUb9-3UzVc8q3P_cexf9I"
|
content="7zE7h5foPaxIcnv5Frq6BkcUb9-3UzVc8q3P_cexf9I"
|
||||||
/>
|
/>
|
||||||
</Meta>
|
</Meta>
|
||||||
<Component {...pageProps} />
|
<BalancerProvider>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</BalancerProvider>
|
||||||
<Analytics />
|
<Analytics />
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
766
pages/onboard.js
Normal file
766
pages/onboard.js
Normal file
|
|
@ -0,0 +1,766 @@
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Grid,
|
||||||
|
Heading,
|
||||||
|
Image,
|
||||||
|
Text,
|
||||||
|
Flex,
|
||||||
|
Link
|
||||||
|
} from 'theme-ui'
|
||||||
|
import Balancer from 'react-wrap-balancer'
|
||||||
|
import Head from 'next/head'
|
||||||
|
import Meta from '@hackclub/meta'
|
||||||
|
import Nav from '../components/nav'
|
||||||
|
import Footer from '../components/footer'
|
||||||
|
import FadeIn from '../components/fade-in'
|
||||||
|
import Sparkles from '../components/sparkles'
|
||||||
|
import Tilt from '../components/tilt'
|
||||||
|
import usePrefersReducedMotion from '../lib/use-prefers-reduced-motion'
|
||||||
|
import { useRef, useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import('theme-ui').ThemeUIStyleObject}
|
||||||
|
*/
|
||||||
|
const traceSx = {
|
||||||
|
width: 6,
|
||||||
|
bg: '#e2b747',
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
mr: 100,
|
||||||
|
position: 'relative'
|
||||||
|
}
|
||||||
|
|
||||||
|
const dimBg = '#151515'
|
||||||
|
|
||||||
|
// Beloved classic utility function :3
|
||||||
|
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
|
||||||
|
|
||||||
|
// "LET'S RECAP" pixel art (exported from Piskel)
|
||||||
|
// Original: https://doggo.ninja/fiK0nk.piskel
|
||||||
|
const recapWidth = 71
|
||||||
|
const recapHeight = 10
|
||||||
|
const recapPixels = [
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||||
|
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
|
||||||
|
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff
|
||||||
|
]
|
||||||
|
|
||||||
|
const slackLink = `/slack/?reason=${encodeURIComponent('I joined for OnBoard!')}`
|
||||||
|
|
||||||
|
const stickerButtonText = 'Click 4 Stickers'
|
||||||
|
const stickerButtonFont = 'Oleo Script'
|
||||||
|
const stickerButtonFontStylesheet = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(stickerButtonFont)}&display=swap&text=${encodeURIComponent(stickerButtonText)}`
|
||||||
|
|
||||||
|
const wandImgTraced = 'https://cloud-8lszi55ph-hack-club-bot.vercel.app/10frame_2.png'
|
||||||
|
const wandImgRendered = 'https://cloud-8lszi55ph-hack-club-bot.vercel.app/00frame_1.png'
|
||||||
|
|
||||||
|
const ShipPage = () => {
|
||||||
|
const prefersReducedMotion = usePrefersReducedMotion()
|
||||||
|
|
||||||
|
// Wand flicker animation
|
||||||
|
const [ wandImg, setWandImg ] = useState(wandImgTraced)
|
||||||
|
const wandAnimated = useRef(false)
|
||||||
|
useEffect(() => {
|
||||||
|
let canceled = false
|
||||||
|
|
||||||
|
const flicker = async () => {
|
||||||
|
if (canceled) return
|
||||||
|
setWandImg(wandImgTraced)
|
||||||
|
await sleep(Math.random() * 80 + 10); if (canceled) return
|
||||||
|
setWandImg(wandImgRendered)
|
||||||
|
setTimeout(flicker, Math.random() * 4000 + 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
const animate = async () => {
|
||||||
|
if (wandAnimated.current) return
|
||||||
|
wandAnimated.current = true
|
||||||
|
|
||||||
|
await sleep(1500); if (canceled) return
|
||||||
|
|
||||||
|
setWandImg(wandImgRendered)
|
||||||
|
await sleep(60); if (canceled) return
|
||||||
|
setWandImg(wandImgTraced)
|
||||||
|
await sleep(340); if (canceled) return
|
||||||
|
|
||||||
|
setWandImg(wandImgRendered)
|
||||||
|
await sleep(14); if (canceled) return
|
||||||
|
setWandImg(wandImgTraced)
|
||||||
|
await sleep(55); if (canceled) return
|
||||||
|
|
||||||
|
setWandImg(wandImgRendered)
|
||||||
|
await sleep(10); if (canceled) return
|
||||||
|
setWandImg(wandImgTraced)
|
||||||
|
await sleep(150); if (canceled) return
|
||||||
|
|
||||||
|
setWandImg(wandImgRendered)
|
||||||
|
setTimeout(flicker, 1200)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefersReducedMotion) {
|
||||||
|
setWandImg(wandImgRendered)
|
||||||
|
} else {
|
||||||
|
animate()
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => canceled = true
|
||||||
|
}, [ prefersReducedMotion ])
|
||||||
|
|
||||||
|
// Spotlight effect
|
||||||
|
const spotlightRef = useRef()
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = (event) => {
|
||||||
|
spotlightRef.current.style.background = `radial-gradient(
|
||||||
|
circle at ${event.pageX}px ${event.pageY}px,
|
||||||
|
rgba(0, 0, 0, 0) 10px,
|
||||||
|
rgba(0, 0, 0, 0.85) 80px
|
||||||
|
)`
|
||||||
|
}
|
||||||
|
window.addEventListener('mousemove', handler)
|
||||||
|
return () => window.removeEventListener('mousemove', handler)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// Calculating the bus height to match the bottom left of the first connector.
|
||||||
|
const [ busHeight, setBusHeight ] = useState(null)
|
||||||
|
const containerRef = useRef() // For ResizeObserver
|
||||||
|
const connectorRef = useRef() // To get bottom left position
|
||||||
|
const busRef = useRef() // To calculate height differential
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new ResizeObserver(() => {
|
||||||
|
const connectorRect = connectorRef.current.getBoundingClientRect()
|
||||||
|
const busRect = busRef.current.getBoundingClientRect()
|
||||||
|
setBusHeight(busRect.bottom - connectorRect.bottom + 4.5)
|
||||||
|
})
|
||||||
|
|
||||||
|
observer.observe(containerRef.current)
|
||||||
|
return () => observer.disconnect()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// Fancy lights animation
|
||||||
|
const lightsScrollTrigger = useRef()
|
||||||
|
const lightsAnimated = useRef(false)
|
||||||
|
useEffect(() => {
|
||||||
|
let canceled = false
|
||||||
|
|
||||||
|
const setAtIndex = (i, color) => {
|
||||||
|
if (canceled) return
|
||||||
|
|
||||||
|
// Going outside of React for performance
|
||||||
|
const el = document.getElementById(`pixel-${i}`)
|
||||||
|
if (!el) return
|
||||||
|
|
||||||
|
if (recapPixels[i]) {
|
||||||
|
el.style.background = color
|
||||||
|
el.style.boxShadow = `0 0 10px ${color}`
|
||||||
|
} else {
|
||||||
|
el.style.background = dimBg
|
||||||
|
el.style.boxShadow = 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const setAll = (color) => {
|
||||||
|
for (let i = 0; i < recapPixels.length; i++) setAtIndex(i, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
const animate = async () => {
|
||||||
|
if (lightsAnimated.current) return
|
||||||
|
lightsAnimated.current = true
|
||||||
|
|
||||||
|
// Illuminate lights in diagonal lines starting with only top left.
|
||||||
|
for (let curColumn = 0; curColumn < recapWidth + recapHeight; curColumn++) {
|
||||||
|
for (let offset = curColumn; offset >= Math.max(0, curColumn - recapHeight); offset--) {
|
||||||
|
const i = curColumn * recapWidth + offset - offset * recapWidth
|
||||||
|
setAtIndex(i, '#ffffff')
|
||||||
|
if (!recapPixels[i]) await sleep(4); if (canceled) return
|
||||||
|
}
|
||||||
|
// await sleep(2); if (canceled) return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flash the lights twice
|
||||||
|
await sleep(600); if (canceled) return
|
||||||
|
|
||||||
|
setAll(dimBg)
|
||||||
|
await sleep(80); if (canceled) return
|
||||||
|
|
||||||
|
setAll('#aaaaaa')
|
||||||
|
await sleep(20); if (canceled) return
|
||||||
|
|
||||||
|
setAll(dimBg)
|
||||||
|
await sleep(30); if (canceled) return
|
||||||
|
|
||||||
|
setAll('#aaaaaa')
|
||||||
|
await sleep(100); if (canceled) return
|
||||||
|
|
||||||
|
setAll(dimBg)
|
||||||
|
await sleep(200); if (canceled) return
|
||||||
|
|
||||||
|
// Animate rainbow 2-column increments
|
||||||
|
for (let x = 0; x < recapWidth; x++) {
|
||||||
|
const color = `hsl(${x * 360 / recapWidth}, 100%, 65%)`
|
||||||
|
for (let y = 0; y < recapHeight; y++) {
|
||||||
|
const i = y * recapWidth + x
|
||||||
|
setAtIndex(i, color)
|
||||||
|
}
|
||||||
|
if (x % 2 === 1) await sleep(35)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefersReducedMotion) {
|
||||||
|
if (!lightsAnimated.current) setAll('#ffffff')
|
||||||
|
return () => canceled = true
|
||||||
|
} else {
|
||||||
|
const observer = new IntersectionObserver(([ entry ]) => {
|
||||||
|
if (entry.isIntersecting) animate()
|
||||||
|
}, { threshold: 0.5 })
|
||||||
|
observer.observe(lightsScrollTrigger.current)
|
||||||
|
return () => {
|
||||||
|
canceled = true
|
||||||
|
observer.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ prefersReducedMotion ])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Meta
|
||||||
|
as={Head}
|
||||||
|
name="OnBoard"
|
||||||
|
description={`We'll pay manufacturing costs for any high schooler who designs a circuit board.`}
|
||||||
|
image="https://cloud-ji9c1qxfx-hack-club-bot.vercel.app/03_card.png"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style>{`
|
||||||
|
@import url('${stickerButtonFontStylesheet}');
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Phantom Sans';
|
||||||
|
src: url('https://assets.hackclub.com/fonts/Phantom_Sans_0.7/Med.woff')
|
||||||
|
format('woff'),
|
||||||
|
url('https://assets.hackclub.com/fonts/Phantom_Sans_0.7/Med.woff2')
|
||||||
|
format('woff2');
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
|
||||||
|
<Head>
|
||||||
|
<link rel="preload" href={wandImgRendered} as="image" />
|
||||||
|
</Head>
|
||||||
|
|
||||||
|
<Nav />
|
||||||
|
|
||||||
|
<Box
|
||||||
|
as="header"
|
||||||
|
sx={{
|
||||||
|
bg: '#000000',
|
||||||
|
backgroundImage: `
|
||||||
|
linear-gradient(rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.75)),
|
||||||
|
url('https://cloud-dst3a9oz5-hack-club-bot.vercel.app/0image.png')
|
||||||
|
`,
|
||||||
|
color: '#ffffff',
|
||||||
|
position: 'relative'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
ref={spotlightRef}
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: 2,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
bg: '#000000',
|
||||||
|
pointerEvents: 'none'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Flex sx={{ p: 4, flexDirection: 'column', alignItems: 'center', zIndex: 5, position: 'relative' }}>
|
||||||
|
<Flex sx={{ pt: 80, width: '100%', maxWidth: 'layout', alignItems: 'center' }}>
|
||||||
|
<Flex sx={{ flex: 1, flexDirection: 'column', gap: 25 }}>
|
||||||
|
<Heading
|
||||||
|
as="h1"
|
||||||
|
sx={{
|
||||||
|
fontSize: 80,
|
||||||
|
maxWidth: 'copyPlus',
|
||||||
|
textShadow: '0 0 30px rgba(42, 252, 88, 0.6)',
|
||||||
|
color: '#87ffa1'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Balancer ratio={.3}>OnBoard</Balancer>
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Heading as="div" sx={{ fontSize: 4, fontWeight: 400, maxWidth: 'copyPlus' }}>
|
||||||
|
<Balancer ratio={.3}>
|
||||||
|
Circuit boards are <Sparkles><Text sx={{ fontWeight: 400 }}>magical</Text></Sparkles>.{' '}
|
||||||
|
You design one, we'll print it!
|
||||||
|
</Balancer>
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Box sx={{ mt: 16 }}>
|
||||||
|
<Button variant="ctaLg" as="a" href="#apply">
|
||||||
|
How do I apply?
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Box sx={{ flex: 1, maxWidth: 230}}>
|
||||||
|
<FadeIn duration={800} delay={100}>
|
||||||
|
<Image
|
||||||
|
src={wandImg}
|
||||||
|
alt='A circuit board of a dino wizard with a light up wand.'
|
||||||
|
/>
|
||||||
|
</FadeIn>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Heading as="h2" sx={{ pt: 60, pb: 35, fontSize: 36, fontWeight: 500, maxWidth: 'copy', textAlign: 'center' }}>
|
||||||
|
<Balancer ratio={.6}>Join 1,000 others to create your own circuit board.</Balancer>
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Grid width={300} gap={4} sx={{ fontSize: 2, h3: { fontSize: 2 }, width: '100%', maxWidth: 'layout', pb: 40 }}>
|
||||||
|
<Flex as="article" sx={{ flexDirection: 'column', gap: 2 }}>
|
||||||
|
<Text as="h3">Community & Friends</Text>
|
||||||
|
<Text as="p">
|
||||||
|
Share your progress and ask for help with Hack Club teens who are designing their own circuit boards.
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex as="article" sx={{ flexDirection: 'column', gap: 2 }}>
|
||||||
|
<Text as="h3">Free Manufacturing</Text>
|
||||||
|
<Text as="p">
|
||||||
|
We’ll pay $100 to cover manufacturing costs, enough for 2-3 iterations of your design.
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Grid>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Flex as="section" sx={{ overflowX: 'hidden', px: 4, py: 5, bg: dimBg, color: '#ffffff', justifyContent: 'center' }}>
|
||||||
|
<Flex sx={{ flexDirection: 'column', alignItems: 'center', gap: 4, width: '100%', maxWidth: 'copyPlus' }}>
|
||||||
|
<Heading as="h2" sx={{ fontSize: 36, fontWeight: 500, textAlign: 'center' }}>
|
||||||
|
<Balancer>What have people made already?</Balancer>
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
width={350}
|
||||||
|
gap={3}
|
||||||
|
sx={{
|
||||||
|
width: '100%',
|
||||||
|
fontSize: 2,
|
||||||
|
a: {
|
||||||
|
display: 'block',
|
||||||
|
position: 'relative',
|
||||||
|
bg: '#000000',
|
||||||
|
borderRadius: 'default',
|
||||||
|
px: 3,
|
||||||
|
py: 4,
|
||||||
|
color: 'inherit',
|
||||||
|
textDecoration: 'inherit',
|
||||||
|
'.arrow': {
|
||||||
|
position: 'relative',
|
||||||
|
left: '0px',
|
||||||
|
top: '1px', // Looks more aligned with text.
|
||||||
|
display: 'inline-block',
|
||||||
|
transition: 'left 80ms ease-in'
|
||||||
|
},
|
||||||
|
'&:hover .arrow': {
|
||||||
|
left: '4px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
article: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 3,
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: '100%',
|
||||||
|
zIndex: 1
|
||||||
|
},
|
||||||
|
img: {
|
||||||
|
pointerEvents: 'none',
|
||||||
|
zIndex: 2
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<a href="https://github.com/maggie-j-liu/orpheus-keychain" target="_blank">
|
||||||
|
<Flex as="article">
|
||||||
|
<Text as="p" sx={{ pr: 80 }}>
|
||||||
|
Make a <strong>keychain</strong> that has a <strong>light up dino</strong> on it.
|
||||||
|
</Text>
|
||||||
|
<Text as="p" sx={{ pr: 100, color: 'gray' }}>
|
||||||
|
See Maggie's designs <span className="arrow">→</span>
|
||||||
|
</Text>
|
||||||
|
<Image
|
||||||
|
src='https://cloud-ahzzebs4i-hack-club-bot.vercel.app/0frame_1.png'
|
||||||
|
alt='A circuit board of a dino wizard with a light up wand, the same image from the top of the page.'
|
||||||
|
sx={{
|
||||||
|
maxWidth: 120,
|
||||||
|
position: 'absolute',
|
||||||
|
top: 10,
|
||||||
|
right: 15
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://github.com/hackclub/sprig-hardware" target="_blank">
|
||||||
|
<Flex as="article">
|
||||||
|
<Text as="p" sx={{ pr: 100 }}>
|
||||||
|
Design a <strong>movement sensor</strong> add-on to an open source <strong>game console</strong>.
|
||||||
|
</Text>
|
||||||
|
<Text as="p" sx={{ pr: 140, color: 'gray' }}>
|
||||||
|
Read the source <span className="arrow">→</span>
|
||||||
|
</Text>
|
||||||
|
<Image
|
||||||
|
src='https://cloud-6exi6bz1i-hack-club-bot.vercel.app/0rotatesprig.png'
|
||||||
|
alt='A black circuit board for a game console with copper wiring.'
|
||||||
|
sx={{
|
||||||
|
maxWidth: 280,
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: -50,
|
||||||
|
right: -75
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://github.com/Hugoyhu/Hack-Club-Zephyr-USB-Hub" target="_blank">
|
||||||
|
<Flex as="article">
|
||||||
|
<Text as="p" sx={{ pr: [ 100, 100, 100, 0 ] }}>
|
||||||
|
Make a <strong>USB-C hub</strong> for the best <strong>hackathon swag</strong> ever.
|
||||||
|
</Text>
|
||||||
|
<Text as="p" sx={{ color: 'gray', pr: 150 }}>
|
||||||
|
Build one for your event <span className="arrow">→</span>
|
||||||
|
</Text>
|
||||||
|
<Image
|
||||||
|
src='https://cloud-c953eezuq-hack-club-bot.vercel.app/0hub.png'
|
||||||
|
alt='A rectangular circuit board in the shape of a train car that acts as a USB type C hub.'
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
right: -15,
|
||||||
|
bottom: -10,
|
||||||
|
maxWidth: 260,
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: 6
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://github.com/maggie-j-liu/macropad" target="_blank">
|
||||||
|
<Flex as="article">
|
||||||
|
<Text as="p" sx={{ pr: 170 }}>
|
||||||
|
Come up with your own custom <strong>keyboard layout</strong>.
|
||||||
|
</Text>
|
||||||
|
<Text as="p" sx={{ pr: 140, color: 'gray' }}>
|
||||||
|
Check it out <span className="arrow">→</span>
|
||||||
|
</Text>
|
||||||
|
<Image
|
||||||
|
src='https://cloud-8yyfro2sg-hack-club-bot.vercel.app/0keyboard.png'
|
||||||
|
alt='A 3-key custom keyboard with colored glowing translucent keys.'
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
right: -20,
|
||||||
|
maxWidth: 230
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</a>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Button variant="outlineLg" as="a" href="https://github.com/hackclub/OnBoard/blob/main/DIRECTIONS.md" target="_blank">
|
||||||
|
Join the Party
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{/* <Flex as="section" sx={{ px: 4, pt: 4, pb: 5, bg: dimBg, color: '#ffffff', justifyContent: 'center' }}>
|
||||||
|
<Flex sx={{ flexDirection: 'column', gap: 4, width: '100%', maxWidth: 'copyPlus' }}>
|
||||||
|
<Heading as="h2" sx={{ fontSize: 42, fontWeight: 500 }}>
|
||||||
|
<Balancer ratio={0.3}>Never made a circuit board before? No problem.</Balancer>
|
||||||
|
</Heading>
|
||||||
|
<Text sx={{ fontSize: 3 }}>
|
||||||
|
Learn from tutorials like Maggie’s intro to PCB design video below. Ask in the{' '}
|
||||||
|
<Link href={slackLink} target="_blank">Hack Club Slack</Link>{' '}
|
||||||
|
if you have any questions!
|
||||||
|
</Text>
|
||||||
|
<iframe
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
maxWidth: 600,
|
||||||
|
alignSelf: 'center',
|
||||||
|
aspectRatio: '16 / 9'
|
||||||
|
}}
|
||||||
|
src="https://www.youtube.com/embed/PnK4gzO6S3Q"
|
||||||
|
title="YouTube video player"
|
||||||
|
frameborder="0"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
allowfullscreen
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Flex> */}
|
||||||
|
|
||||||
|
<Flex as="section" id="apply" sx={{ px: 4, pt: 5, bg: '#ffffff', color: '#000000', justifyContent: 'center' }}>
|
||||||
|
<Flex as="section" sx={{ flexDirection: 'column', gap: 4, width: '100%', maxWidth: 'layout' }} ref={containerRef}>
|
||||||
|
<Heading as="h2" sx={{ fontSize: 5, fontWeight: 500, textAlign: 'center' }}>
|
||||||
|
How to Qualify
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Flex>
|
||||||
|
<Box sx={{
|
||||||
|
...traceSx,
|
||||||
|
alignSelf: 'flex-end',
|
||||||
|
height: busHeight
|
||||||
|
}} ref={busRef} />
|
||||||
|
|
||||||
|
<Flex sx={{
|
||||||
|
flexDirection: [ 'column', 'column', 'row' ],
|
||||||
|
flex: 1,
|
||||||
|
gap: 5,
|
||||||
|
pb: 5
|
||||||
|
}}>
|
||||||
|
<Flex
|
||||||
|
as="ul"
|
||||||
|
sx={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
fontSize: 24,
|
||||||
|
listStyleType: 'none',
|
||||||
|
gap: 4,
|
||||||
|
flex: 1,
|
||||||
|
p: 0
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
(<><strong>Design a PCB</strong> using any tool that can export Gerber files.</>),
|
||||||
|
(<><strong>Upload your design</strong> to JLCPCB and take a screenshot.</>),
|
||||||
|
(<>
|
||||||
|
<strong>Open source your design</strong> on GitHub and{' '}
|
||||||
|
<Link href="https://github.com/hackclub/OnBoard/blob/main/DIRECTIONS.md" target="_blank">apply for the grant</Link>!{' '}
|
||||||
|
You must be a teenager in high school to apply.
|
||||||
|
</>)
|
||||||
|
].map((text, i) => (
|
||||||
|
<Text as="li" key={i} sx={{ display: 'flex', alignItems: 'center', position: 'relative' }}>
|
||||||
|
<Box sx={{
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
borderWidth: traceSx.width,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: traceSx.bg,
|
||||||
|
borderRadius: '50%',
|
||||||
|
left: t => -60,
|
||||||
|
position: 'absolute'
|
||||||
|
}}>
|
||||||
|
<Box
|
||||||
|
ref={i === 0 ? connectorRef : null}
|
||||||
|
sx={{
|
||||||
|
// Yeah, yeah, it's a 45-45-90 triangle...
|
||||||
|
// I'm too lazy to do math though, so I'm hardcoding
|
||||||
|
// coords until there's actually a problem.
|
||||||
|
width: traceSx.width,
|
||||||
|
height: 69,
|
||||||
|
bg: traceSx.bg,
|
||||||
|
position: 'absolute',
|
||||||
|
transform: 'rotate(45deg)',
|
||||||
|
transformOrigin: 'top right',
|
||||||
|
top: '20.5px',
|
||||||
|
left: '-5px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<span>{text}</span>
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Tilt options={{ scale: 1 }}>
|
||||||
|
<Image
|
||||||
|
src='https://cloud-hy108iezt-hack-club-bot.vercel.app/0dinopcb.png'
|
||||||
|
alt='A complex white circuit board in the shape of a cute leaping dinosaur.'
|
||||||
|
loading='lazy'
|
||||||
|
sx={{
|
||||||
|
flex: 1,
|
||||||
|
maxWidth: 350,
|
||||||
|
objectFit: 'contain',
|
||||||
|
mt: [ '-40px', '-40px', 0 ]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tilt>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex sx={{ px: 4, bg: '#000000', color: '#ffffff', justifyContent: 'center' }}>
|
||||||
|
<Flex as="section" sx={{ width: '100%', maxWidth: 'layout' }}>
|
||||||
|
<Box sx={traceSx}>
|
||||||
|
<Box sx={{
|
||||||
|
height: traceSx.width,
|
||||||
|
width: 40,
|
||||||
|
bg: traceSx.bg,
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
left: -20 + traceSx.width/2
|
||||||
|
}} />
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Flex sx={{ flex: 1, flexDirection: 'column', gap: 4, py: 5 }}>
|
||||||
|
<Heading as="h2" sx={{ fontSize: 36, fontWeight: 500 }}>
|
||||||
|
<Balancer>Join the Hack Club Slack</Balancer>
|
||||||
|
</Heading>
|
||||||
|
<Text as="p" sx={{ fontSize: 24 }}>
|
||||||
|
Meet others learning how to make their own circuit boards. Collaborate, get help, and support others as you take the leap.
|
||||||
|
</Text>
|
||||||
|
<Box sx={{ mt: 1 }}>
|
||||||
|
<Button variant="lg" as="a" href={slackLink} target="_blank">
|
||||||
|
Join the Slack
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex as="section" sx={{ overflowX: 'hidden', px: 4, py: 6, bg: '#000000', color: '#ffffff', justifyContent: 'center' }}>
|
||||||
|
<Flex sx={{ flexDirection: 'column', alignItems: 'center', gap: 5, width: '100%', maxWidth: 'layout' }}>
|
||||||
|
{/* For accessibility and screen readers: */}
|
||||||
|
<Heading as="h2" sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
width: '1px',
|
||||||
|
height: '1px',
|
||||||
|
margin: '-1px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
clip: 'rect(0, 0, 0, 0)',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
borderWidth: 0
|
||||||
|
}}>
|
||||||
|
Let's Recap
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
<Grid ref={lightsScrollTrigger} gap='4px' columns={recapWidth} sx={{ width: '100%', maxWidth: 800 }}>
|
||||||
|
{recapPixels.map((_, i) => (
|
||||||
|
<Box id={`pixel-${i}`} key={i} sx={{ bg: dimBg, paddingTop: '100%' }} />
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
width={300}
|
||||||
|
gap={4}
|
||||||
|
sx={{
|
||||||
|
width: '100%',
|
||||||
|
article: {
|
||||||
|
bg: dimBg,
|
||||||
|
borderRadius: 'default',
|
||||||
|
p: 4,
|
||||||
|
flexDirection: 'column',
|
||||||
|
boxShadow: 'inset 0px 0px 14px rgba(255, 255, 255, 0.15);'
|
||||||
|
},
|
||||||
|
h3: {
|
||||||
|
fontSize: 3,
|
||||||
|
mb: 3
|
||||||
|
},
|
||||||
|
p: {
|
||||||
|
fontSize: 18,
|
||||||
|
pb: 3,
|
||||||
|
mb: '6px'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Flex as="article">
|
||||||
|
<Text as="h3">$100 Grants</Text>
|
||||||
|
<Text as="p">We’ll pay $100 to manufacture your boards, all components included.</Text>
|
||||||
|
<Button variant="outline" as="a" href="https://github.com/hackclub/OnBoard#requirements" target="_blank">
|
||||||
|
Read the Rules
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex as="article">
|
||||||
|
<Text as="h3">Community</Text>
|
||||||
|
<Text as="p">Share progress with fellow participants and ask for help in the Hack Club Slack.</Text>
|
||||||
|
<Button variant="outline" as="a" href={slackLink} target="_blank">
|
||||||
|
Join Slack
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex as="article">
|
||||||
|
<Text as="h3">Free Stickers</Text>
|
||||||
|
<Text as="p">Like stickers? Request below and we'll ship you an envelope full of stickers for free.</Text>
|
||||||
|
<Button variant="outline" as="a" href="https://airtable.com/shrOOU2ZZFYtffUVz" target="_blank">
|
||||||
|
Request Stickers
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{/* <Flex as="article">
|
||||||
|
<Text as="h3">Learn to PCB</Text>
|
||||||
|
<Text as="p">Watch Maggie’s intro video to learn how to make a simple circuit board from start to end.</Text>
|
||||||
|
<Button variant="outline" as="a" href="https://airtable.com/shrOOU2ZZFYtffUVz" target="_blank">
|
||||||
|
Watch Tutorial
|
||||||
|
</Button>
|
||||||
|
</Flex> */}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Flex sx={{ gap: 3, alignItems: 'center', textAlign: 'center', mt: '-16px' }}>
|
||||||
|
<Text sx={{ fontSize: 3 }}>Get started now:</Text>
|
||||||
|
<Button variant="ctaLg" as="a" href={slackLink} target="_blank">Join the Slack</Button>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Box sx={{ position: 'relative' }}>
|
||||||
|
<Image
|
||||||
|
src='https://cloud-f4lij7sq1-hack-club-bot.vercel.app/0flowerpcb.png'
|
||||||
|
alt='A big image of several pink flower-shaped PCBs.'
|
||||||
|
loading='lazy'
|
||||||
|
sx={{
|
||||||
|
display: 'block',
|
||||||
|
width: '100%',
|
||||||
|
height: 500,
|
||||||
|
objectFit: 'cover',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <Flex
|
||||||
|
as="a"
|
||||||
|
href="javascript:void(0)"
|
||||||
|
target="_blank"
|
||||||
|
sx={{
|
||||||
|
bg: '#ff0000',
|
||||||
|
color: '#ffffff',
|
||||||
|
textDecoration: 'none',
|
||||||
|
size: 160,
|
||||||
|
flexDirection: 'column',
|
||||||
|
textAlign: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
position: 'absolute',
|
||||||
|
top: -80,
|
||||||
|
right: '14vw',
|
||||||
|
fontSize: 3,
|
||||||
|
lineHeight: 1.3,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
fontFamily: `'${stickerButtonFont}', cursive`,
|
||||||
|
transform: 'rotate(-25deg)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
boxShadow: '0px 4px 44px rgba(0, 0, 0, 0.55), 0px 0px 10px rgba(0, 0, 0, 0.75), inset 0px 0px 60px rgba(255, 255, 255, 0.40)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{stickerButtonText.split(' ').map((line, i) => <div key={i}>{line}</div>)}
|
||||||
|
</Flex> */}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Footer dark />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ShipPage
|
||||||
|
|
@ -3916,10 +3916,10 @@ react-use-websocket@^4.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-4.3.1.tgz#13cd2fd2e0fb90010482ab2858f8ae81f2ce85c2"
|
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-4.3.1.tgz#13cd2fd2e0fb90010482ab2858f8ae81f2ce85c2"
|
||||||
integrity sha512-zHPLWrgcqydJaak2O5V9hiz4q2dwkwqNQqpgFVmSuPxLZdsZlnDs8DVHy3WtHH+A6ms/8aHIyX7+7ulOcrnR0Q==
|
integrity sha512-zHPLWrgcqydJaak2O5V9hiz4q2dwkwqNQqpgFVmSuPxLZdsZlnDs8DVHy3WtHH+A6ms/8aHIyX7+7ulOcrnR0Q==
|
||||||
|
|
||||||
react-wrap-balancer@^0.4.0:
|
react-wrap-balancer@^0.5.0:
|
||||||
version "0.4.0"
|
version "0.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-wrap-balancer/-/react-wrap-balancer-0.4.0.tgz#1ee2bcee25e2c7524cf69297cb355b79cc5daf08"
|
resolved "https://registry.yarnpkg.com/react-wrap-balancer/-/react-wrap-balancer-0.5.0.tgz#a63b14b6a125c8f15509e6f8be7e2faaae5ad8a9"
|
||||||
integrity sha512-MUsROihHd7bFHCo9kCOifKDYBEZPgKTyGvfa8RcwRQKtT2cL7Um9Cc8A7GvuT8t3np7LAGsEkzdEyJdKrr5lVQ==
|
integrity sha512-5vwe5QDczQ9zwAtv3iEVj8hdMbNwQtM/QlSNLJfDUzRE9noPtxevb+Kon916Mu2RUorCrAtashQ1F9BVBjdeZg==
|
||||||
|
|
||||||
react@^17.0.2:
|
react@^17.0.2:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue