feat: Animated pixel art ocean floor background for FloatingTranscriptDebug
Replace galaxy background with animated underwater scene featuring water depth gradient, pixel art sea floor (sand, seaweed, coral, starfish), rising bubbles with water sway, and swimming pixel art fish. Also update transcript-debug tool cards styling and add .claude-*/tasks/ to gitignore.
This commit is contained in:
@@ -4,6 +4,12 @@ import type { ParsedUserMessage } from '@/types/transcript-debug'
|
||||
|
||||
const props = defineProps<{
|
||||
message: ParsedUserMessage
|
||||
collapsed?: boolean
|
||||
sectionCount?: number
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
toggleCollapse: []
|
||||
}>()
|
||||
|
||||
const isOptimistic = computed(() => props.message.uuid.startsWith('optimistic-'))
|
||||
@@ -15,57 +21,151 @@ function formatTime(ts: string): string {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="['user-bubble', { meta: message.isMeta, optimistic: isOptimistic }]">
|
||||
<div class="bubble-header">
|
||||
<span class="role-badge">User</span>
|
||||
<span v-if="message.isMeta" class="meta-badge">meta</span>
|
||||
<span v-if="isOptimistic" class="sending-badge">
|
||||
<span class="sending-dot"></span>
|
||||
<span class="sending-dot"></span>
|
||||
<span class="sending-dot"></span>
|
||||
Sending
|
||||
</span>
|
||||
<span class="timestamp">{{ formatTime(message.timestamp) }}</span>
|
||||
<div :class="['user-divider', { meta: message.isMeta, optimistic: isOptimistic }]">
|
||||
<div class="divider-line" />
|
||||
<div class="divider-content">
|
||||
<div class="divider-header">
|
||||
<span class="role-badge">User</span>
|
||||
<span v-if="message.isMeta" class="meta-badge">meta</span>
|
||||
<span v-if="isOptimistic" class="sending-badge">
|
||||
<span class="sending-dot"></span>
|
||||
<span class="sending-dot"></span>
|
||||
<span class="sending-dot"></span>
|
||||
Sending
|
||||
</span>
|
||||
<button
|
||||
v-if="sectionCount && sectionCount > 0"
|
||||
:class="['collapse-btn', { collapsed }]"
|
||||
@click.stop="emit('toggleCollapse')"
|
||||
:title="collapsed ? 'Expand section' : 'Collapse section'"
|
||||
>
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline :points="collapsed ? '9 18 15 12 9 6' : '6 9 12 15 18 9'" />
|
||||
</svg>
|
||||
<span v-if="collapsed" class="collapse-count">{{ sectionCount }}</span>
|
||||
</button>
|
||||
<span class="timestamp">{{ formatTime(message.timestamp) }}</span>
|
||||
</div>
|
||||
<div class="divider-text">{{ message.content }}</div>
|
||||
</div>
|
||||
<div class="bubble-content">{{ message.content }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.user-bubble {
|
||||
.user-divider {
|
||||
width: 100%;
|
||||
margin: 0.75rem 0 0.25rem;
|
||||
}
|
||||
|
||||
.divider-line {
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.2) 10%, rgba(129, 140, 248, 0.2) 90%, transparent);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.divider-content {
|
||||
padding: 0 0.25rem;
|
||||
}
|
||||
|
||||
.divider-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.role-badge {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
color: #818cf8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.meta-badge {
|
||||
font-size: 9px;
|
||||
padding: 0.05rem 0.3rem;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
color: rgba(251, 191, 36, 0.7);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
margin-left: auto;
|
||||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||||
}
|
||||
|
||||
.divider-text {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
/* Meta messages: dimmed */
|
||||
.user-divider.meta {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.user-divider.meta .divider-line {
|
||||
background: linear-gradient(90deg, transparent, rgba(251, 191, 36, 0.15) 10%, rgba(251, 191, 36, 0.15) 90%, transparent);
|
||||
}
|
||||
|
||||
/* Collapse button */
|
||||
.collapse-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 1px 4px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
padding: 0.75rem 1rem;
|
||||
margin-left: 2rem;
|
||||
transition: opacity 0.3s, border-color 0.3s, background 0.3s;
|
||||
}
|
||||
|
||||
.user-bubble.meta {
|
||||
opacity: 0.5;
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
/* Optimistic / sending state */
|
||||
.user-bubble.optimistic {
|
||||
opacity: 0.7;
|
||||
border-color: rgba(99, 102, 241, 0.08);
|
||||
border-style: dashed;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: var(--text-muted);
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.collapse-btn:hover {
|
||||
background: rgba(129, 140, 248, 0.1);
|
||||
color: #818cf8;
|
||||
}
|
||||
|
||||
.collapse-btn svg {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.collapse-count {
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
color: var(--text-muted);
|
||||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||||
}
|
||||
|
||||
.collapse-btn:hover .collapse-count {
|
||||
color: #818cf8;
|
||||
}
|
||||
|
||||
/* Optimistic / sending */
|
||||
.user-divider.optimistic {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.user-divider.optimistic .divider-line {
|
||||
background: linear-gradient(90deg, transparent, rgba(99, 102, 241, 0.1) 10%, rgba(99, 102, 241, 0.1) 90%, transparent);
|
||||
}
|
||||
|
||||
.sending-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
font-size: 10px;
|
||||
font-size: 9px;
|
||||
color: var(--accent, #6366f1);
|
||||
font-weight: 500;
|
||||
padding: 0.1rem 0.4rem;
|
||||
border-radius: 4px;
|
||||
background: rgba(99, 102, 241, 0.08);
|
||||
}
|
||||
|
||||
.sending-dot {
|
||||
@@ -83,42 +183,4 @@ function formatTime(ts: string): string {
|
||||
0%, 80%, 100% { opacity: 0.2; }
|
||||
40% { opacity: 1; }
|
||||
}
|
||||
|
||||
.bubble-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.role-badge {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #818cf8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.meta-badge {
|
||||
font-size: 10px;
|
||||
padding: 0.1rem 0.4rem;
|
||||
border-radius: 4px;
|
||||
background: rgba(251, 191, 36, 0.15);
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-left: auto;
|
||||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||||
}
|
||||
|
||||
.bubble-content {
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: var(--text-primary);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user