talk2me/static/css/styles.css
Adolfo Delorenzo 05ad940079 Major improvements: TypeScript, animations, notifications, compression, GPU optimization
- Added TypeScript support with type definitions and build process
- Implemented loading animations and visual feedback
- Added push notifications with user preferences
- Implemented audio compression (50-70% bandwidth reduction)
- Added GPU optimization for Whisper (2-3x faster transcription)
- Support for NVIDIA, AMD (ROCm), and Apple Silicon GPUs
- Removed duplicate JavaScript code (15KB reduction)
- Enhanced .gitignore for Node.js and VAPID keys
- Created documentation for TypeScript and GPU support

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-02 21:18:16 -06:00

425 lines
7.3 KiB
CSS

/* Main styles for Talk2Me application */
/* Loading animations */
.loading-dots {
display: inline-flex;
align-items: center;
gap: 4px;
}
.loading-dots span {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #007bff;
animation: dotPulse 1.4s infinite ease-in-out both;
}
.loading-dots span:nth-child(1) {
animation-delay: -0.32s;
}
.loading-dots span:nth-child(2) {
animation-delay: -0.16s;
}
@keyframes dotPulse {
0%, 80%, 100% {
transform: scale(0);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
/* Wave animation for recording */
.recording-wave {
position: relative;
display: inline-block;
width: 40px;
height: 40px;
}
.recording-wave span {
position: absolute;
bottom: 0;
width: 4px;
height: 100%;
background: #fff;
border-radius: 2px;
animation: wave 1.2s linear infinite;
}
.recording-wave span:nth-child(1) {
left: 0;
animation-delay: 0s;
}
.recording-wave span:nth-child(2) {
left: 8px;
animation-delay: -1.1s;
}
.recording-wave span:nth-child(3) {
left: 16px;
animation-delay: -1s;
}
.recording-wave span:nth-child(4) {
left: 24px;
animation-delay: -0.9s;
}
.recording-wave span:nth-child(5) {
left: 32px;
animation-delay: -0.8s;
}
@keyframes wave {
0%, 40%, 100% {
transform: scaleY(0.4);
}
20% {
transform: scaleY(1);
}
}
/* Spinner animation */
.spinner-custom {
width: 40px;
height: 40px;
position: relative;
display: inline-block;
}
.spinner-custom::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
border: 3px solid rgba(0, 123, 255, 0.2);
}
.spinner-custom::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #007bff;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* Translation animation */
.translation-animation {
position: relative;
display: inline-flex;
align-items: center;
gap: 10px;
}
.translation-animation .arrow {
width: 30px;
height: 2px;
background: #28a745;
position: relative;
animation: moveArrow 1.5s infinite;
}
.translation-animation .arrow::after {
content: '';
position: absolute;
right: -8px;
top: -4px;
width: 0;
height: 0;
border-left: 8px solid #28a745;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
}
@keyframes moveArrow {
0%, 100% {
transform: translateX(0);
}
50% {
transform: translateX(10px);
}
}
/* Processing text animation */
.processing-text {
display: inline-block;
position: relative;
font-style: italic;
color: #6c757d;
}
.processing-text::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 100%;
height: 2px;
background: linear-gradient(90deg,
transparent 0%,
#007bff 50%,
transparent 100%);
animation: processLine 2s linear infinite;
}
@keyframes processLine {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
/* Fade in animation for results */
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Pulse animation for buttons */
.btn-pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(0, 123, 255, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(0, 123, 255, 0);
}
}
/* Loading overlay */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.9);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.loading-overlay.active {
opacity: 1;
pointer-events: all;
}
.loading-content {
text-align: center;
}
.loading-content .spinner-custom {
margin-bottom: 20px;
}
/* Status indicator animations */
.status-indicator {
transition: all 0.3s ease;
}
.status-indicator.processing {
font-weight: 500;
color: #007bff;
}
.status-indicator.success {
color: #28a745;
}
.status-indicator.error {
color: #dc3545;
}
/* Card loading state */
.card-loading {
position: relative;
overflow: hidden;
}
.card-loading::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.4),
transparent
);
animation: shimmer 2s infinite;
}
@keyframes shimmer {
100% {
left: 100%;
}
}
/* Text skeleton loader */
.skeleton-loader {
background: #eee;
background: linear-gradient(90deg, #eee 25%, #f5f5f5 50%, #eee 75%);
background-size: 200% 100%;
animation: loading 1.5s infinite;
border-radius: 4px;
height: 20px;
margin: 10px 0;
}
@keyframes loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
/* Audio playing animation */
.audio-playing {
display: inline-flex;
align-items: flex-end;
gap: 2px;
height: 20px;
}
.audio-playing span {
width: 3px;
background: #28a745;
animation: audioBar 0.5s ease-in-out infinite alternate;
}
.audio-playing span:nth-child(1) {
height: 40%;
animation-delay: 0s;
}
.audio-playing span:nth-child(2) {
height: 60%;
animation-delay: 0.1s;
}
.audio-playing span:nth-child(3) {
height: 80%;
animation-delay: 0.2s;
}
.audio-playing span:nth-child(4) {
height: 60%;
animation-delay: 0.3s;
}
.audio-playing span:nth-child(5) {
height: 40%;
animation-delay: 0.4s;
}
@keyframes audioBar {
to {
height: 100%;
}
}
/* Smooth transitions */
.btn {
transition: all 0.3s ease;
}
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}
/* Success notification */
.success-notification {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background-color: #28a745;
color: white;
padding: 12px 24px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
display: flex;
align-items: center;
gap: 10px;
z-index: 9999;
opacity: 0;
transition: opacity 0.3s ease, transform 0.3s ease;
pointer-events: none;
}
.success-notification.show {
opacity: 1;
transform: translateX(-50%) translateY(0);
pointer-events: all;
}
.success-notification i {
font-size: 18px;
}
/* Mobile optimizations */
@media (max-width: 768px) {
.loading-overlay {
background: rgba(255, 255, 255, 0.95);
}
.spinner-custom,
.recording-wave {
transform: scale(0.8);
}
.success-notification {
width: 90%;
max-width: 300px;
font-size: 14px;
}
}