fix(know-your-world): improve mobile layout for setup screen
- Fix broken CSS by simplifying breadcrumb styles - Stack breadcrumbs vertically on phones to avoid overlap with region selector - Shrink mode/guidance menus on phones (64px → 48px height) - Scale region size selector to 75% on phones - Remove complex calc() and alpha channel values causing issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
02762fad81
commit
81b44a6422
|
|
@ -90,7 +90,13 @@ const PLANETS: PlanetData[] = [
|
|||
{ id: 'mercury', name: 'Mercury', color: '#b0b0b0', size: 0.38 },
|
||||
{ id: 'venus', name: 'Venus', color: '#e6c87a', size: 0.95 },
|
||||
{ id: 'mars', name: 'Mars', color: '#c1440e', size: 0.53 },
|
||||
{ id: 'jupiter', name: 'Jupiter', color: '#d8ca9d', size: 2.0, hasStripes: true },
|
||||
{
|
||||
id: 'jupiter',
|
||||
name: 'Jupiter',
|
||||
color: '#d8ca9d',
|
||||
size: 2.0,
|
||||
hasStripes: true,
|
||||
},
|
||||
{ id: 'saturn', name: 'Saturn', color: '#ead6b8', size: 1.7, hasRings: true },
|
||||
]
|
||||
|
||||
|
|
@ -152,7 +158,10 @@ export function DrillDownMapSelector({
|
|||
const [sizeRangePreview, setSizeRangePreview] = useState<RangePreviewState<RegionSize> | null>(
|
||||
null
|
||||
)
|
||||
const [containerDimensions, setContainerDimensions] = useState({ width: 0, height: 0 })
|
||||
const [containerDimensions, setContainerDimensions] = useState({
|
||||
width: 0,
|
||||
height: 0,
|
||||
})
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
// Track which region name is being hovered in the popover (for zoom preview)
|
||||
const [previewRegionName, setPreviewRegionName] = useState<string | null>(null)
|
||||
|
|
@ -477,7 +486,10 @@ export function DrillDownMapSelector({
|
|||
}
|
||||
}
|
||||
|
||||
return { previewAddRegions: addRegions, previewRemoveRegions: removeRegions }
|
||||
return {
|
||||
previewAddRegions: addRegions,
|
||||
previewRemoveRegions: removeRegions,
|
||||
}
|
||||
}, [sizeRangePreview, currentLevel, path, selectedContinent, includeSizes])
|
||||
|
||||
// Compute the label to display for the hovered region
|
||||
|
|
@ -634,7 +646,12 @@ export function DrillDownMapSelector({
|
|||
}
|
||||
: null
|
||||
})
|
||||
.filter(Boolean) as Array<{ id: string; label: string; emoji: string; path: SelectionPath }>
|
||||
.filter(Boolean) as Array<{
|
||||
id: string
|
||||
label: string
|
||||
emoji: string
|
||||
path: SelectionPath
|
||||
}>
|
||||
}
|
||||
|
||||
return []
|
||||
|
|
@ -761,205 +778,76 @@ export function DrillDownMapSelector({
|
|||
>
|
||||
{/* Breadcrumb Navigation - different styles for fillContainer vs normal */}
|
||||
{fillContainer ? (
|
||||
/* Navigation breadcrumb - positioned well below nav bar */
|
||||
/* Breadcrumb navigation overlay for full-screen mode */
|
||||
<div
|
||||
data-element="navigation-overlay"
|
||||
className={css({
|
||||
position: 'absolute',
|
||||
top: 'calc(var(--app-nav-height, 92px) + 72px)',
|
||||
left: { base: '16px', sm: '24px' },
|
||||
top: '164px',
|
||||
left: { base: '12px', sm: '24px' },
|
||||
zIndex: 50,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '3',
|
||||
padding: '10px 16px',
|
||||
bg: isDark
|
||||
? 'linear-gradient(135deg, rgba(30, 41, 59, 0.95) 0%, rgba(15, 23, 42, 0.95) 100%)'
|
||||
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%)',
|
||||
backdropFilter: 'blur(12px)',
|
||||
border: '1px solid',
|
||||
borderColor: isDark ? 'rgba(71, 85, 105, 0.5)' : 'rgba(203, 213, 225, 0.8)',
|
||||
rounded: 'full',
|
||||
shadow: isDark
|
||||
? '0 4px 20px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05)'
|
||||
: '0 4px 20px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.8)',
|
||||
flexDirection: { base: 'column', sm: 'row' },
|
||||
alignItems: { base: 'flex-start', sm: 'center' },
|
||||
gap: { base: '1', sm: '2' },
|
||||
padding: '2',
|
||||
bg: isDark ? 'gray.800' : 'gray.100',
|
||||
rounded: 'xl',
|
||||
shadow: 'lg',
|
||||
fontSize: 'sm',
|
||||
})}
|
||||
>
|
||||
{currentLevel > 0 ? (
|
||||
<>
|
||||
{/* Back button with mini-map */}
|
||||
{(() => {
|
||||
const backToWorld = currentLevel === 1
|
||||
const backToContinentId = currentLevel === 2 ? path[0] : null
|
||||
const backLabel = backToWorld
|
||||
? 'World'
|
||||
: (CONTINENTS.find((c) => c.id === backToContinentId)?.name ?? 'Continent')
|
||||
const backEmoji = backToWorld
|
||||
? '🌍'
|
||||
: (CONTINENTS.find((c) => c.id === backToContinentId)?.emoji ?? '🗺️')
|
||||
|
||||
// Get viewBox and regions for the mini-map preview
|
||||
const backViewBox = backToWorld
|
||||
? WORLD_MAP.viewBox
|
||||
: backToContinentId
|
||||
? calculateContinentViewBox(
|
||||
WORLD_MAP.regions,
|
||||
backToContinentId,
|
||||
WORLD_MAP.viewBox,
|
||||
'world'
|
||||
)
|
||||
: WORLD_MAP.viewBox
|
||||
const backRegions = backToWorld
|
||||
? WORLD_MAP.regions
|
||||
: backToContinentId
|
||||
? filterRegionsByContinent(WORLD_MAP.regions, backToContinentId)
|
||||
: []
|
||||
|
||||
return (
|
||||
<button
|
||||
data-action="navigate-back"
|
||||
onClick={handleZoomOut}
|
||||
className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: '6px 12px 6px 8px',
|
||||
bg: isDark ? 'rgba(51, 65, 85, 0.6)' : 'rgba(241, 245, 249, 0.8)',
|
||||
border: '1px solid',
|
||||
borderColor: isDark ? 'rgba(71, 85, 105, 0.4)' : 'rgba(203, 213, 225, 0.6)',
|
||||
rounded: 'full',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.2s ease',
|
||||
_hover: {
|
||||
bg: isDark ? 'rgba(71, 85, 105, 0.7)' : 'rgba(226, 232, 240, 0.9)',
|
||||
transform: 'translateX(-2px)',
|
||||
},
|
||||
})}
|
||||
{breadcrumbs.map((crumb, index) => (
|
||||
<span
|
||||
key={crumb.label}
|
||||
className={css({ display: 'flex', alignItems: 'center', gap: '1' })}
|
||||
>
|
||||
{/* Mini-map preview */}
|
||||
<div
|
||||
className={css({
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
rounded: 'full',
|
||||
overflow: 'hidden',
|
||||
border: '2px solid',
|
||||
borderColor: isDark ? 'rgba(100, 116, 139, 0.5)' : 'rgba(203, 213, 225, 0.8)',
|
||||
boxShadow: 'inset 0 1px 3px rgba(0,0,0,0.1)',
|
||||
})}
|
||||
>
|
||||
<svg
|
||||
viewBox={backViewBox}
|
||||
className={css({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'block',
|
||||
})}
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
>
|
||||
<rect
|
||||
x="-10000"
|
||||
y="-10000"
|
||||
width="30000"
|
||||
height="30000"
|
||||
fill={isDark ? '#1e3a5f' : '#bae6fd'}
|
||||
/>
|
||||
{backRegions.map((region) => (
|
||||
<path
|
||||
key={region.id}
|
||||
d={region.path}
|
||||
fill={isDark ? '#64748b' : '#a8d4a8'}
|
||||
stroke={isDark ? '#475569' : '#86b386'}
|
||||
strokeWidth={0.3}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
</div>
|
||||
<div className={css({ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' })}>
|
||||
{index > 0 && (
|
||||
<span
|
||||
className={css({
|
||||
fontSize: '10px',
|
||||
fontWeight: '500',
|
||||
color: isDark ? 'gray.400' : 'gray.500',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.05em',
|
||||
lineHeight: 1,
|
||||
color: isDark ? 'gray.500' : 'gray.400',
|
||||
display: { base: 'none', sm: 'inline' },
|
||||
})}
|
||||
>
|
||||
Back to
|
||||
›
|
||||
</span>
|
||||
<span
|
||||
className={css({
|
||||
fontSize: '13px',
|
||||
fontWeight: '600',
|
||||
color: isDark ? 'gray.200' : 'gray.700',
|
||||
lineHeight: 1.2,
|
||||
})}
|
||||
>
|
||||
{backEmoji} {backLabel}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
})()}
|
||||
|
||||
{/* Current location badge */}
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
padding: '6px 14px',
|
||||
bg: isDark
|
||||
? 'linear-gradient(135deg, rgba(59, 130, 246, 0.2) 0%, rgba(139, 92, 246, 0.2) 100%)'
|
||||
: 'linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%)',
|
||||
border: '1px solid',
|
||||
borderColor: isDark ? 'rgba(59, 130, 246, 0.3)' : 'rgba(59, 130, 246, 0.2)',
|
||||
rounded: 'full',
|
||||
})}
|
||||
>
|
||||
<span className={css({ fontSize: 'md' })}>
|
||||
{breadcrumbs[breadcrumbs.length - 1]?.emoji}
|
||||
</span>
|
||||
<span
|
||||
className={css({
|
||||
fontSize: '14px',
|
||||
fontWeight: '600',
|
||||
color: isDark ? 'white' : 'gray.800',
|
||||
})}
|
||||
>
|
||||
{breadcrumbs[breadcrumbs.length - 1]?.label}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
/* World level - current location badge */
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
padding: '6px 14px',
|
||||
bg: isDark
|
||||
? 'linear-gradient(135deg, rgba(59, 130, 246, 0.2) 0%, rgba(139, 92, 246, 0.2) 100%)'
|
||||
: 'linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%)',
|
||||
border: '1px solid',
|
||||
borderColor: isDark ? 'rgba(59, 130, 246, 0.3)' : 'rgba(59, 130, 246, 0.2)',
|
||||
rounded: 'full',
|
||||
})}
|
||||
>
|
||||
<span className={css({ fontSize: 'md' })}>🌍</span>
|
||||
<span
|
||||
className={css({
|
||||
fontSize: '14px',
|
||||
fontWeight: '600',
|
||||
color: isDark ? 'white' : 'gray.800',
|
||||
})}
|
||||
>
|
||||
World
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{crumb.isClickable ? (
|
||||
<button
|
||||
data-action={`nav-${crumb.label.toLowerCase().replace(/\s/g, '-')}`}
|
||||
onClick={() => handleBreadcrumbClick(crumb.path)}
|
||||
className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '1',
|
||||
color: isDark ? 'blue.400' : 'blue.600',
|
||||
cursor: 'pointer',
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
padding: '0',
|
||||
font: 'inherit',
|
||||
_hover: { textDecoration: 'underline' },
|
||||
})}
|
||||
>
|
||||
<span>{crumb.emoji}</span>
|
||||
<span>{crumb.label}</span>
|
||||
</button>
|
||||
) : (
|
||||
<span
|
||||
className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '1',
|
||||
fontWeight: 'bold',
|
||||
color: isDark ? 'gray.100' : 'gray.800',
|
||||
})}
|
||||
>
|
||||
<span>{crumb.emoji}</span>
|
||||
<span>{crumb.label}</span>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
/* Normal breadcrumb for non-fillContainer mode */
|
||||
|
|
@ -977,7 +865,11 @@ export function DrillDownMapSelector({
|
|||
{breadcrumbs.map((crumb, index) => (
|
||||
<span
|
||||
key={crumb.label}
|
||||
className={css({ display: 'flex', alignItems: 'center', gap: '1' })}
|
||||
className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '1',
|
||||
})}
|
||||
>
|
||||
{index > 0 && (
|
||||
<span className={css({ color: isDark ? 'gray.500' : 'gray.400' })}>›</span>
|
||||
|
|
@ -1153,20 +1045,15 @@ export function DrillDownMapSelector({
|
|||
data-element="region-size-filters"
|
||||
className={css({
|
||||
position: 'absolute',
|
||||
top: fillContainer ? 'calc(var(--app-nav-height, 92px) + 72px)' : '3',
|
||||
right: { base: '16px', sm: '24px' },
|
||||
padding: '12px',
|
||||
bg: isDark
|
||||
? 'linear-gradient(135deg, rgba(30, 41, 59, 0.95) 0%, rgba(15, 23, 42, 0.95) 100%)'
|
||||
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%)',
|
||||
backdropFilter: 'blur(12px)',
|
||||
border: '1px solid',
|
||||
borderColor: isDark ? 'rgba(71, 85, 105, 0.5)' : 'rgba(203, 213, 225, 0.8)',
|
||||
top: fillContainer ? '164px' : '3',
|
||||
right: { base: '8px', sm: '24px' },
|
||||
padding: { base: '2', sm: '3' },
|
||||
bg: isDark ? 'gray.800' : 'gray.100',
|
||||
rounded: 'xl',
|
||||
shadow: isDark
|
||||
? '0 4px 20px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05)'
|
||||
: '0 4px 20px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.8)',
|
||||
shadow: 'lg',
|
||||
zIndex: 10,
|
||||
transform: { base: 'scale(0.75)', sm: 'scale(1)' },
|
||||
transformOrigin: 'top right',
|
||||
})}
|
||||
>
|
||||
<RangeThermometer
|
||||
|
|
|
|||
|
|
@ -184,14 +184,14 @@ export function SetupPhase() {
|
|||
const cardTriggerStyles = css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: { base: '2', sm: '3' },
|
||||
padding: { base: '2', sm: '3' },
|
||||
gap: { base: '1.5', sm: '3' },
|
||||
padding: { base: '1.5', sm: '3' },
|
||||
bg: isDark ? 'gray.700/80' : 'white/80',
|
||||
rounded: 'xl',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.15s',
|
||||
width: { base: 'calc(50% - 4px)', sm: '260px' },
|
||||
height: { base: '64px', sm: '88px' },
|
||||
height: { base: '48px', sm: '88px' },
|
||||
textAlign: 'left',
|
||||
_hover: {
|
||||
bg: isDark ? 'gray.600/90' : 'white',
|
||||
|
|
@ -283,7 +283,12 @@ export function SetupPhase() {
|
|||
onValueChange={(value) => setMode(value as 'cooperative' | 'race' | 'turn-based')}
|
||||
>
|
||||
<Select.Trigger className={cardTriggerStyles}>
|
||||
<span className={css({ fontSize: { base: 'xl', sm: '2xl' }, flexShrink: 0 })}>
|
||||
<span
|
||||
className={css({
|
||||
fontSize: { base: 'lg', sm: '2xl' },
|
||||
flexShrink: 0,
|
||||
})}
|
||||
>
|
||||
{selectedMode?.emoji}
|
||||
</span>
|
||||
<div className={css({ flex: 1, minWidth: 0 })}>
|
||||
|
|
@ -304,7 +309,10 @@ export function SetupPhase() {
|
|||
{selectedMode?.label}
|
||||
</span>
|
||||
<Select.Icon
|
||||
className={css({ color: isDark ? 'gray.400' : 'gray.500', fontSize: 'xs' })}
|
||||
className={css({
|
||||
color: isDark ? 'gray.400' : 'gray.500',
|
||||
fontSize: 'xs',
|
||||
})}
|
||||
>
|
||||
▼
|
||||
</Select.Icon>
|
||||
|
|
@ -365,7 +373,12 @@ export function SetupPhase() {
|
|||
}
|
||||
>
|
||||
<Select.Trigger className={cardTriggerStyles}>
|
||||
<span className={css({ fontSize: { base: 'xl', sm: '2xl' }, flexShrink: 0 })}>
|
||||
<span
|
||||
className={css({
|
||||
fontSize: { base: 'lg', sm: '2xl' },
|
||||
flexShrink: 0,
|
||||
})}
|
||||
>
|
||||
{selectedAssistance?.emoji || '💡'}
|
||||
</span>
|
||||
<div className={css({ flex: 1, minWidth: 0 })}>
|
||||
|
|
@ -386,7 +399,10 @@ export function SetupPhase() {
|
|||
{selectedAssistance?.label}
|
||||
</span>
|
||||
<Select.Icon
|
||||
className={css({ color: isDark ? 'gray.400' : 'gray.500', fontSize: 'xs' })}
|
||||
className={css({
|
||||
color: isDark ? 'gray.400' : 'gray.500',
|
||||
fontSize: 'xs',
|
||||
})}
|
||||
>
|
||||
▼
|
||||
</Select.Icon>
|
||||
|
|
@ -578,7 +594,12 @@ export function SetupPhase() {
|
|||
})}
|
||||
>
|
||||
<span>{regionTheme.icons[0]}</span>
|
||||
<span className={css({ fontSize: { base: 'xs', sm: 'sm' }, marginTop: '-2px' })}>
|
||||
<span
|
||||
className={css({
|
||||
fontSize: { base: 'xs', sm: 'sm' },
|
||||
marginTop: '-2px',
|
||||
})}
|
||||
>
|
||||
{regionTheme.icons[1]}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue