feat: implement full-screen mobile hamburger menu with portal

Refactor hamburger menu to use custom full-screen overlay on mobile
instead of Radix UI dropdown, fixing z-index stacking context issues.

Key changes:
- Extract MenuContent component for shared rendering logic between
  mobile and desktop versions
- Implement custom full-screen mobile menu with viewport detection
- Use React Portal to render mobile menu outside header's stacking
  context, ensuring it layers above hero abacus (z-index 9999 > 10)
- Desktop continues using Radix UI dropdown menu as before
- Mobile menu closes on navigation and backdrop click

Technical details:
- Header's opacity: 0.95 creates stacking context, constraining child
  z-indexes. Portal breaks out to document.body for global z-index.
- Conditional rendering based on viewport width (640px breakpoint)
- Shared MenuContent adapts rendering (plain divs vs Radix components)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-11-08 11:50:38 -06:00
parent 85db052f07
commit 615cd28829
1 changed files with 419 additions and 385 deletions

View File

@ -5,6 +5,7 @@ import * as Tooltip from '@radix-ui/react-tooltip'
import Link from 'next/link'
import { usePathname, useRouter } from 'next/navigation'
import React, { useContext, useMemo, useState } from 'react'
import { createPortal } from 'react-dom'
import { css } from '../../styled-system/css'
import { container, hstack } from '../../styled-system/patterns'
import { Z_INDEX } from '../constants/zIndex'
@ -46,6 +47,281 @@ interface AppNavBarProps {
/**
* Hamburger menu component for utility navigation
*/
// Shared menu content component
function MenuContent({
isFullscreen,
isArcadePage,
pathname,
toggleFullscreen,
router,
onNavigate,
handleNestedDropdownChange,
isMobile,
}: {
isFullscreen: boolean
isArcadePage: boolean
pathname: string | null
toggleFullscreen: () => void
router: any
onNavigate?: () => void
handleNestedDropdownChange?: (isOpen: boolean) => void
isMobile?: boolean
}) {
const linkStyle = {
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
textDecoration: 'none',
transition: 'all 0.2s ease',
}
const separatorStyle = {
height: '1px',
background: 'rgba(75, 85, 99, 0.5)',
margin: '6px 0',
}
const sectionHeaderStyle = {
fontSize: '10px',
fontWeight: '600',
color: 'rgba(196, 181, 253, 0.7)',
marginBottom: '6px',
marginLeft: '12px',
marginTop: '6px',
textTransform: 'uppercase' as const,
letterSpacing: '0.5px',
}
const handleLinkClick = (href: string) => {
if (isMobile) {
router.push(href)
onNavigate?.()
}
}
const renderNavLink = (href: string, icon: string, label: string) => {
const linkElement = (
<Link
href={href}
onClick={
isMobile
? (e) => {
e.preventDefault()
handleLinkClick(href)
}
: undefined
}
style={linkStyle}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(139, 92, 246, 0.2)'
e.currentTarget.style.color = 'rgba(196, 181, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>{icon}</span>
<span>{label}</span>
</Link>
)
return isMobile ? linkElement : <DropdownMenu.Item asChild>{linkElement}</DropdownMenu.Item>
}
return (
<>
{/* Site Navigation Section */}
<div style={sectionHeaderStyle}>Navigation</div>
{renderNavLink('/', '🧮', 'Home')}
{renderNavLink('/create', '✏️', 'Create')}
{renderNavLink('/guide', '📖', 'Guide')}
{renderNavLink('/games', '🎮', 'Games')}
{renderNavLink('/blog', '📝', 'Blog')}
{isMobile ? (
<div style={separatorStyle} />
) : (
<DropdownMenu.Separator style={separatorStyle} />
)}
{/* Controls Section */}
<div style={sectionHeaderStyle}>Controls</div>
{isMobile ? (
<div
onClick={() => {
toggleFullscreen()
onNavigate?.()
}}
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(59, 130, 246, 0.2)'
e.currentTarget.style.color = 'rgba(147, 197, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>{isFullscreen ? '🪟' : '⛶'}</span>
<span>{isFullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}</span>
</div>
) : (
<DropdownMenu.Item
onSelect={toggleFullscreen}
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(59, 130, 246, 0.2)'
e.currentTarget.style.color = 'rgba(147, 197, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>{isFullscreen ? '🪟' : '⛶'}</span>
<span>{isFullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}</span>
</DropdownMenu.Item>
)}
{isArcadePage &&
(isMobile ? (
<div
onClick={() => {
router.push('/games')
onNavigate?.()
}}
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(239, 68, 68, 0.2)'
e.currentTarget.style.color = 'rgba(252, 165, 165, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>🚪</span>
<span>Exit Arcade</span>
</div>
) : (
<DropdownMenu.Item
onSelect={() => router.push('/games')}
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(239, 68, 68, 0.2)'
e.currentTarget.style.color = 'rgba(252, 165, 165, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>🚪</span>
<span>Exit Arcade</span>
</DropdownMenu.Item>
))}
{isMobile ? (
<div style={separatorStyle} />
) : (
<DropdownMenu.Separator style={separatorStyle} />
)}
{/* Style Section */}
<div style={sectionHeaderStyle}>Abacus Style</div>
<div style={{ padding: '0 6px' }}>
<AbacusDisplayDropdown
isFullscreen={isFullscreen}
onOpenChange={handleNestedDropdownChange}
/>
</div>
{isMobile ? (
<div style={separatorStyle} />
) : (
<DropdownMenu.Separator style={separatorStyle} />
)}
{/* Language Section */}
<div style={sectionHeaderStyle}>Language</div>
<LanguageSelector variant="dropdown-item" isFullscreen={isFullscreen} />
{isMobile ? (
<div style={separatorStyle} />
) : (
<DropdownMenu.Separator style={separatorStyle} />
)}
{/* Theme Section */}
<div style={sectionHeaderStyle}>Theme</div>
{isMobile ? (
<div style={{ padding: '0 6px' }}>
<ThemeToggle />
</div>
) : (
<DropdownMenu.Item onSelect={(e) => e.preventDefault()} style={{ padding: '0 6px' }}>
<ThemeToggle />
</DropdownMenu.Item>
)}
</>
)
}
function HamburgerMenu({
isFullscreen,
isArcadePage,
@ -60,32 +336,21 @@ function HamburgerMenu({
router: any
}) {
const [open, setOpen] = useState(false)
const [hovered, setHovered] = useState(false)
const [nestedDropdownOpen, setNestedDropdownOpen] = useState(false)
const hoverTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)
const [isMobile, setIsMobile] = useState(false)
// Open on hover or click OR if nested dropdown is open
const isOpen = open || hovered || nestedDropdownOpen
const handleMouseEnter = () => {
if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current)
hoverTimeoutRef.current = null
// Detect mobile viewport
React.useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth < 640)
}
setHovered(true)
}
checkMobile()
window.addEventListener('resize', checkMobile)
return () => window.removeEventListener('resize', checkMobile)
}, [])
const handleMouseLeave = () => {
// Don't close if nested dropdown is open
if (nestedDropdownOpen) {
return
}
// Delay closing to allow moving from button to menu
hoverTimeoutRef.current = setTimeout(() => {
setHovered(false)
}, 150)
}
// Open on click OR if nested dropdown is open
const isOpen = open || nestedDropdownOpen
const handleOpenChange = (newOpen: boolean) => {
setOpen(newOpen)
@ -93,26 +358,107 @@ function HamburgerMenu({
const handleNestedDropdownChange = (isNestedOpen: boolean) => {
setNestedDropdownOpen(isNestedOpen)
// Just update the nested dropdown state
// The hamburger will stay open if mouse is still hovering or it was clicked open
// The existing hover/click logic will handle closing naturally when appropriate
}
React.useEffect(() => {
return () => {
if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current)
}
}
}, [])
const handleClose = () => {
setOpen(false)
}
// Mobile full-screen menu
if (isMobile) {
return (
<>
<button
type="button"
onClick={() => setOpen(!open)}
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '44px',
height: '44px',
padding: '8px',
background: isFullscreen ? 'rgba(0, 0, 0, 0.85)' : 'white',
border: isFullscreen ? '1px solid rgba(255, 255, 255, 0.1)' : '1px solid #e5e7eb',
borderRadius: '8px',
boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
backdropFilter: isFullscreen ? 'blur(15px)' : 'none',
cursor: 'pointer',
transition: 'all 0.2s ease',
}}
>
<span
style={{
fontSize: '20px',
color: isFullscreen ? 'white' : '#374151',
}}
>
{open ? '✕' : '☰'}
</span>
</button>
{open &&
typeof document !== 'undefined' &&
createPortal(
<>
<div
className={css({
position: 'fixed',
inset: 0,
background:
'linear-gradient(135deg, rgba(17, 24, 39, 0.97), rgba(31, 41, 55, 0.97))',
backdropFilter: 'blur(12px)',
zIndex: Z_INDEX.GAME_NAV.HAMBURGER_MENU,
overflowY: 'auto',
padding: '8px',
animation: 'mobileMenuFadeIn 0.2s ease-out',
})}
onClick={(e) => {
// Close if clicking the backdrop
if (e.target === e.currentTarget) {
handleClose()
}
}}
>
<MenuContent
isFullscreen={isFullscreen}
isArcadePage={isArcadePage}
pathname={pathname}
toggleFullscreen={toggleFullscreen}
router={router}
onNavigate={handleClose}
handleNestedDropdownChange={handleNestedDropdownChange}
isMobile={true}
/>
</div>
<style
dangerouslySetInnerHTML={{
__html: `
@keyframes mobileMenuFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
`,
}}
/>
</>,
document.body
)}
</>
)
}
// Desktop dropdown menu
return (
<DropdownMenu.Root open={isOpen} onOpenChange={handleOpenChange}>
<DropdownMenu.Trigger asChild>
<button
type="button"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={{
display: 'flex',
alignItems: 'center',
@ -145,8 +491,6 @@ function HamburgerMenu({
side="bottom"
align="start"
sideOffset={8}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onInteractOutside={(e) => {
// Don't close the hamburger menu when clicking inside the nested style dropdown
const target = e.target as HTMLElement
@ -157,7 +501,7 @@ function HamburgerMenu({
e.preventDefault()
}
}}
style={{
className={css({
background: 'linear-gradient(135deg, rgba(17, 24, 39, 0.97), rgba(31, 41, 55, 0.97))',
backdropFilter: 'blur(12px)',
borderRadius: '12px',
@ -166,342 +510,17 @@ function HamburgerMenu({
minWidth: '220px',
zIndex: Z_INDEX.GAME_NAV.HAMBURGER_MENU,
animation: 'dropdownFadeIn 0.2s ease-out',
}}
})}
>
{/* Site Navigation Section */}
<div
style={{
fontSize: '10px',
fontWeight: '600',
color: 'rgba(196, 181, 253, 0.7)',
marginBottom: '6px',
marginLeft: '12px',
textTransform: 'uppercase',
letterSpacing: '0.5px',
}}
>
Navigation
</div>
<DropdownMenu.Item asChild>
<Link
href="/"
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
textDecoration: 'none',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(139, 92, 246, 0.2)'
e.currentTarget.style.color = 'rgba(196, 181, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>🧮</span>
<span>Home</span>
</Link>
</DropdownMenu.Item>
<DropdownMenu.Item asChild>
<Link
href="/create"
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
textDecoration: 'none',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(139, 92, 246, 0.2)'
e.currentTarget.style.color = 'rgba(196, 181, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}></span>
<span>Create</span>
</Link>
</DropdownMenu.Item>
<DropdownMenu.Item asChild>
<Link
href="/guide"
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
textDecoration: 'none',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(139, 92, 246, 0.2)'
e.currentTarget.style.color = 'rgba(196, 181, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>📖</span>
<span>Guide</span>
</Link>
</DropdownMenu.Item>
<DropdownMenu.Item asChild>
<Link
href="/games"
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
textDecoration: 'none',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(139, 92, 246, 0.2)'
e.currentTarget.style.color = 'rgba(196, 181, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>🎮</span>
<span>Games</span>
</Link>
</DropdownMenu.Item>
<DropdownMenu.Item asChild>
<Link
href="/blog"
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
textDecoration: 'none',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(139, 92, 246, 0.2)'
e.currentTarget.style.color = 'rgba(196, 181, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>📝</span>
<span>Blog</span>
</Link>
</DropdownMenu.Item>
<DropdownMenu.Separator
style={{
height: '1px',
background: 'rgba(75, 85, 99, 0.5)',
margin: '6px 0',
}}
<MenuContent
isFullscreen={isFullscreen}
isArcadePage={isArcadePage}
pathname={pathname}
toggleFullscreen={toggleFullscreen}
router={router}
handleNestedDropdownChange={handleNestedDropdownChange}
isMobile={false}
/>
{/* Controls Section */}
<div
style={{
fontSize: '10px',
fontWeight: '600',
color: 'rgba(196, 181, 253, 0.7)',
marginBottom: '6px',
marginLeft: '12px',
marginTop: '6px',
textTransform: 'uppercase',
letterSpacing: '0.5px',
}}
>
Controls
</div>
<DropdownMenu.Item
onSelect={toggleFullscreen}
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(59, 130, 246, 0.2)'
e.currentTarget.style.color = 'rgba(147, 197, 253, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>{isFullscreen ? '🪟' : '⛶'}</span>
<span>{isFullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}</span>
</DropdownMenu.Item>
{isArcadePage && (
<DropdownMenu.Item
onSelect={() => router.push('/games')}
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '10px 14px',
borderRadius: '8px',
color: 'rgba(209, 213, 219, 1)',
fontSize: '14px',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.2s ease',
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'rgba(239, 68, 68, 0.2)'
e.currentTarget.style.color = 'rgba(252, 165, 165, 1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent'
e.currentTarget.style.color = 'rgba(209, 213, 219, 1)'
}}
>
<span style={{ fontSize: '16px' }}>🚪</span>
<span>Exit Arcade</span>
</DropdownMenu.Item>
)}
<DropdownMenu.Separator
style={{
height: '1px',
background: 'rgba(75, 85, 99, 0.5)',
margin: '6px 0',
}}
/>
{/* Style Section */}
<div
style={{
fontSize: '10px',
fontWeight: '600',
color: 'rgba(196, 181, 253, 0.7)',
marginBottom: '6px',
marginLeft: '12px',
marginTop: '6px',
textTransform: 'uppercase',
letterSpacing: '0.5px',
}}
>
Abacus Style
</div>
<div
style={{ padding: '0 6px' }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<AbacusDisplayDropdown
isFullscreen={isFullscreen}
onOpenChange={handleNestedDropdownChange}
/>
</div>
<DropdownMenu.Separator
style={{
height: '1px',
background: 'rgba(75, 85, 99, 0.5)',
margin: '6px 0',
}}
/>
{/* Language Section */}
<div
style={{
fontSize: '10px',
fontWeight: '600',
color: 'rgba(196, 181, 253, 0.7)',
marginBottom: '6px',
marginLeft: '12px',
marginTop: '6px',
textTransform: 'uppercase',
letterSpacing: '0.5px',
}}
>
Language
</div>
<div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<LanguageSelector variant="dropdown-item" isFullscreen={isFullscreen} />
</div>
<DropdownMenu.Separator
style={{
height: '1px',
background: 'rgba(75, 85, 99, 0.5)',
margin: '6px 0',
}}
/>
{/* Theme Section */}
<div
style={{
fontSize: '10px',
fontWeight: '600',
color: 'rgba(196, 181, 253, 0.7)',
marginBottom: '6px',
marginLeft: '12px',
marginTop: '6px',
textTransform: 'uppercase',
letterSpacing: '0.5px',
}}
>
Theme
</div>
<div
style={{ padding: '0 6px' }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<ThemeToggle />
</div>
</DropdownMenu.Content>
</DropdownMenu.Portal>
@ -773,23 +792,38 @@ export function AppNavBar({ variant = 'full', navSlot }: AppNavBarProps) {
)}
<div className={hstack({ gap: '6', alignItems: 'center' })}>
{/* Navigation Links */}
{/* Navigation Links - progressively hide as viewport narrows */}
<nav className={hstack({ gap: '4' })}>
<NavLink href="/create" currentPath={pathname} isTransparent={isTransparent}>
Create
</NavLink>
<NavLink href="/guide" currentPath={pathname} isTransparent={isTransparent}>
Guide
</NavLink>
<NavLink href="/games" currentPath={pathname} isTransparent={isTransparent}>
Games
</NavLink>
<NavLink href="/blog" currentPath={pathname} isTransparent={isTransparent}>
Blog
</NavLink>
{/* Create - always visible when nav is shown */}
<div className={css({ display: { base: 'none', sm: 'block' } })}>
<NavLink href="/create" currentPath={pathname} isTransparent={isTransparent}>
Create
</NavLink>
</div>
{/* Guide - hidden below md breakpoint */}
<div className={css({ display: { base: 'none', md: 'block' } })}>
<NavLink href="/guide" currentPath={pathname} isTransparent={isTransparent}>
Guide
</NavLink>
</div>
{/* Games - hidden below lg breakpoint */}
<div className={css({ display: { base: 'none', lg: 'block' } })}>
<NavLink href="/games" currentPath={pathname} isTransparent={isTransparent}>
Games
</NavLink>
</div>
{/* Blog - hidden below xl breakpoint */}
<div className={css({ display: { base: 'none', xl: 'block' } })}>
<NavLink href="/blog" currentPath={pathname} isTransparent={isTransparent}>
Blog
</NavLink>
</div>
</nav>
{/* Hamburger Menu */}
{/* Hamburger Menu - always visible, contains all links that don't fit */}
<HamburgerMenu
isFullscreen={false}
isArcadePage={false}