fix: viewport-fixed layout on all pages for mobile
- Replace 100vh with 100dvh everywhere (accounts for mobile browser chrome) - DocsPage: viewport-fixed with tabs pinned, tab content scrolls internally - BotProfilePage: overflow-hidden outer, internal scroll container - JoinBoutPage: viewport-fixed with internal overflow scroll - HumanFightPage: viewport-fixed, flex-1 content area with internal scroll - All other pages: vh → dvh for correct mobile sizing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
8a345f5e56
commit
896e81960f
@@ -59,6 +59,22 @@ const tierColors: Record<number, string> = {
|
||||
0: '#8a8a9a', 1: '#4ade80', 2: '#38bdf8', 3: '#a855f7', 4: '#f97316', 5: '#ef4444',
|
||||
}
|
||||
|
||||
function isCreator(bot: BotInfo | null): boolean {
|
||||
return bot?.archetype === 'the_creator'
|
||||
}
|
||||
|
||||
function getTierName(bot: BotInfo | null): string {
|
||||
if (!bot) return ''
|
||||
if (isCreator(bot)) return '₿ CREATOR'
|
||||
return tierNames[bot.tier ?? 0]
|
||||
}
|
||||
|
||||
function getTierColor(bot: BotInfo | null): string {
|
||||
if (!bot) return '#8a8a9a'
|
||||
if (isCreator(bot)) return '#ffd700'
|
||||
return tierColors[bot.tier ?? 0]
|
||||
}
|
||||
|
||||
function selectFight(fightId: string) {
|
||||
const fight = fights.value.find(f => f.id === fightId)
|
||||
if (!fight || !fight.botA || !fight.botB) return
|
||||
@@ -95,7 +111,7 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-[calc(100vh-4rem)] flex flex-col overflow-hidden relative">
|
||||
<div class="h-[calc(100dvh-4rem)] flex flex-col overflow-hidden relative">
|
||||
|
||||
<!-- Page background -->
|
||||
<div class="absolute inset-0 overflow-hidden pointer-events-none">
|
||||
@@ -196,7 +212,7 @@ onUnmounted(() => {
|
||||
<div class="flex-1 flex flex-col items-center min-w-0">
|
||||
<div v-if="fighterA" class="relative fighter-bob">
|
||||
<!-- Circular glow behind fighter -->
|
||||
<div class="fighter-glow fighter-glow-cyan" />
|
||||
<div class="fighter-glow" :class="isCreator(fighterA) ? 'fighter-glow-gold' : 'fighter-glow-cyan'" />
|
||||
<SpritePreview
|
||||
:key="`a-${featured.id}-${fighterA.avatarSeed}`"
|
||||
:seed="fighterA.avatarSeed || fighterA.name"
|
||||
@@ -212,7 +228,7 @@ onUnmounted(() => {
|
||||
<div class="flex-1 flex flex-col items-center min-w-0 -ml-6 sm:-ml-12 lg:-ml-20">
|
||||
<div v-if="fighterB" class="relative fighter-bob-delayed" style="transform: scaleX(-1)">
|
||||
<!-- Circular glow behind fighter -->
|
||||
<div class="fighter-glow fighter-glow-pink" />
|
||||
<div class="fighter-glow" :class="isCreator(fighterB) ? 'fighter-glow-gold' : 'fighter-glow-pink'" />
|
||||
<SpritePreview
|
||||
:key="`b-${featured.id}-${fighterB.avatarSeed}`"
|
||||
:seed="fighterB.avatarSeed || fighterB.name"
|
||||
@@ -230,14 +246,16 @@ onUnmounted(() => {
|
||||
<!-- Names with VS orb in center -->
|
||||
<div class="flex items-stretch w-full max-w-3xl mt-1 sm:mt-2 lg:mt-3 shrink-0 relative">
|
||||
|
||||
<!-- Fighter A — cyan -->
|
||||
<div class="flex-1 min-w-0 name-block-cyan border-2 border-neon-cyan/40 rounded-l-lg px-2 sm:px-3 pr-16 sm:pr-20 lg:pr-24 py-1.5 sm:py-2 lg:py-3 text-center">
|
||||
<p class="font-funky text-base sm:text-2xl lg:text-4xl tracking-widest text-neon-cyan truncate pb-0.5 poster-name-cyan uppercase">
|
||||
<!-- Fighter A -->
|
||||
<div class="flex-1 min-w-0 border-2 rounded-l-lg px-2 sm:px-3 pr-16 sm:pr-20 lg:pr-24 py-1.5 sm:py-2 lg:py-3 text-center"
|
||||
:class="isCreator(fighterA) ? 'name-block-gold border-yellow-500/40' : 'name-block-cyan border-neon-cyan/40'">
|
||||
<p class="font-funky text-base sm:text-2xl lg:text-4xl tracking-widest truncate pb-0.5 uppercase"
|
||||
:class="isCreator(fighterA) ? 'text-yellow-400 poster-name-gold' : 'text-neon-cyan poster-name-cyan'">
|
||||
{{ fighterA?.name || '???' }}
|
||||
</p>
|
||||
<p class="font-pixel text-[6px] sm:text-[8px] lg:text-[11px] tracking-[0.2em]"
|
||||
:style="{ color: tierColors[fighterA?.tier ?? 0] }">
|
||||
{{ tierNames[fighterA?.tier ?? 0] }}
|
||||
:style="{ color: getTierColor(fighterA) }">
|
||||
{{ getTierName(fighterA) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -253,14 +271,16 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Fighter B — pink -->
|
||||
<div class="flex-1 min-w-0 name-block-pink border-2 border-neon-pink/40 border-l-0 rounded-r-lg px-2 sm:px-3 pl-16 sm:pl-20 lg:pl-24 py-1.5 sm:py-2 lg:py-3 text-center">
|
||||
<p class="font-funky text-base sm:text-2xl lg:text-4xl tracking-widest text-neon-pink truncate pb-0.5 poster-name-pink uppercase">
|
||||
<!-- Fighter B -->
|
||||
<div class="flex-1 min-w-0 border-2 border-l-0 rounded-r-lg px-2 sm:px-3 pl-16 sm:pl-20 lg:pl-24 py-1.5 sm:py-2 lg:py-3 text-center"
|
||||
:class="isCreator(fighterB) ? 'name-block-gold border-yellow-500/40' : 'name-block-pink border-neon-pink/40'">
|
||||
<p class="font-funky text-base sm:text-2xl lg:text-4xl tracking-widest truncate pb-0.5 uppercase"
|
||||
:class="isCreator(fighterB) ? 'text-yellow-400 poster-name-gold' : 'text-neon-pink poster-name-pink'">
|
||||
{{ fighterB?.name || '???' }}
|
||||
</p>
|
||||
<p class="font-pixel text-[6px] sm:text-[8px] lg:text-[11px] tracking-[0.2em]"
|
||||
:style="{ color: tierColors[fighterB?.tier ?? 0] }">
|
||||
{{ tierNames[fighterB?.tier ?? 0] }}
|
||||
:style="{ color: getTierColor(fighterB) }">
|
||||
{{ getTierName(fighterB) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -295,7 +315,10 @@ onUnmounted(() => {
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="flex-1 flex items-center justify-end gap-1.5 min-w-0">
|
||||
<p class="font-display font-bold text-xs text-neon-cyan truncate">{{ mainEvent.botA.name }}</p>
|
||||
<p class="font-display font-bold text-xs truncate"
|
||||
:class="isCreator(mainEvent.botA) ? 'text-yellow-400' : 'text-neon-cyan'">
|
||||
{{ isCreator(mainEvent.botA) ? '₿ ' : '' }}{{ mainEvent.botA.name }}
|
||||
</p>
|
||||
<SpritePreview
|
||||
:seed="mainEvent.botA.avatarSeed || mainEvent.botA.name"
|
||||
:archetype="mainEvent.botA.archetype || 'standard'"
|
||||
@@ -314,7 +337,10 @@ onUnmounted(() => {
|
||||
class="shrink-0"
|
||||
style="transform: scaleX(-1)"
|
||||
/>
|
||||
<p class="font-display font-bold text-xs text-neon-pink truncate">{{ mainEvent.botB.name }}</p>
|
||||
<p class="font-display font-bold text-xs truncate"
|
||||
:class="isCreator(mainEvent.botB) ? 'text-yellow-400' : 'text-neon-pink'">
|
||||
{{ mainEvent.botB.name }}{{ isCreator(mainEvent.botB) ? ' ₿' : '' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
@@ -346,8 +372,8 @@ onUnmounted(() => {
|
||||
>
|
||||
<div class="flex-1 flex items-center justify-end gap-1.5 min-w-0">
|
||||
<p class="font-display font-bold text-[11px] truncate"
|
||||
:class="fight.botA ? 'text-text-primary' : 'text-text-muted'">
|
||||
{{ fight.botA?.name || '???' }}
|
||||
:class="isCreator(fight.botA) ? 'text-yellow-400' : fight.botA ? 'text-text-primary' : 'text-text-muted'">
|
||||
{{ isCreator(fight.botA) ? '₿ ' : '' }}{{ fight.botA?.name || '???' }}
|
||||
</p>
|
||||
<SpritePreview
|
||||
v-if="fight.botA"
|
||||
@@ -370,8 +396,8 @@ onUnmounted(() => {
|
||||
style="transform: scaleX(-1)"
|
||||
/>
|
||||
<p class="font-display font-bold text-[11px] truncate"
|
||||
:class="fight.botB ? 'text-text-primary' : 'text-text-muted'">
|
||||
{{ fight.botB?.name || '???' }}
|
||||
:class="isCreator(fight.botB) ? 'text-yellow-400' : fight.botB ? 'text-text-primary' : 'text-text-muted'">
|
||||
{{ fight.botB?.name || '???' }}{{ isCreator(fight.botB) ? ' ₿' : '' }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-1.5 shrink-0">
|
||||
@@ -469,6 +495,14 @@ onUnmounted(() => {
|
||||
0 0 30px rgba(255, 45, 120, 0.3),
|
||||
0 0 60px rgba(255, 45, 120, 0.15);
|
||||
}
|
||||
.poster-name-gold {
|
||||
-webkit-text-stroke: 1px rgba(200, 160, 0, 0.6);
|
||||
text-shadow:
|
||||
2px 2px 0 rgba(130, 100, 0, 0.8),
|
||||
0 0 10px rgba(255, 215, 0, 0.6),
|
||||
0 0 30px rgba(255, 215, 0, 0.3),
|
||||
0 0 60px rgba(255, 180, 0, 0.15);
|
||||
}
|
||||
.poster-title {
|
||||
text-shadow:
|
||||
0 0 15px rgba(255, 45, 120, 0.6),
|
||||
@@ -483,6 +517,9 @@ onUnmounted(() => {
|
||||
.name-block-pink {
|
||||
background: linear-gradient(225deg, rgba(255, 45, 120, 0.08) 0%, rgba(255, 45, 120, 0.02) 100%);
|
||||
}
|
||||
.name-block-gold {
|
||||
background: linear-gradient(180deg, rgba(255, 215, 0, 0.12) 0%, rgba(255, 180, 0, 0.04) 100%);
|
||||
}
|
||||
|
||||
/* ═══ VS Orb — 3D circle ═══ */
|
||||
.vs-orb {
|
||||
@@ -578,6 +615,10 @@ onUnmounted(() => {
|
||||
background: radial-gradient(circle, rgba(255, 45, 120, 0.25) 0%, rgba(255, 45, 120, 0.10) 35%, rgba(255, 45, 120, 0.03) 60%, transparent 80%);
|
||||
box-shadow: 0 0 60px rgba(255, 45, 120, 0.15), 0 0 120px rgba(255, 45, 120, 0.05);
|
||||
}
|
||||
.fighter-glow-gold {
|
||||
background: radial-gradient(circle, rgba(255, 215, 0, 0.35) 0%, rgba(255, 215, 0, 0.15) 35%, rgba(255, 180, 0, 0.05) 60%, transparent 80%);
|
||||
box-shadow: 0 0 60px rgba(255, 215, 0, 0.25), 0 0 120px rgba(255, 215, 0, 0.10);
|
||||
}
|
||||
|
||||
/* Fighter bobbing */
|
||||
.fighter-bob {
|
||||
|
||||
Reference in New Issue
Block a user