feat: Pixel art ocean buttons and scrollbar-gutter stable

- FAB button: night ocean pixel art with stars, moon, waves, seaweed, coral
- Send button: daytime ocean pixel art with sun, clouds, fish, sand
- Scrollbar hides with chrome using scrollbar-gutter: stable to prevent content shift
This commit is contained in:
2026-02-19 15:36:35 -06:00
parent 18aaa0ee7b
commit f7391f83b4
2 changed files with 58 additions and 23 deletions

View File

@@ -523,15 +523,25 @@ watch(() => route.name, (newPage) => {
</template>
</button>
<!-- Transcript Debug FAB Button -->
<!-- Transcript Debug FAB Button (pixel art ocean) -->
<button
class="transcript-fab"
:class="{ active: showTranscriptDebug, 'sheet-open': showTerminal || showVoice || showTranscriptDebug, 'keyboard-visible': keyboardVisible }"
@click="showTranscriptDebug = !showTranscriptDebug"
title="Transcript Debug"
>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
<!-- Pixel art chat bubble icon -->
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" shape-rendering="crispEdges">
<rect x="4" y="2" width="12" height="2" fill="currentColor"/>
<rect x="2" y="4" width="2" height="8" fill="currentColor"/>
<rect x="16" y="4" width="2" height="8" fill="currentColor"/>
<rect x="4" y="12" width="12" height="2" fill="currentColor"/>
<rect x="4" y="14" width="2" height="2" fill="currentColor"/>
<rect x="2" y="16" width="2" height="2" fill="currentColor"/>
<!-- Dots inside -->
<rect x="6" y="7" width="2" height="2" fill="currentColor" opacity="0.5"/>
<rect x="9" y="7" width="2" height="2" fill="currentColor" opacity="0.5"/>
<rect x="12" y="7" width="2" height="2" fill="currentColor" opacity="0.5"/>
</svg>
</button>
@@ -1326,47 +1336,46 @@ watch(() => route.name, (newPage) => {
50% { box-shadow: 0 0 50px rgba(249, 115, 22, 0.9); }
}
/* Transcript Debug FAB */
/* Transcript Debug FAB — pixel art night ocean */
.transcript-fab {
position: fixed;
bottom: 20px;
left: 80px;
width: 44px;
height: 44px;
border-radius: 4px;
background: rgba(15, 15, 20, 0.85);
color: #818cf8;
border: 1px solid rgba(99, 102, 241, 0.2);
border-radius: 0;
background:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44' viewBox='0 0 44 44' shape-rendering='crispEdges'%3E%3Crect width='44' height='8' fill='%23050a14'/%3E%3Crect y='8' width='44' height='4' fill='%23061020'/%3E%3Crect y='12' width='44' height='4' fill='%23071828'/%3E%3Crect y='16' width='44' height='4' fill='%23081e30'/%3E%3Crect y='20' width='44' height='4' fill='%23092438'/%3E%3Crect y='24' width='44' height='4' fill='%230a2a3e'/%3E%3Crect y='28' width='44' height='4' fill='%23082030'/%3E%3Crect y='32' width='44' height='4' fill='%23061828'/%3E%3Crect y='36' width='44' height='8' fill='%231a1810'/%3E%3Crect x='34' y='2' width='3' height='3' fill='%23e8e4c8' opacity='0.6'/%3E%3Crect x='35' y='1' width='2' height='1' fill='%23e8e4c8' opacity='0.35'/%3E%3Crect x='35' y='5' width='1' height='1' fill='%23c8c4a8' opacity='0.2'/%3E%3Crect x='6' y='2' width='1' height='1' fill='%23c8d8f0' opacity='0.5'/%3E%3Crect x='14' y='4' width='1' height='1' fill='%23c8d8f0' opacity='0.35'/%3E%3Crect x='24' y='1' width='1' height='1' fill='%23c8d8f0' opacity='0.4'/%3E%3Crect x='40' y='6' width='1' height='1' fill='%23c8d8f0' opacity='0.3'/%3E%3Crect x='18' y='7' width='1' height='1' fill='%23c8d8f0' opacity='0.25'/%3E%3Crect x='2' y='9' width='1' height='1' fill='%23c8d8f0' opacity='0.2'/%3E%3Crect x='30' y='3' width='1' height='1' fill='%23c8d8f0' opacity='0.3'/%3E%3Crect x='10' y='6' width='1' height='1' fill='%23fde68a' opacity='0.2'/%3E%3Crect x='3' y='10' width='6' height='2' fill='%230ea5e9' opacity='0.15'/%3E%3Crect x='9' y='11' width='8' height='2' fill='%230284c7' opacity='0.12'/%3E%3Crect x='17' y='10' width='4' height='2' fill='%230ea5e9' opacity='0.15'/%3E%3Crect x='25' y='11' width='10' height='2' fill='%230284c7' opacity='0.12'/%3E%3Crect x='35' y='10' width='6' height='2' fill='%230ea5e9' opacity='0.15'/%3E%3Crect x='3' y='10' width='2' height='1' fill='%23c8d8f0' opacity='0.1'/%3E%3Crect x='17' y='10' width='2' height='1' fill='%23c8d8f0' opacity='0.08'/%3E%3Crect x='35' y='10' width='2' height='1' fill='%23c8d8f0' opacity='0.1'/%3E%3Crect x='10' y='18' width='3' height='2' fill='%23f97316' opacity='0.35'/%3E%3Crect x='9' y='19' width='1' height='1' fill='%23fdba74' opacity='0.2'/%3E%3Crect x='30' y='24' width='2' height='1' fill='%23818cf8' opacity='0.3'/%3E%3Crect x='32' y='24' width='1' height='1' fill='%23a5b4fc' opacity='0.2'/%3E%3Crect x='20' y='30' width='1' height='1' fill='%23c8d8f0' opacity='0.1'/%3E%3Crect x='36' y='22' width='1' height='1' fill='%23c8d8f0' opacity='0.1'/%3E%3Crect x='6' y='26' width='1' height='1' fill='%23c8d8f0' opacity='0.08'/%3E%3Crect x='4' y='36' width='6' height='5' fill='%23052e1e' opacity='0.7'/%3E%3Crect x='5' y='32' width='2' height='4' fill='%23064e33' opacity='0.5'/%3E%3Crect x='8' y='34' width='2' height='2' fill='%23059669' opacity='0.35'/%3E%3Crect x='30' y='38' width='5' height='4' fill='%23052e1e' opacity='0.6'/%3E%3Crect x='32' y='35' width='2' height='3' fill='%23064e33' opacity='0.45'/%3E%3Crect x='18' y='39' width='4' height='3' fill='%23500e28' opacity='0.45'/%3E%3Crect x='19' y='37' width='2' height='2' fill='%23701838' opacity='0.35'/%3E%3Crect x='14' y='40' width='2' height='2' fill='%23052e1e' opacity='0.5'/%3E%3Crect x='38' y='40' width='3' height='2' fill='%231a1810' opacity='0.6'/%3E%3Crect x='24' y='42' width='2' height='1' fill='%23c8b060' opacity='0.15'/%3E%3Crect x='10' y='42' width='2' height='1' fill='%23c8b060' opacity='0.12'/%3E%3C/svg%3E");
color: #0ea5e9;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
transition: all 0.2s ease;
z-index: 9998;
-webkit-user-select: none;
user-select: none;
-webkit-touch-callout: none;
touch-action: manipulation;
backdrop-filter: blur(12px);
image-rendering: pixelated;
}
.transcript-fab:hover {
transform: translateY(-2px);
border-color: rgba(99, 102, 241, 0.4);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5), 0 0 12px rgba(99, 102, 241, 0.15);
color: #a5b4fc;
box-shadow:
0 6px 20px rgba(0, 0, 0, 0.7),
0 0 10px rgba(14, 165, 233, 0.2);
color: #38bdf8;
}
.transcript-fab.active {
background: rgba(99, 102, 241, 0.15);
border-color: rgba(99, 102, 241, 0.4);
color: #c7d2fe;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4), 0 0 8px rgba(99, 102, 241, 0.2);
color: #67e8f9;
}
.transcript-fab.active:hover {
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5), 0 0 12px rgba(99, 102, 241, 0.3);
color: #a5f3fc;
}
@media (max-width: 768px) {

View File

@@ -803,6 +803,7 @@ onBeforeUnmount(() => {
padding-top: 5rem !important;
padding-bottom: 3.5rem !important;
flex: 1 !important;
scrollbar-gutter: stable !important;
}
.content :deep(.chat-title-row) {
@@ -861,6 +862,17 @@ onBeforeUnmount(() => {
/* Pixel art scrollbar */
.content :deep(.messages-scroll)::-webkit-scrollbar {
width: 8px;
transition: opacity 0.35s ease;
}
/* Idle: hide scrollbar visuals (gutter stays via scrollbar-gutter: stable) */
.aero-win:not(.chrome-visible) .content :deep(.messages-scroll)::-webkit-scrollbar-track {
background: transparent !important;
}
.aero-win:not(.chrome-visible) .content :deep(.messages-scroll)::-webkit-scrollbar-thumb {
background: transparent !important;
border-color: transparent !important;
}
.content :deep(.messages-scroll)::-webkit-scrollbar-track {
@@ -913,15 +925,29 @@ onBeforeUnmount(() => {
font-size: 12px;
}
/* Send button: pixel art daytime ocean, no border */
.content :deep(.send-btn) {
background: rgba(14, 165, 233, 0.2);
border-radius: 0;
width: 26px;
height: 26px;
background:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' shape-rendering='crispEdges'%3E%3Crect width='28' height='6' fill='%2387ceeb'/%3E%3Crect y='6' width='28' height='4' fill='%2356b3d9'/%3E%3Crect y='10' width='28' height='4' fill='%232d9abf'/%3E%3Crect y='14' width='28' height='4' fill='%231a7fa5'/%3E%3Crect y='18' width='28' height='4' fill='%23106888'/%3E%3Crect y='22' width='28' height='6' fill='%23c2b280'/%3E%3Crect x='24' y='4' width='3' height='3' fill='%23fffde0' opacity='0.8'/%3E%3Crect x='25' y='3' width='2' height='1' fill='%23fffde0' opacity='0.5'/%3E%3Crect x='2' y='5' width='4' height='2' fill='white' opacity='0.35'/%3E%3Crect x='10' y='4' width='6' height='2' fill='white' opacity='0.25'/%3E%3Crect x='20' y='6' width='3' height='1' fill='white' opacity='0.2'/%3E%3Crect x='5' y='12' width='3' height='2' fill='%23f97316' opacity='0.7'/%3E%3Crect x='4' y='13' width='1' height='1' fill='%23fdba74' opacity='0.5'/%3E%3Crect x='18' y='16' width='2' height='1' fill='%232563eb' opacity='0.5'/%3E%3Crect x='20' y='16' width='1' height='1' fill='%2393c5fd' opacity='0.4'/%3E%3Crect x='8' y='18' width='1' height='1' fill='white' opacity='0.2'/%3E%3Crect x='22' y='12' width='1' height='1' fill='white' opacity='0.2'/%3E%3Crect x='14' y='20' width='1' height='1' fill='white' opacity='0.15'/%3E%3Crect x='3' y='23' width='4' height='3' fill='%23059669' opacity='0.5'/%3E%3Crect x='4' y='22' width='2' height='1' fill='%2310b981' opacity='0.4'/%3E%3Crect x='20' y='24' width='3' height='2' fill='%23059669' opacity='0.4'/%3E%3Crect x='12' y='25' width='3' height='2' fill='%23ec4899' opacity='0.45'/%3E%3Crect x='13' y='24' width='2' height='1' fill='%23f472b6' opacity='0.35'/%3E%3C/svg%3E") !important;
border: none !important;
border-radius: 0 !important;
width: 28px !important;
height: 28px !important;
color: white !important;
image-rendering: pixelated;
box-shadow: none !important;
transition: color 0.15s ease !important;
}
.content :deep(.send-btn:hover:not(:disabled)) {
background: rgba(14, 165, 233, 0.35);
color: #fffde0 !important;
filter: none !important;
box-shadow: 0 0 12px rgba(135, 206, 235, 0.5), 0 0 4px rgba(255, 253, 224, 0.3) !important;
}
.content :deep(.send-btn:disabled) {
opacity: 0.25 !important;
filter: saturate(0.3) !important;
}
/* Selection bar */