{"version":3,"sources":["webpack:///./src/components/atoms/button/Button.tsx","webpack:///./src/components/atoms/loader/animations.ts","webpack:///./src/components/atoms/loader/Loader.tsx","webpack:///./src/hooks/use-lock-body-scroll/useLockBodyScroll.ts","webpack:///./src/components/molecules/intro-video/IntroVideo.tsx","webpack:///./src/components/atoms/map/animations.ts","webpack:///./src/components/atoms/map/dots.ts","webpack:///./src/components/atoms/map/Map.tsx","webpack:///./src/components/atoms/project-card/animations.ts","webpack:///./src/components/atoms/project-card/ProjectCard.tsx","webpack:///./src/components/pages/HomePage.tsx"],"names":["StyledButton","styled","motion","button","rem","Colors","WHITE","SHIP_GREY","ALTO","Button","className","label","to","props","as","Link","loaderAnimation","left","x","right","StyledLoader","div","Loader","duration","animate","initial","transition","ease","repeat","variants","useLockBodyScroll","useLayoutEffect","document","body","style","overflow","StyledIntroVideo","BLACK","mediaQueries","tablet","Video","video","IntroVideo","dispatch","useAppState","landscapeVideo","portraitVideo","useState","isPlaying","setIsPlaying","isTablet","useBreakPoints","dictionary","useDictionary","videoSource","setVideoSource","videoRef","useRef","current","load","onSkipIntroButtonClick","useCallback","payload","type","Actions","SET_IS_INTRO_VIEWED","onVideoEnded","onVideoIsPlaying","opacity","exit","autoPlay","controls","muted","onEnded","onPlay","playsInline","ref","src","get","onClick","mapAnimation","scale","opacityIn","transformIn","dotAnimation","transformOut","pulseAnimation","repeatType","Infinity","opacityOut","dots","project","y","StyledMapGrid","grid","Wrapper","gridColumnsRoot","desktop","DotWrapper","maxHeight","ratio","Pulse","top","Dot","Map","onHeightChange","activeProject","gridRef","image","useImageData","useWindowSize","windowWidth","windowHeight","isIntroViewed","getMaxHeight","clientHeight","setMaxHeight","wrapperRef","useEffect","newMaxHeight","Math","min","clientWidth","fluid","aspectRatio","imgStyle","objectFit","objectPosition","map","key","projectCardAnimation","StyledProjectCard","section","StyledLink","ImageWrapper","Content","Overlay","StyledTitle","Title","ProjectCard","title","artist","slug","hover","setHover","onHoverStart","onHoverEnd","fixed","width","height","responsiveSizes","TitleSizes","large","size","small","level","xSmall","dangerouslySetInnerHTML","__html","mobileHeaderHeight","mapMargins","projectListAnimation","staggerChildren","delay","StyledHomePage","Grid","ProjectList","mapHeight","HomePage","pageContext","projects","meta","ogImage","og","setMapHeight","stateProjects","hoveredProject","setHoveredProject","onMapHeightChange","Helmet","content","description","name","siteUrl"],"mappings":"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,KAAM,UACN4D,WAAY,OACZ3D,OAAQ4D,MAGZC,WAAY,CACVrB,QAAS,EACT1C,WAAY,CACVH,SAAU,EACVI,KAAM,YCwEG+D,EA/IK,CAClB,CACEC,QAAS,sBACTzE,EAAG,KACH0E,EAAG,IAEL,CACED,QAAS,mBACTzE,EAAG,KACH0E,EAAG,IAEL,CACED,QAAS,cACTzE,EAAG,EACH0E,EAAG,IAEL,CACED,QAAS,YACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,UACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,wBACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,eACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,sBACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,iBACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,6BACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,+BACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,wBACTzE,EAAG,KACH0E,EAAG,KAEL,CACED,QAAS,QACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,WACTzE,EAAG,KACH0E,EAAG,IAEL,CACED,QAAS,cACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,OACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,aACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,iBACTzE,EAAG,EACH0E,EAAG,IAEL,CACED,QAAS,YACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,aACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,OACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,UACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,eACTzE,EAAG,KACH0E,EAAG,IAEL,CACED,QAAS,gBACTzE,EAAG,KACH0E,EAAG,IAEL,CACED,QAAS,OACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,gBACTzE,EAAG,KACH0E,EAAG,MAEL,CACED,QAAS,qBACTzE,EAAG,KACH0E,EAAG,MAEL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","file":"component---src-components-pages-home-page-tsx-5c306aaecd226ac7b29b.js","sourcesContent":["import { HoverHandlers, motion } from 'framer-motion'\nimport React, { FunctionComponent, MouseEvent } from 'react'\nimport Colors from '../../../tokens/Colors'\nimport { Link } from 'gatsby'\nimport { rem } from '../../../utils/rem'\nimport styled from 'styled-components'\n\nexport interface ButtonProps {\n className?: string\n label: string\n onClick?: (event: MouseEvent) => void\n onHoverEnd?: HoverHandlers['onHoverEnd']\n onHoverStart?: HoverHandlers['onHoverStart']\n to?: string\n}\n\nconst Button: FunctionComponent = ({\n className,\n label,\n to,\n ...props\n}) =>\n to ? (\n \n {label}\n \n ) : (\n \n {label}\n \n )\n\nconst StyledButton = styled(motion.button)`\n font-size: ${rem(15)};\n font-weight: 700;\n background: ${Colors.WHITE};\n text-decoration: none;\n color: ${Colors.SHIP_GREY};\n padding: 0 ${rem(24)};\n line-height: ${rem(40)};\n height: ${rem(40)};\n border-radius: ${rem(20)};\n display: inline-block;\n transition: background 200ms ease-out;\n border: none;\n cursor: pointer;\n outline: none;\n\n &:hover {\n transition: background 200ms ease-in;\n background: ${Colors.ALTO};\n }\n\n .hide-cursor & {\n cursor: none;\n }\n`\n\nexport default Button\n","export const loaderAnimation = {\n left: {\n x: '-100%',\n },\n right: {\n x: '100%',\n },\n}\n","import React, { FunctionComponent } from 'react'\nimport Colors from '../../../tokens/Colors'\nimport { loaderAnimation } from './animations'\nimport { motion } from 'framer-motion'\nimport { rem } from '../../../utils/rem'\nimport styled from 'styled-components'\n\ninterface LoaderProps {\n className?: string\n duration?: number\n}\n\nconst Loader: FunctionComponent = ({\n className,\n duration = 6,\n}) => (\n \n)\n\nconst StyledLoader = styled(motion.div)`\n width: 100%;\n height: ${rem(3)};\n background-color: ${Colors.WHITE};\n`\n\nexport default Loader\n","// Hook\nimport { useLayoutEffect } from 'react'\n\n// https://usehooks.com/useLockBodyScroll/\nconst useLockBodyScroll = (): void => {\n useLayoutEffect((): (() => void) => {\n // Prevent scrolling on mount\n document.body.style.overflow = 'hidden'\n // Re-enable scrolling when component unmounts\n return (): void => {\n document.body.style.overflow = ''\n }\n }, []) // Empty array ensures effect is only run on mount and unmount\n}\n\nexport default useLockBodyScroll\n","import React, {\n FunctionComponent,\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react'\nimport { Actions } from '../../../contexts/app-state/AppStateReducer'\nimport Button from '../../atoms/button/Button'\nimport Colors from '../../../tokens/Colors'\nimport Loader from '../../atoms/loader/Loader'\nimport { mediaQueries } from '../../../utils/mediaQueries'\nimport { motion } from 'framer-motion'\nimport { rem } from '../../../utils/rem'\nimport styled from 'styled-components'\nimport { useAppState } from '../../../contexts/app-state/AppStateContext'\nimport useBreakPoints from '../../../hooks/use-breakpoints/useBreakPoints'\nimport useDictionary from '../../../hooks/use-dictionary/useDictionary'\nimport useLockBodyScroll from '../../../hooks/use-lock-body-scroll/useLockBodyScroll'\n\ninterface IntroVideoProps {\n className?: string\n}\n\nconst IntroVideo: FunctionComponent = ({ className }) => {\n const [, dispatch] = useAppState()\n const landscapeVideo =\n 'https://player.vimeo.com/external/449631314.hd.mp4?s=b4194e7d4c1c20b6f36bce98258d79b9f1e2284d&profile_id=175'\n const portraitVideo =\n 'https://player.vimeo.com/external/449631284.hd.mp4?s=e8c1c0c01ab43c861dd26d94c23089e96e83ecdf&profile_id=175'\n const [isPlaying, setIsPlaying] = useState(false)\n const { isTablet } = useBreakPoints()\n const dictionary = useDictionary()\n const [videoSource, setVideoSource] = useState(landscapeVideo)\n\n useLockBodyScroll()\n\n /**\n * Video reference.\n */\n const videoRef = useRef(null)\n\n /*\n * Set video source based on breakpoint\n * */\n useLayoutEffect(() => {\n if (videoRef.current) {\n setVideoSource(isTablet ? landscapeVideo : portraitVideo)\n videoRef.current.load()\n }\n }, [isTablet, videoRef, landscapeVideo, portraitVideo])\n\n const onSkipIntroButtonClick = useCallback((): void => {\n dispatch({\n payload: true,\n type: Actions.SET_IS_INTRO_VIEWED,\n })\n }, [dispatch])\n\n const onVideoEnded = useCallback((): void => {\n dispatch({\n payload: true,\n type: Actions.SET_IS_INTRO_VIEWED,\n })\n }, [dispatch])\n\n const onVideoIsPlaying = useCallback(() => {\n setIsPlaying(true)\n }, [])\n\n return (\n \n \n \n \n \n {!isPlaying && }\n \n )\n}\n\nconst StyledIntroVideo = styled(motion.div)`\n background: ${Colors.BLACK};\n position: fixed;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n`\n\nconst StyledLoader = styled(Loader)`\n position: absolute;\n top: 0;\n left: 0;\n`\n\nconst StyledButton = styled(Button)`\n margin-bottom: ${rem(32)};\n position: relative;\n\n ${mediaQueries.tablet} {\n margin-bottom: ${rem(40)};\n }\n`\n\nconst Video = styled.video`\n object-fit: cover;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100%;\n height: 100%;\n`\n\nexport default IntroVideo\n","import { Variants } from 'framer-motion'\n\nexport const mapAnimation: Variants = {\n initial: {\n scale: 1.1,\n opacity: 0,\n },\n opacityIn: {\n opacity: 1,\n transition: {\n duration: 0.17,\n ease: 'linear',\n },\n },\n transformIn: {\n scale: 1,\n transition: {\n duration: 0.3,\n ease: 'linear',\n },\n },\n}\n\nexport const dotAnimation: Variants = {\n initial: {\n scale: 1,\n },\n\n transformIn: {\n scale: 2,\n transition: {\n duration: 0.5,\n ease: 'easeOut',\n },\n },\n transformOut: {\n scale: 1,\n transition: {\n duration: 0.5,\n ease: 'easeIn',\n },\n },\n}\n\nexport const pulseAnimation: Variants = {\n initial: {\n scale: 0,\n },\n transformIn: {\n scale: 5,\n transition: {\n duration: 2,\n ease: 'easeOut',\n repeatType: 'loop',\n repeat: Infinity,\n },\n },\n transformOut: {\n scale: 0,\n transition: {\n duration: 1,\n ease: 'easeIn',\n },\n },\n opacityIn: {\n opacity: [1, 0],\n transition: {\n duration: 2,\n ease: 'easeOut',\n repeatType: 'loop',\n repeat: Infinity,\n },\n },\n opacityOut: {\n opacity: 0,\n transition: {\n duration: 1,\n ease: 'easeIn',\n },\n },\n}\n","export interface Dot {\n project: string\n x: number\n y: number\n}\n\nconst dots: Dot[] = [\n {\n project: 'conversation-series',\n x: 52.1,\n y: 30,\n },\n {\n project: 'internal-windows',\n x: 37.8,\n y: 73,\n },\n {\n project: 'ofset-chair',\n x: 0,\n y: 48,\n },\n {\n project: 'seat-prop',\n x: 89.7,\n y: 12.2,\n },\n {\n project: 'garment',\n x: 52.1,\n y: 50.8,\n },\n {\n project: 'blue-velvet-colonnade',\n x: 59.9,\n y: 24.4,\n },\n {\n project: 'interpersona',\n x: 79.7,\n y: 23.2,\n },\n {\n project: 'duct-taped-blankets',\n x: 23.7,\n y: 57.2,\n },\n {\n project: 'chroma-columns',\n x: 31.1,\n y: 28.5,\n },\n {\n project: 'an-alternative-sample-room',\n x: 23.5,\n y: 39.4,\n },\n {\n project: 'doric-columns-kinetic-object',\n x: 89.7,\n y: 12.2,\n },\n {\n project: 'a-softly-winded-chair',\n x: 99.1,\n y: 7.9,\n },\n {\n project: 'strap',\n x: 10.3,\n y: 72.3,\n },\n {\n project: 'coalesce',\n x: 99.1,\n y: 11,\n },\n {\n project: 'living-room',\n x: 61.3,\n y: 19.7,\n },\n {\n project: 'shed',\n x: 64.4,\n y: 24.4,\n },\n {\n project: 'salamandre',\n x: 47.5,\n y: 10.5,\n },\n {\n project: 'if-i-had-wings',\n x: 0,\n y: 22,\n },\n {\n project: 'wave-zero',\n x: 61.3,\n y: 13.7,\n },\n {\n project: 'dressed-up',\n x: 33.4,\n y: 28.5,\n },\n {\n project: 'bola',\n x: 42.8,\n y: 28.5,\n },\n {\n project: 'sundays',\n x: 89.7,\n y: 12.2,\n },\n {\n project: 'bumpy-basket',\n x: 42.8,\n y: 85,\n },\n {\n project: 'knit-together',\n x: 78.3,\n y: 10,\n },\n {\n project: 'berg',\n x: 39.9,\n y: 43.9,\n },\n {\n project: 'hammock-chair',\n x: 47.5,\n y: 10.5,\n },\n {\n project: 'a-trifle-of-colour',\n x: 61.3,\n y: 19.7,\n },\n {\n project: 'orillon',\n x: 61.3,\n y: 28,\n },\n]\n\nexport default dots\n","import { dotAnimation, mapAnimation, pulseAnimation } from './animations'\nimport { grid, gridColumnsRoot } from '../../../utils/grid'\nimport React, {\n Fragment,\n FunctionComponent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport Colors from '../../../tokens/Colors'\nimport dots from './dots'\nimport Img from 'gatsby-image'\nimport { mediaQueries } from '../../../utils/mediaQueries'\nimport { motion } from 'framer-motion'\nimport { rem } from '../../../utils/rem'\nimport styled from 'styled-components'\nimport { useAppState } from '../../../contexts/app-state/AppStateContext'\nimport useImageData from '../../../hooks/use-image-data/useImageData'\nimport useWindowSize from '../../../hooks/use-window-size/useWindowSize'\n\ninterface MapProps {\n activeProject: string | null\n className?: string\n onHeightChange?: (height: number) => void\n}\n\nconst Map: FunctionComponent = ({\n className,\n onHeightChange,\n activeProject,\n}) => {\n const gridRef = useRef(null)\n const image = useImageData('map.jpg')\n const [windowWidth, windowHeight] = useWindowSize()\n const [{ isIntroViewed }] = useAppState()\n\n const getMaxHeight = useCallback(() => {\n if (gridRef.current) {\n return gridRef.current.clientHeight\n }\n\n return null\n }, [windowHeight, windowWidth, gridRef.current])\n\n const [maxHeight, setMaxHeight] = useState(getMaxHeight())\n const wrapperRef = useRef(null)\n\n useEffect(() => {\n if (wrapperRef.current && image) {\n const newMaxHeight = getMaxHeight() || 0\n\n onHeightChange &&\n onHeightChange(\n Math.min(\n newMaxHeight,\n wrapperRef.current.clientWidth / image.fluid.aspectRatio,\n ),\n )\n setMaxHeight(newMaxHeight)\n }\n }, [image, windowHeight, windowWidth, wrapperRef])\n\n return (\n \n \n {image && (\n \n )}\n {image && (\n \n {dots.map(({ project, x, y }) => (\n \n \n \n \n ))}\n \n )}\n \n \n )\n}\n\nconst StyledMapGrid = styled.div`\n ${grid()};\n background: ${Colors.BLACK};\n position: fixed;\n width: 100%;\n height: 100%;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n overflow: hidden;\n margin: ${rem(32)} 0 0;\n box-sizing: border-box;\n padding-top: ${rem(64)};\n\n ${mediaQueries.tablet} {\n align-items: center;\n height: calc(100vh - ${rem(152)});\n padding-top: 0;\n top: 0;\n transform: translate(-50%, 0);\n margin: ${rem(120)} 0 0;\n }\n`\n\nconst Wrapper = styled(motion.div)`\n position: relative;\n grid-column: 1 / span ${gridColumnsRoot};\n height: fit-content;\n\n ${mediaQueries.tablet} {\n grid-column: 1 / span 5;\n }\n\n ${mediaQueries.desktop} {\n grid-column: 1 / span 11;\n }\n`\n\ninterface DotWrapperProps {\n maxHeight: number | null\n ratio: number\n}\n\nconst DotWrapper = styled.div`\n position: absolute;\n width: 100%;\n height: 100%;\n max-width: ${({ maxHeight, ratio }): string =>\n maxHeight ? rem(maxHeight * ratio) : '100%'};\n top: 0;\n left: 0;\n`\n\ninterface PulseProps {\n left: number\n top: number\n}\n\nconst Pulse = styled(motion.div)`\n width: ${rem(8)};\n height: ${rem(8)};\n border-radius: ${rem(4)};\n background: ${Colors.WHITE};\n position: absolute;\n top: ${({ top }): string => `${top}%`};\n left: ${({ left }): string => `${left}%`};\n`\n\ninterface DotProps {\n left: number\n top: number\n}\n\nconst Dot = styled(motion.div)`\n width: ${rem(8)};\n height: ${rem(8)};\n border-radius: ${rem(4)};\n background: ${Colors.WHITE};\n position: absolute;\n top: ${({ top }): string => `${top}%`};\n left: ${({ left }): string => `${left}%`};\n`\n\nexport default Map\n","export const projectCardAnimation = {\n initial: {\n opacity: 0,\n y: 80,\n },\n opacityIn: {\n opacity: 1,\n transition: {\n duration: 0.27,\n ease: 'linear',\n },\n },\n transformIn: {\n y: 0,\n transition: {\n duration: 0.27,\n ease: 'easeInOut',\n },\n },\n opacityOut: {\n opacity: 0,\n transition: {\n duration: 0.27,\n ease: 'linear',\n },\n },\n transformOut: {\n y: 80,\n transition: {\n duration: 0.27,\n ease: 'easeInOut',\n },\n },\n}\n","import React, { FunctionComponent, useCallback, useState } from 'react'\nimport Title, { TitleProps, TitleSizes } from '../title/Title'\nimport Colors from '../../../tokens/Colors'\nimport { ImageNodeData } from '../../../contexts/images/ImagesContext'\nimport Img from 'gatsby-image'\nimport { Link } from 'gatsby'\nimport { mediaQueries } from '../../../utils/mediaQueries'\nimport { motion } from 'framer-motion'\nimport { rem } from '../../../utils/rem'\nimport styled from 'styled-components'\nimport useImageData from '../../../hooks/use-image-data/useImageData'\nimport { projectCardAnimation } from './animations'\n\ninterface ProjectCardProps {\n artist: string\n className?: string\n onHoverEnd?: () => void\n onHoverStart?: () => void\n slug: string\n title: string\n}\n\nconst ProjectCard: FunctionComponent = ({\n className,\n title,\n artist,\n slug,\n ...props\n}) => {\n const [hover, setHover] = useState(false)\n const image = useImageData(`cards/${slug}.jpg`) as ImageNodeData\n\n const onHoverStart = useCallback((): void => {\n props.onHoverStart && props.onHoverStart()\n setHover(true)\n }, [])\n\n const onHoverEnd = useCallback((): void => {\n props.onHoverEnd && props.onHoverEnd()\n setHover(false)\n }, [])\n\n return (\n \n \n {image && (\n \n {image.fixed && (\n \n )}\n \n )}\n \n \n \n {title}\n \n \n \n \n \n \n \n )\n}\n\nconst StyledProjectCard = styled(motion.section)`\n background: ${Colors.SHIP_GREY};\n margin: 0 ${rem(-16)} ${rem(16)};\n height: ${rem(200)};\n display: flex;\n overflow: hidden;\n position: relative;\n\n ${mediaQueries.tablet} {\n margin: 0 0 ${rem(16)};\n }\n\n ${mediaQueries.desktop} {\n height: ${rem(224)};\n }\n`\n\nconst StyledLink = styled(Link)`\n flex: 1;\n text-decoration: none;\n width: 100%;\n`\n\nconst ImageWrapper = styled(motion.div)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n`\n\nconst Content = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n padding: ${rem(16)};\n\n ${mediaQueries.desktop} {\n padding: ${rem(24)};\n }\n`\n\nconst Overlay = styled(motion.div)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: ${Colors.BLACK};\n opacity: 0.2;\n`\n\nconst StyledTitle = styled(Title)`\n color: ${Colors.WHITE};\n\n ${mediaQueries.desktop} {\n margin: 0 0 ${rem(4)};\n }\n`\n\nexport default ProjectCard\n","import { AnimatePresence, motion } from 'framer-motion'\nimport { grid, gridColumnsRoot } from '../../utils/grid'\nimport React, { FunctionComponent, useCallback, useState } from 'react'\nimport Colors from '../../tokens/Colors'\nimport { Helmet } from 'react-helmet'\nimport IntroVideo from '../molecules/intro-video/IntroVideo'\nimport Map from '../atoms/map/Map'\nimport { mediaQueries } from '../../utils/mediaQueries'\nimport MetaData from '../../types/MetaData'\nimport ProjectCard from '../atoms/project-card/ProjectCard'\nimport { ProjectProps } from './ProjectPage'\nimport { rem } from '../../utils/rem'\nimport styled from 'styled-components'\nimport { useAppState } from '../../contexts/app-state/AppStateContext'\nimport useImageData from '../../hooks/use-image-data/useImageData'\n\ninterface PageProps {\n pageContext: {\n meta: MetaData\n projects: ProjectProps[]\n route: string\n }\n}\n\nexport const mobileHeaderHeight = 64\nexport const mapMargins = 2 * 32\n\nconst projectListAnimation = {\n opacityIn: {\n transition: {\n staggerChildren: 0.1,\n delay: 0.3,\n },\n },\n transformIn: {\n transition: {\n staggerChildren: 0.1,\n delay: 0.13,\n },\n },\n}\n\nconst HomePage: FunctionComponent = ({ pageContext }) => {\n const { projects, meta } = pageContext\n const ogImage = useImageData(meta.og?.image)\n const [mapHeight, setMapHeight] = useState(0)\n const [{ isIntroViewed, projects: stateProjects }] = useAppState()\n const [hoveredProject, setHoveredProject] = useState(null)\n\n const onMapHeightChange = useCallback((height: number) => {\n setMapHeight(height)\n }, [])\n\n return (\n \n \n {meta.title}\n \n \n \n {ogImage?.fixed?.src && (\n \n )}\n \n \n \n {isIntroViewed ? (\n \n {(stateProjects || projects).map((project) => (\n setHoveredProject(null)}\n onHoverStart={(): void => setHoveredProject(project.slug)}\n />\n ))}\n \n ) : (\n projects.map((project) => (\n \n ))\n )}\n \n {!isIntroViewed && }\n \n )\n}\n\nconst StyledHomePage = styled.div`\n background: ${Colors.BLACK};\n min-height: 100vh;\n`\n\nconst Grid = styled.div`\n ${grid()};\n position: relative;\n padding-top: ${rem(mobileHeaderHeight)};\n\n ${mediaQueries.tablet} {\n padding-top: ${rem(72)};\n }\n\n ${mediaQueries.desktop} {\n padding-top: ${rem(80)};\n }\n`\n\ninterface ProjectListProps {\n mapHeight: number\n}\n\nconst ProjectList = styled(motion.div)`\n grid-column: 1 / span ${gridColumnsRoot};\n width: 100%;\n padding-top: ${({ mapHeight }): string => rem(mapHeight + mapMargins)};\n\n ${mediaQueries.tablet} {\n grid-column: -5 / span 4;\n padding-top: ${rem(32)};\n }\n\n ${mediaQueries.desktop} {\n grid-column: -6 / span 5;\n padding-top: ${rem(40)};\n }\n`\n\nexport default HomePage\n"],"sourceRoot":""}