{"version":3,"file":"static/chunks/95813-3c5bde5b63a46bf6.js","mappings":"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","sources":["webpack://_N_E/./src/components/ButtonPoofy/ButtonPoofy.tsx","webpack://_N_E/./src/components/ButtonPoofy/index.ts","webpack://_N_E/./src/components/ButtonRainbow/use-rainbow.hook.ts","webpack://_N_E/./src/components/ButtonRainbow/ButtonRainbow.tsx","webpack://_N_E/./src/components/ButtonRainbow/index.ts","webpack://_N_E/./src/components/List/List.tsx","webpack://_N_E/./src/components/Paragraph/Paragraph.tsx","webpack://_N_E/./src/components/Paragraph/index.ts","webpack://_N_E/./src/components/ConfettiGeyser/index.ts","webpack://_N_E/./src/components/SubscribeGeyser/SubscribeGeyser.tsx","webpack://_N_E/./src/components/SubscribeGeyser/index.ts","webpack://_N_E/./src/hooks/use-on-scroll.ts","webpack://_N_E/./src/components/VideoGif/VideoGif.tsx","webpack://_N_E/./src/helpers/browser.helpers.ts","webpack://_N_E/./src/hooks/use-browser.ts","webpack://_N_E/./src/hooks/use-incrementing-number.ts","webpack://_N_E/./src/hooks/use-is-onscreen.ts","webpack://_N_E/./src/hooks/use-window-dimensions.ts","webpack://_N_E/./src/components/ButtonPoofy/ButtonPoofy.linaria.module.css","webpack://_N_E/./src/components/ButtonRainbow/ButtonRainbow.linaria.module.css","webpack://_N_E/./src/components/List/List.linaria.module.css","webpack://_N_E/./src/components/Paragraph/Paragraph.linaria.module.css","webpack://_N_E/./src/components/Spicy/Spicy.linaria.module.css","webpack://_N_E/./src/components/VideoGif/VideoGif.linaria.module.css"],"sourcesContent":["import * as React from 'react';\nimport { styled } from '@linaria/react';\n\nfunction ButtonPoofy({\n children,\n ...delegated\n}: React.HTMLAttributes) {\n return (\n \n );\n}\n\nconst Button = styled.button`\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n border-radius: 6px;\n color: white;\n font-weight: var(--font-weight-medium);\n font-size: 1.125rem;\n text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.15);\n background: linear-gradient(\n 15deg,\n var(--poofy-dark, hsl(210deg 30% 10%)),\n var(--poofy-light, hsl(250deg 40% 35%))\n );\n\n &:focus-visible {\n outline-color: var(--color-primary);\n outline-offset: 4px;\n }\n\n &:disabled,\n &[data-disabled='true'] {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n &:before {\n content: '';\n position: absolute;\n z-index: 1;\n top: 2px;\n left: 6px;\n right: 6px;\n height: 20%;\n background: linear-gradient(\n hsl(0deg 0% 100% / 0.3),\n hsl(0deg 0% 100% / 0)\n );\n border-radius: 20px;\n border-top-left-radius: 20px 14px;\n border-bottom-left-radius: 100px 30px;\n border-top-right-radius: 20px 14px;\n border-bottom-right-radius: 100px 30px;\n pointer-events: none;\n }\n\n &:after {\n content: '';\n position: absolute;\n z-index: 1;\n bottom: 0px;\n left: 0;\n right: 0;\n height: 30%;\n background: linear-gradient(\n hsl(0deg 0% 0% / 0),\n hsl(0deg 0% 0% / 0.17)\n );\n border-radius: 0px 0px 4px 4px;\n pointer-events: none;\n }\n\n &:active {\n filter: brightness(90%);\n }\n\n &:active:before {\n top: 0;\n left: 0;\n right: 0;\n height: 30%;\n background: linear-gradient(\n hsl(0deg 0% 0% / 0.17),\n hsl(0deg 0% 0% / 0)\n );\n border-radius: 4px 4px 0px 0px;\n }\n\n &:active:after {\n top: revert;\n left: 2px;\n right: 2px;\n bottom: 2px;\n height: 20%;\n background: linear-gradient(\n hsl(0deg 0% 100% / 0),\n hsl(0deg 0% 100% / 0.3)\n );\n border-radius: 20px;\n border-bottom-left-radius: 10px 14px;\n border-top-left-radius: 100px 30px;\n border-bottom-right-radius: 10px 14px;\n border-top-right-radius: 100px 30px;\n }\n`;\n\nconst ButtonContent = styled.span`\n ${Button}:active & {\n transform: scale(0.9);\n }\n`;\n\nexport default ButtonPoofy;\n","export { default } from './ButtonPoofy';\n","import React from 'react';\n\nimport { range } from '@/utils';\nimport useIncrementingNumber from '@/hooks/use-incrementing-number';\n\nconst rainbowColors = [\n 'hsl(230deg, 100%, 45%)', // blue\n 'hsl(240deg, 100%, 45%)', // indigo\n 'hsl(260deg, 100%, 55%)', // violet\n 'hsl(325deg, 100%, 48%)', // pink\n 'hsl(325deg, 100%, 48%)', // pink\n 'hsl(325deg, 100%, 48%)', // pink\n 'hsl(260deg, 100%, 55%)', // violet\n];\nconst paletteSize = rainbowColors.length;\nconst WINDOW_SIZE = 3;\n\n// During compile-time build, we have to assume no browser support.\n// On mount, we'll check if `CSS.registerProperty` exists\nconst hasBrowserSupport =\n typeof window !== 'undefined'\n ? typeof window.CSS.registerProperty === 'function'\n : false;\n\nconst getColorPropName = (id: string, index: number) =>\n `--magic-rainbow-color-${id}-${index}`;\n\nconst useRainbow = ({\n intervalDelay = 2000,\n}: {\n intervalDelay?: number;\n}) => {\n const id = React.useId().replace(/:/g, '');\n\n const prefersReducedMotion =\n typeof window === 'undefined'\n ? { matches: true }\n : window.matchMedia('(prefers-reduced-motion: no-preference)');\n\n const isEnabled = hasBrowserSupport && prefersReducedMotion.matches;\n\n // Register all custom properties\n React.useEffect(() => {\n if (!isEnabled) {\n return;\n }\n\n range(0, WINDOW_SIZE).map((index) => {\n const name = getColorPropName(id, index);\n const initialValue = rainbowColors[index];\n\n try {\n CSS.registerProperty({\n name,\n initialValue,\n syntax: '',\n inherits: false,\n });\n } catch (err) {}\n });\n }, [id, isEnabled]);\n\n const intervalCount = useIncrementingNumber(intervalDelay);\n\n return range(0, WINDOW_SIZE).reduce((acc, index) => {\n const effectiveIntervalCount = isEnabled ? intervalCount : 0;\n\n const name = getColorPropName(id, index);\n const value =\n rainbowColors[(effectiveIntervalCount + index) % paletteSize];\n\n return {\n ...acc,\n [name]: value,\n };\n }, {});\n};\n\nexport default useRainbow;\n","'use client';\n\n/*\n NOTE: This component used to have a separate wrapper, PoofyRainbowButton, that added a glassy effect to the button. I was using that in all but 1 of the places I used the ButtonRainbow, so I merged them. This component includes the PoofyRainbowButton styling.\n*/\nimport * as React from 'react';\nimport { styled } from '@linaria/react';\n\nimport useBrowser from '@/hooks/use-browser';\n\nimport ButtonPoofy from '@/components/ButtonPoofy';\n\nimport useRainbow from './use-rainbow.hook';\n\ninterface Props\n extends React.ButtonHTMLAttributes {\n intervalDelay?: number;\n}\n\nfunction ButtonRainbow({\n children,\n intervalDelay = 1300,\n className,\n style = {},\n ...delegated\n}: Props) {\n const transitionDelay = intervalDelay * 1.25;\n\n const colors = useRainbow({ intervalDelay });\n\n // Frustratingly, the transition doesn't work in Firefox, despite the APIs being supported according to caniuse. I suspect maybe this is a bug in the latest Firefox release, since this isn't a regression between old blog and new.\n // For now, we’ll disable this in Firefox. In 2025, I should see if I can remove this:\n const browser = useBrowser();\n\n const colorKeys = Object.keys(colors);\n\n return (\n \n {children}\n \n );\n}\n\nconst Button = styled(ButtonPoofy)`\n min-height: 3.75rem;\n backface-visibility: hidden;\n background: var(--background);\n\n &[data-disable-transition='true'] {\n background: hsl(240deg, 80%, 40%);\n }\n`;\n\nexport default ButtonRainbow;\n","export { default } from './ButtonRainbow';\n","'use client';\n\nimport React from 'react';\nimport { styled } from '@linaria/react';\nimport { useSpring, animated } from 'react-spring';\nimport { ArrowRight, Star } from 'lucide-react';\n\nimport { BREAKPOINTS, TIGHT_SPRING } from '@/constants';\nimport usePrefersReducedMotion from '@/hooks/use-prefers-reduced-motion';\n\nimport {\n BaseWrapper as AsideWrapper,\n WarningAside,\n} from '@/components/Aside';\n\ntype ListType = 'unordered' | 'ordered';\nconst ListContext = React.createContext<{ type: ListType }>({\n type: 'unordered',\n});\n\nconst DefaultIcon = () => ;\nconst FullStarIcon = () => ;\n\nconst ICONS = {\n default: DefaultIcon,\n fullStar: FullStarIcon,\n};\n\ninterface ListItemProps extends React.HTMLAttributes {\n bullet?: keyof typeof ICONS;\n animated?: boolean;\n children: React.ReactNode;\n}\n\nexport const ListItem = ({\n bullet = 'default',\n animated = false,\n children,\n ...delegated\n}: ListItemProps) => {\n const { type } = React.useContext(ListContext);\n\n const prefersReducedMotion = usePrefersReducedMotion();\n\n const IconComponent = ICONS[bullet];\n const [isHovering, setIsHovering] = React.useState(false);\n\n const iconSpring = useSpring(\n animated && !prefersReducedMotion\n ? {\n '--x': isHovering ? `8px` : `0px`,\n config: TIGHT_SPRING,\n }\n : { transform: 'translateY(4px) translateX(0px)' }\n );\n\n if (type === 'ordered') {\n return (\n \n {children}\n \n );\n }\n\n return (\n \n \n \n \n {/*\n This interaction is purely decorative, and is not required for\n folks using the keyboard or a screen-reader.\n */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n >\n {children}\n \n \n );\n};\n\ninterface Props extends React.HTMLAttributes {\n type?: ListType;\n}\n\nconst List = ({ type = 'unordered', ...delegated }: Props) => {\n return (\n \n {type === 'ordered' && }\n {type === 'unordered' && }\n \n );\n};\n\nconst UnorderedListElem = styled.ul`\n font-size: inherit;\n margin-bottom: 2rem;\n list-style: none;\n padding: 0;\n\n /* For nested list items, add top margin as well */\n ul & {\n margin-top: 16px;\n }\n\n @media ${BREAKPOINTS.smAndSmaller} {\n margin-bottom: 1.5rem;\n }\n`;\n\nconst OrderedListElem = styled.ol`\n --counter-name: counts;\n\n font-size: inherit;\n margin-bottom: 2rem;\n counter-reset: var(--counter-name);\n list-style: none;\n padding: 0;\n\n & li {\n counter-increment: var(--counter-name);\n align-items: baseline;\n }\n\n & li::before {\n content: counters(var(--counter-name), '.') '. ';\n display: inline-flex;\n justify-content: center;\n font-feature-settings: 'tnum';\n color: var(--color-primary);\n font-weight: var(--font-weight-medium);\n padding-right: 12px;\n width: 2.25rem;\n }\n\n /* The orange warning color is too light, not enough contrast. Reset to text color. */\n ${WarningAside} & li::before {\n color: var(--color-text);\n }\n\n @media ${BREAKPOINTS.smAndSmaller} {\n font-size: calc(18 / 16 * 1rem);\n margin-bottom: 1.5rem;\n }\n`;\n\nconst Wrapper = styled.li`\n margin-bottom: 16px;\n display: flex;\n align-items: flex-start;\n\n &:last-of-type {\n margin-bottom: 0;\n }\n\n ${AsideWrapper} & {\n font-size: 1rem;\n margin-bottom: 8px;\n }\n`;\n\nconst ListItemContents = styled.div`\n flex: 1;\n`;\n\nconst IconWrapper = styled(animated.span)`\n --optical-align: 0.1875em;\n display: flex;\n align-items: center;\n padding-right: 16px;\n padding-top: 0;\n color: var(--color-primary);\n transform: translate(var(--x), var(--optical-align));\n\n ${AsideWrapper} & {\n /* Optical alignment - text is smaller in asides, so the icon needs to be shifted */\n --optical-align: 0.125em;\n }\n\n ${WarningAside} & {\n color: var(--color-text);\n }\n`;\n\nList.ListItem = ListItem;\n\nexport default List;\n","import { styled } from '@linaria/react';\n\nimport { BREAKPOINTS } from '@/constants';\n\nimport { BaseWrapper as AsideWrapper } from '@/components/Aside';\nimport { Wrapper as BlockquoteWrapper } from '@/components/Blockquote';\nimport { Wrapper as TweetWrapper } from '@/components/FakeTweet';\n\nexport default styled.p`\n font-size: var(--paragraph-font-size-override, 1.125rem);\n margin-bottom: 1.25em;\n\n ${AsideWrapper} & {\n font-size: 1rem;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n ${BlockquoteWrapper} & {\n @media ${BREAKPOINTS.mdAndLarger} {\n text-wrap: balance;\n text-align: center;\n }\n }\n\n ${TweetWrapper} & {\n font-size: 1rem;\n }\n`;\n","export { default } from './Paragraph';\n","'use client';\n\nimport dynamic from 'next/dynamic';\n\nconst ConfettiGeyser = dynamic(\n () =>\n import('./ConfettiGeyser').catch((err) => {\n // If the internet connection is lost, we won’t be able to load the ConfettiGeyser component, but that’s fine.\n return { default: () => null };\n }),\n {\n ssr: false,\n }\n);\n\nexport default ConfettiGeyser;\n","import * as React from 'react';\n\nimport useInterval from '@/hooks/use-interval';\nimport useWindowDimensions from '@/hooks/use-window-dimensions';\nimport type { ConfettiStatus } from '@/helpers/newsletter.helpers';\n\nimport ConfettiGeyser from '@/components/ConfettiGeyser';\nimport InPortal from '@/components/InPortal';\n\ntype Mode = 'burst' | 'stream' | 'preload';\n\ninterface Props {\n status: ConfettiStatus;\n mode: Mode;\n}\n\n// Subscribe Geysers have two modes:\n// - Burst: A big burst of confetti that slowly tapers to 0\n// - Stream: A constant stream of moderate confetti\nfunction SubscribeGeyser({ status, mode = 'burst' }: Props) {\n const windowDimensions = useWindowDimensions();\n\n const [burstConcentration, setBurstConcentration] =\n React.useState(100);\n\n // In portrait orientations (mostly mobile), we want to fire straight up from the bottom of the screen.\n const isPortrait =\n typeof windowDimensions.width === 'number' &&\n typeof windowDimensions.height === 'number' &&\n windowDimensions.width < windowDimensions.height;\n\n const geyserPosition: [number, number] = React.useMemo(() => {\n if (\n typeof windowDimensions.width !== 'number' ||\n typeof windowDimensions.height !== 'number'\n ) {\n // Should never actually be used:\n return [0, 1000];\n }\n\n if (isPortrait) {\n return [windowDimensions.width / 2, windowDimensions.height];\n } else {\n return [0, Math.min(700, windowDimensions.height)];\n }\n }, [isPortrait, windowDimensions.width, windowDimensions.height]);\n\n const intervalDuration =\n burstConcentration > 0 && status === 'active' && mode === 'burst'\n ? 250\n : null;\n\n useInterval(() => {\n let newConcentration = burstConcentration * 0.7 - 1;\n\n if (newConcentration < 1) {\n newConcentration = 0;\n }\n\n setBurstConcentration(newConcentration);\n }, intervalDuration);\n\n let concentration;\n if (status === 'inert') {\n // The `ConfettiGeyser` component is lazy-loaded, meaning that it’s only downloaded when it’s rendered. When `status` is \"inert\", we won’t render it.\n return null;\n } else if (status === 'preload') {\n // When the user submits the form, the status switches to \"preload\", and we’ll render the ConfettiGeyser, but with 0 concentration (so no visible confetti yet).\n concentration = 0;\n } else {\n // We know at this point that the confetti is running, so we’ll set the confetti based on the mode. In burst, it starts high and falls to 0. In stream, it stays constant.\n concentration = mode === 'burst' ? burstConcentration : 16;\n }\n\n return (\n \n \n \n );\n}\n\nexport default SubscribeGeyser;\n","export { default } from './SubscribeGeyser';\n","import React from 'react';\n\nimport { throttle } from '@/utils';\n\ninterface Options {\n throttleBy?: number;\n}\n\nconst useScrollPosition = (\n handleScroll: (event: UIEvent) => void,\n { throttleBy = 150 }: Options = {}\n) => {\n const cachedHandleScroll = React.useRef(handleScroll);\n cachedHandleScroll.current = handleScroll;\n\n React.useEffect(() => {\n const throttled = throttle((event: UIEvent) => {\n cachedHandleScroll.current(event);\n }, throttleBy);\n\n window.addEventListener('scroll', throttled);\n\n return () => {\n window.removeEventListener('scroll', throttled);\n };\n }, [throttleBy]);\n};\n\nexport default useScrollPosition;\n","'use client';\n\nimport React from 'react';\nimport { styled } from '@linaria/react';\nimport { Pause, Play } from 'lucide-react';\n\nimport { FANCY_SHADOW } from '@/constants';\nimport usePrefersReducedMotion from '@/hooks/use-prefers-reduced-motion';\nimport useOnScroll from '@/hooks/use-on-scroll';\nimport useIsOnscreen from '@/hooks/use-is-onscreen';\n\nimport { UserPreferencesContext } from '@/components/UserPreferencesProvider';\nimport { BaseWrapper as BaseAside } from '@/components/Aside';\n\nexport interface Props\n extends React.HTMLAttributes {\n src: string;\n darkSrc?: string;\n width?: number;\n height?: number;\n maxWidth?: string | number;\n alt: string;\n caption?: string;\n captionStyle?: React.CSSProperties;\n lazy?: boolean;\n includeBorder?: boolean | 'dark-only';\n includeShadow?: boolean;\n fillEdges?: boolean;\n backdrop?: string;\n style?: React.CSSProperties;\n wrapperStyle?: React.CSSProperties;\n autoPlay?: boolean;\n controls?: boolean;\n}\n\nfunction VideoGif({\n src,\n darkSrc,\n width,\n height,\n maxWidth: rawMaxWidth,\n alt,\n caption,\n captionStyle = {},\n lazy,\n includeBorder = 'dark-only',\n includeShadow,\n fillEdges,\n backdrop,\n style = {},\n wrapperStyle = {},\n autoPlay,\n controls = false,\n ...delegated\n}: Props) {\n const wrapperRef = React.useRef(null);\n const videoRef = React.useRef(null);\n\n const { colorMode } = React.useContext(UserPreferencesContext);\n const prefersReducedMotion = usePrefersReducedMotion();\n\n const autoPlayConsideringReducedMotion =\n typeof autoPlay === 'boolean' ? autoPlay : !prefersReducedMotion;\n\n const [isPaused, setIsPaused] = React.useState(\n !autoPlayConsideringReducedMotion\n );\n const [showControls, setShowControls] = React.useState(false);\n\n const actualSrc = colorMode === 'light' ? src : darkSrc || src;\n\n const isOnscreen = useIsOnscreen(wrapperRef, false, {\n threshold: [0],\n ignoreSubsequentEntries: true,\n disabled: !lazy,\n });\n\n // A weird thing happens in iOS where sometimes the autoplay doesn't work. As a result, our state gets out of sync; the actual video is actually paused, but `isPaused` is false.\n // To solve this, we'll add a scroll handler which checks for any videos in the viewport that are out-of-sync, and synchronizes them by playing the video.\n useOnScroll(() => {\n if (!videoRef.current) {\n return;\n }\n\n const isOutOfSync = videoRef.current.paused && !isPaused;\n if (!isOutOfSync) {\n return;\n }\n\n const boundingBox = videoRef.current.getBoundingClientRect();\n\n if (\n boundingBox.top < window.innerHeight &&\n boundingBox.bottom > 0\n ) {\n videoRef.current.play();\n }\n });\n\n function handleTogglePlaying(method: 'pointer' | 'keyboard') {\n if (!videoRef.current) {\n return;\n }\n\n if (videoRef.current.paused) {\n setIsPaused(false);\n videoRef.current.play();\n // Clicking the play button should hide the controls, but we shouldn't do this for keyboard users, since it would be strange to have the currently-focused element become invisible.\n if (method === 'pointer') {\n setShowControls(false);\n }\n } else {\n setIsPaused(true);\n videoRef.current.pause();\n if (method === 'pointer') {\n setShowControls(true);\n }\n }\n }\n\n let aspectRatio;\n if (typeof width === 'number' && typeof height === 'number') {\n aspectRatio = `${width} / ${height}`;\n }\n\n let maxWidth;\n if (typeof width === 'number') {\n maxWidth = `${width}px`;\n } else if (typeof width === 'string') {\n maxWidth = width;\n } else {\n maxWidth = '100%';\n }\n\n let borderColor;\n if (includeBorder === 'dark-only') {\n borderColor = 'var(--color-content-outline)';\n } else if (includeBorder) {\n borderColor = 'var(--color-gray-200)';\n } else {\n borderColor = 'transparent';\n }\n\n // We generally want to center-align images, but if they're almost full-width, it looks more natural if they're left-aligned.\n let alignment = width && width < 600 ? 'center' : 'left';\n\n // If we have a caption, however, the caption will always be center-aligned, which looks funky if the image is left-aligned.\n if (alignment === 'left' && caption) {\n alignment = 'center';\n }\n\n const shouldRenderVideo = isOnscreen || !lazy;\n\n return (\n <>\n \n {shouldRenderVideo && (\n {\n // The `controls` prop dictates whether we’re using the native video UI, or my own play/pause button. If `controls` is true, we don’t have to do anything special.\n if (controls) {\n return;\n }\n\n handleTogglePlaying('pointer');\n }}\n onMouseEnter={() => {\n if (controls) {\n return;\n }\n\n setShowControls(true);\n }}\n onMouseLeave={() => {\n if (controls) {\n return;\n }\n\n setShowControls(false);\n }}\n {...delegated}\n />\n )}\n {fillEdges && }\n\n {!controls && (\n {\n if (event.code === 'Enter') {\n handleTogglePlaying('keyboard');\n }\n }}\n onFocus={() => setShowControls(true)}\n onBlur={() => setShowControls(false)}\n >\n {isPaused ? : }\n \n )}\n \n {caption && (\n \n {caption}\n \n )}\n \n );\n}\n\nconst Wrapper = styled.div`\n position: relative;\n width: 100%;\n max-width: var(--max-width);\n margin-top: 16px;\n margin-bottom: 64px;\n border-radius: 6px;\n /* Trim corners */\n overflow: hidden;\n overflow: clip;\n transition: outline var(--color-swap-duration);\n\n ${BaseAside} & {\n /* Asides are flex columns and most elements only have bottom margin. I still want a *bit* of top margin for optical alignment, but not much */\n margin-top: 8px;\n /* A bit less bottom margin since things are less sparse inside Asides: */\n margin-bottom: 32px;\n }\n\n &[data-include-caption='true'] {\n margin-bottom: 16px;\n }\n &[data-alignment='center'] {\n margin-inline: auto;\n }\n`;\n\nconst Caption = styled.div`\n padding-top: 8px;\n font-size: 0.875rem;\n text-align: center;\n margin-bottom: 48px;\n\n ${BaseAside} & {\n padding-top: 0px;\n margin-bottom: 32px;\n }\n`;\n\nconst Video = styled.video`\n position: relative;\n display: block;\n width: 100%;\n border-radius: 3px;\n cursor: pointer;\n`;\n\n// For some reason, screenflow sometimes creates a 1px black\n// outline. Let's hide it.\nconst Filler = styled.div`\n position: absolute;\n top: -1px;\n left: -1px;\n right: -1px;\n bottom: -1px;\n pointer-events: none;\n border: 3px solid white;\n border-radius: 4px;\n`;\n\nconst PauseButton = styled.button`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n margin: auto;\n width: 64px;\n height: 64px;\n background: hsl(0deg 0% 0% / 0.5);\n border-radius: 50%;\n color: white;\n display: flex;\n justify-content: center;\n align-items: center;\n transition: opacity 500ms;\n pointer-events: none;\n\n i,\n svg {\n display: block !important;\n }\n`;\n\nexport default VideoGif;\n","export type Browser =\n | 'firefox'\n | 'chrome'\n | 'safari'\n | 'ie'\n | 'edge'\n | 'brave';\n\nexport const detectBrowser = (): Browser | null => {\n // SSR!\n if (typeof navigator === 'undefined') {\n return null;\n }\n\n if (\n // @ts-ignore\n typeof InstallTrigger !== 'undefined' ||\n navigator.userAgent.indexOf('Firefox') !== -1\n ) {\n return 'firefox';\n }\n\n // @ts-ignore\n if (!!window.navigator.brave) {\n return 'brave';\n }\n\n const isChrome = navigator.userAgent.indexOf('Chrome') !== -1;\n\n if (isChrome) {\n return 'chrome';\n }\n\n // Safari 3.0+ \"[object HTMLElementConstructor]\"\n const isSafari =\n navigator.userAgent.indexOf('Safari') !== -1 ||\n // @ts-ignore\n /constructor/i.test(window.HTMLElement) ||\n (function (p) {\n return p.toString() === '[object SafariRemoteNotification]';\n })(\n // @ts-ignore\n !window['safari'] ||\n // @ts-ignore\n (typeof safari !== 'undefined' &&\n // @ts-ignore\n window['safari'].pushNotification)\n );\n const isMobileSafari =\n navigator.userAgent.match(/iPad/i) ||\n navigator.userAgent.match(/iPhone/i);\n if (isSafari || isMobileSafari) {\n return 'safari';\n }\n\n // Internet Explorer 6-11\n // @ts-ignore\n const isIE = /*@cc_on!@*/ false || !!document.documentMode;\n if (isIE) {\n return 'ie';\n }\n // Edge 20+\n // @ts-ignore\n const isEdge = !isIE && !!window.StyleMedia;\n if (isEdge) {\n return 'edge';\n }\n\n return null;\n};\n","import React from 'react';\n\nimport { Browser, detectBrowser } from '@/helpers/browser.helpers';\n\nexport default function useBrowser() {\n const [browser, setBrowser] = React.useState(null);\n\n React.useEffect(() => {\n setBrowser(detectBrowser());\n }, []);\n\n return browser;\n}\n","import React from 'react';\n\nfunction useIncrementingNumber(delay: number) {\n const [count, setCount] = React.useState(0);\n\n const savedCallback = React.useRef(() => setCount((c) => c + 1));\n\n // Set up the interval.\n React.useEffect(() => {\n function tick() {\n savedCallback.current();\n }\n if (delay !== null) {\n let id = setInterval(tick, delay);\n return () => clearInterval(id);\n }\n }, [delay]);\n\n return count;\n}\n\nexport default useIncrementingNumber;\n","import React from 'react';\n\ninterface Options {\n // threshold is an option on IntersectionObserver. It allows us to specify that the element should only be on-screen when a certain percentage of it is visible.\n // For example, if we set `threshold: [0.5]`, the element will only be considered onscreen when 50%+ is within the viewport.\n // Defaults to [0], which listens for a single pixel of visibility.\n threshold: Array;\n // By default, `isOnscreen` tracks whether the element is on screen in perpetuity. Sometimes, we only care about when it *first* enters the viewport. If we specify this argument, the IntersectionObserver is dissolved after that first entry.\n ignoreSubsequentEntries?: boolean;\n // Because hooks can’t be called conditionally, there may be cases where I only want to enable the IntersectionObserver *sometimes*. In that case, I can pass the `disabled` prop.\n disabled?: boolean;\n}\n\nexport default function useIsOnscreen(\n elementRef: React.RefObject,\n defaultState: boolean = false,\n options: Options = {\n threshold: [0],\n ignoreSubsequentEntries: false,\n disabled: false,\n }\n) {\n const [isOnscreen, setIsOnscreen] = React.useState(defaultState);\n\n // For the threshold, we don’t need to re-run the effect when it changes, so we’ll covertly access the value in the effect via a ref.\n const thresholdRef = React.useRef(options.threshold);\n thresholdRef.current = options.threshold;\n\n React.useEffect(() => {\n if (!elementRef.current) {\n return;\n }\n\n if (options.disabled) {\n return;\n }\n\n if (isOnscreen && options.ignoreSubsequentEntries) {\n return;\n }\n\n const observer = new window.IntersectionObserver(\n (entries) => {\n const [entry] = entries;\n\n setIsOnscreen(entry.intersectionRatio > 0);\n },\n {\n threshold: thresholdRef.current,\n }\n );\n\n observer.observe(elementRef.current);\n\n return () => {\n observer.disconnect();\n };\n }, [\n isOnscreen,\n elementRef,\n options.ignoreSubsequentEntries,\n options.disabled,\n ]);\n\n return isOnscreen;\n}\n","/*\n This hook provides responsive window dimensions.\n\n SPECIAL THING: by default, window.innerWidth is always in pixels, and doesn't change as the user scales up their default font size. This isn't useful; if the user cranks their default font size to 32px, the window essentially shrinks by half, but `window.innerWidth` doesn't change.\n This hook solves for this. The values it returns are in pixels, but scaled based on the user’s default font size.\n*/\nimport React from 'react';\n\nimport { throttle } from '@/utils';\n\ninterface WindowDimensions {\n width: number | undefined;\n height: number | undefined;\n clientWidth: number | undefined;\n}\n\nconst useWindowDimensionsInRems = () => {\n const [windowDimensions, setWindowDimensions] =\n React.useState({\n width: undefined,\n height: undefined,\n clientWidth: undefined,\n });\n\n React.useEffect(() => {\n const calculatorElement = document.createElement('div');\n calculatorElement.style.fontSize = '1rem';\n\n document.body.appendChild(calculatorElement);\n\n const fontSize = parseFloat(\n window.getComputedStyle(calculatorElement).fontSize\n );\n\n const ratio = 16 / fontSize;\n\n setWindowDimensions({\n width: window.innerWidth * ratio,\n height: window.innerHeight * ratio,\n clientWidth: document.documentElement.clientWidth * ratio,\n });\n\n const handleResize = throttle(() => {\n setWindowDimensions({\n width: window.innerWidth * ratio,\n height: window.innerHeight * ratio,\n clientWidth: document.documentElement.clientWidth * ratio,\n });\n }, 250);\n\n window.addEventListener('resize', handleResize);\n\n return () => {\n // Hm so weirdly, sometimes the `calculatorElement` is already removed from the DOM by the time this cleanup function runs. So we wrap this in a try/catch to prevent errors.\n try {\n document.body.removeChild(calculatorElement);\n window.removeEventListener('resize', handleResize);\n } catch (err) {}\n };\n }, []);\n\n return windowDimensions;\n};\n\nexport default useWindowDimensionsInRems;\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"bhgdr3i\":\"bhgdr3i\",\"b16w56qw\":\"b16w56qw\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"bqvz84h\":\"bqvz84h\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"uzpj0zh\":\"uzpj0zh\",\"oc96fnv\":\"oc96fnv\",\"wcnkszl\":\"wcnkszl\",\"wp18jjy\":\"wp18jjy\",\"b1btlj5u\":\"b1btlj5u\",\"l1n7gg9f\":\"l1n7gg9f\",\"idw7p1w\":\"idw7p1w\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"prg881n\":\"prg881n\",\"b1btlj5u\":\"b1btlj5u\",\"w12kxl7t\":\"w12kxl7t\",\"w9k8ad0\":\"w9k8ad0\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"w10oesj0\":\"w10oesj0\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"w1hban68\":\"w1hban68\",\"b1btlj5u\":\"b1btlj5u\",\"c1ubytjc\":\"c1ubytjc\",\"vsmrqjy\":\"vsmrqjy\",\"f11p4usk\":\"f11p4usk\",\"ps5yn9o\":\"ps5yn9o\"};"],"names":["Button","styled","name","class","propsAsIs","ButtonContent","ButtonPoofy","delegated","children","rainbowColors","paletteSize","length","hasBrowserSupport","window","CSS","registerProperty","getColorPropName","id","index","useRainbow","intervalDelay","React","replace","prefersReducedMotion","matchMedia","isEnabled","matches","range","WINDOW_SIZE","map","initialValue","syntax","inherits","err","intervalCount","useIncrementingNumber","reduce","acc","effectiveIntervalCount","value","ButtonRainbow","className","style","transitionDelay","colors","browser","useBrowser","colorKeys","Object","transition","ListContext","type","ICONS","default","DefaultIcon","fullStar","FullStarIcon","ListItem","bullet","animated","usePrefersReducedMotion","IconComponent","isHovering","iconSpring","useSpring","config","TIGHT_SPRING","transform","setIsHovering","List","UnorderedListElem","OrderedListElem","Wrapper","ListItemContents","IconWrapper","_exp5","ConfettiGeyser","dynamic","catch","ssr","SubscribeGeyser","concentration","status","mode","windowDimensions","useWindowDimensions","burstConcentration","setBurstConcentration","isPortrait","width","height","geyserPosition","Math","min","useInterval","newConcentration","intervalDuration","InPortal","position","enableCollisions","airFriction","velocity","angularVelocity","angle","spread","volatility","handleScroll","useScrollPosition","throttleBy","cachedHandleScroll","current","throttled","throttle","event","addEventListener","removeEventListener","Caption","Video","Filler","PauseButton","VideoGif","aspectRatio","maxWidth","borderColor","darkSrc","rawMaxWidth","alt","caption","captionStyle","lazy","includeBorder","includeShadow","fillEdges","backdrop","wrapperStyle","autoPlay","controls","wrapperRef","videoRef","HTMLVideoElement","colorMode","UserPreferencesContext","autoPlayConsideringReducedMotion","showControls","setShowControls","isOnscreen","useIsOnscreen","threshold","ignoreSubsequentEntries","disabled","handleTogglePlaying","method","paused","play","pause","useOnScroll","isOutOfSync","isPaused","boundingBox","getBoundingClientRect","top","innerHeight","bottom","alignment","String","outline","undefined","background","boxShadow","FANCY_SHADOW","shouldRenderVideo","actualSrc","src","opacity","code","marginTop","detectBrowser","navigator","InstallTrigger","userAgent","indexOf","brave","isSafari","test","HTMLElement","p","safari","pushNotification","toString","isMobileSafari","match","isIE","document","documentMode","StyleMedia","setBrowser","count","setCount","savedCallback","c","delay","setInterval","tick","clearInterval","elementRef","defaultState","options","setIsOnscreen","thresholdRef","observer","IntersectionObserver","entry","entries","intersectionRatio","observe","disconnect","setWindowDimensions","useWindowDimensionsInRems","clientWidth","calculatorElement","createElement","fontSize","body","appendChild","ratio","parseFloat","getComputedStyle","innerWidth","documentElement","handleResize","removeChild"],"sourceRoot":"","ignoreList":[]}