fix: early name validation, fighter glow, reduced visual noise

- Add /api/auth/check-name endpoint for early name availability check
- JoinBoutPage checks name availability at naming step (not after webhook)
- FightCardPage: replace poster containers with circular glow behind sprites
- Reduce synthwave grid and CRT overlay opacity for cleaner backgrounds
- BotProfilePage: webhook management, owner-only fields
- useNostr: normalize bot data, guard auto-restore, clearAllState helper
- bots.ts: expose owner-only webhook info on stats endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-08 11:03:16 +00:00
co-authored by Claude Opus 4.6
parent 2d8cdcc60a
commit 9a11c48487
7 changed files with 405 additions and 120 deletions
+42 -20
View File
@@ -2,7 +2,6 @@
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { RouterLink } from 'vue-router'
import SpritePreview from '../components/SpritePreview.vue'
import PosterSprite from '../components/PosterSprite.vue'
import PixelGlove from '../components/PixelGlove.vue'
interface BotInfo {
@@ -195,32 +194,34 @@ onUnmounted(() => {
<!-- Sprites -->
<div class="flex items-end justify-center w-full max-w-4xl">
<div class="flex-1 flex flex-col items-center min-w-0">
<PosterSprite
v-if="fighterA"
:key="`a-${featured.id}-${fighterA.avatarSeed}`"
:seed="fighterA.avatarSeed || fighterA.name"
:archetype="fighterA.archetype || 'standard'"
:tier="fighterA.tier"
:size="160"
pose="win"
glow-color="cyan"
class="relative z-10 fighter-bob
sm:!w-[240px] sm:!h-[240px] lg:!w-[340px] lg:!h-[340px]"
/>
<div v-if="fighterA" class="relative fighter-bob">
<!-- Circular glow behind fighter -->
<div class="fighter-glow fighter-glow-cyan" />
<SpritePreview
:key="`a-${featured.id}-${fighterA.avatarSeed}`"
:seed="fighterA.avatarSeed || fighterA.name"
:archetype="fighterA.archetype || 'standard'"
:tier="fighterA.tier"
:size="120"
pose="win"
class="relative z-10
sm:!w-[180px] sm:!h-[180px] lg:!w-[260px] lg:!h-[260px]"
/>
</div>
</div>
<div class="flex-1 flex flex-col items-center min-w-0 -ml-6 sm:-ml-12 lg:-ml-20">
<div style="transform: scaleX(-1)">
<PosterSprite
v-if="fighterB"
<div v-if="fighterB" class="relative fighter-bob-delayed" style="transform: scaleX(-1)">
<!-- Circular glow behind fighter -->
<div class="fighter-glow fighter-glow-pink" />
<SpritePreview
:key="`b-${featured.id}-${fighterB.avatarSeed}`"
:seed="fighterB.avatarSeed || fighterB.name"
:archetype="fighterB.archetype || 'standard'"
:tier="fighterB.tier"
:size="160"
:size="120"
pose="idle"
glow-color="pink"
class="relative z-10 fighter-bob-delayed
sm:!w-[240px] sm:!h-[240px] lg:!w-[340px] lg:!h-[340px]"
class="relative z-10
sm:!w-[180px] sm:!h-[180px] lg:!w-[260px] lg:!h-[260px]"
/>
</div>
</div>
@@ -557,6 +558,27 @@ onUnmounted(() => {
animation: punchRight 2s ease-in-out infinite 0.3s;
}
/* Circular glow behind fighters */
.fighter-glow {
position: absolute;
top: 50%;
left: 50%;
width: 140%;
height: 140%;
transform: translate(-50%, -50%);
border-radius: 50%;
pointer-events: none;
z-index: 0;
}
.fighter-glow-cyan {
background: radial-gradient(circle, rgba(0, 240, 255, 0.25) 0%, rgba(0, 240, 255, 0.10) 35%, rgba(0, 240, 255, 0.03) 60%, transparent 80%);
box-shadow: 0 0 60px rgba(0, 240, 255, 0.15), 0 0 120px rgba(0, 240, 255, 0.05);
}
.fighter-glow-pink {
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 bobbing */
.fighter-bob {
animation: fighterBob 2.5s ease-in-out infinite;