videotomp3transcriptor/public/style.css
Trouve Alexis 23bb4cd2d9 Add video/audio to MP3 conversion feature
Implement drag-and-drop interface for converting video and audio files to MP3 format using FFmpeg. Users can now upload files (MP4, M4A, AVI, MKV, MOV, WAV, FLAC, OGG) and convert them with customizable bitrate and quality settings.

- Add conversion service with FFmpeg integration
- Add /convert-to-mp3 and /supported-formats API endpoints
- Add new "Video to MP3" tab with drag-and-drop UI
- Support multiple file uploads with batch conversion
- Add bitrate (128k-320k) and VBR quality options

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 22:56:58 +08:00

717 lines
12 KiB
CSS

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
min-height: 100vh;
color: #fff;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 2rem;
}
header {
text-align: center;
margin-bottom: 2rem;
}
header h1 {
font-size: 2.5rem;
background: linear-gradient(90deg, #e94560, #0f3460);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.subtitle {
color: #8892b0;
margin-top: 0.5rem;
}
/* Tabs */
.tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 2rem;
border-bottom: 2px solid #233554;
padding-bottom: 0.5rem;
flex-wrap: wrap;
}
.tab {
padding: 0.75rem 1.5rem;
background: transparent;
border: none;
color: #8892b0;
cursor: pointer;
font-size: 1rem;
border-radius: 8px 8px 0 0;
transition: all 0.3s ease;
}
.tab:hover {
color: #e94560;
background: rgba(233, 69, 96, 0.1);
}
.tab.active {
color: #e94560;
background: rgba(233, 69, 96, 0.2);
border-bottom: 2px solid #e94560;
margin-bottom: -2px;
}
/* Tab Content */
.tab-content {
display: none;
background: rgba(255, 255, 255, 0.05);
padding: 2rem;
border-radius: 12px;
backdrop-filter: blur(10px);
}
.tab-content.active {
display: block;
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.tab-content h2 {
margin-bottom: 1.5rem;
color: #ccd6f6;
}
/* Forms */
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
color: #8892b0;
font-size: 0.9rem;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
@media (max-width: 600px) {
.form-row {
grid-template-columns: 1fr;
}
}
input[type="url"],
input[type="text"],
select {
width: 100%;
padding: 0.75rem 1rem;
background: rgba(255, 255, 255, 0.1);
border: 1px solid #233554;
border-radius: 8px;
color: #fff;
font-size: 1rem;
transition: all 0.3s ease;
}
input[type="url"]:focus,
input[type="text"]:focus,
select:focus {
outline: none;
border-color: #e94560;
background: rgba(233, 69, 96, 0.1);
}
select option {
background: #1a1a2e;
color: #fff;
}
/* Buttons */
.btn {
padding: 0.75rem 2rem;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.btn-primary {
background: linear-gradient(90deg, #e94560, #0f3460);
color: #fff;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 5px 20px rgba(233, 69, 96, 0.4);
}
.btn-primary:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.btn-secondary {
background: rgba(255, 255, 255, 0.1);
color: #ccd6f6;
border: 1px solid #233554;
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.2);
}
.btn-small {
padding: 0.5rem 1rem;
font-size: 0.85rem;
margin-left: 0.5rem;
}
.btn-loading {
display: none;
}
.btn.loading .btn-text {
display: none;
}
.btn.loading .btn-loading {
display: inline;
}
/* Results */
.result {
margin-top: 1.5rem;
padding: 1rem;
border-radius: 8px;
display: none;
}
.result.show {
display: block;
animation: fadeIn 0.3s ease;
}
.result.success {
background: rgba(16, 185, 129, 0.2);
border: 1px solid #10b981;
}
.result.error {
background: rgba(239, 68, 68, 0.2);
border: 1px solid #ef4444;
}
.result h3 {
margin-bottom: 0.75rem;
font-size: 1.1rem;
}
.result ul {
list-style: none;
margin-top: 0.5rem;
}
.result li {
padding: 0.5rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
gap: 0.5rem;
}
.result li:last-child {
border-bottom: none;
}
.result .icon-success {
color: #10b981;
}
.result .icon-error {
color: #ef4444;
}
.result a {
color: #e94560;
text-decoration: none;
}
.result a:hover {
text-decoration: underline;
}
.result .preview {
margin-top: 1rem;
padding: 1rem;
background: rgba(0, 0, 0, 0.3);
border-radius: 8px;
font-family: monospace;
font-size: 0.9rem;
white-space: pre-wrap;
max-height: 300px;
overflow-y: auto;
}
/* Files Grid */
.files-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1rem;
margin-top: 1.5rem;
}
.file-card {
background: rgba(255, 255, 255, 0.05);
padding: 1rem;
border-radius: 8px;
border: 1px solid #233554;
transition: all 0.3s ease;
}
.file-card:hover {
border-color: #e94560;
transform: translateY(-2px);
}
.file-card .file-name {
font-weight: 600;
margin-bottom: 0.5rem;
word-break: break-all;
color: #ccd6f6;
}
.file-card .file-type {
font-size: 0.8rem;
color: #8892b0;
margin-bottom: 0.75rem;
}
.file-card .file-actions {
display: flex;
gap: 0.5rem;
}
.file-card .file-actions a {
padding: 0.4rem 0.8rem;
background: rgba(233, 69, 96, 0.2);
color: #e94560;
text-decoration: none;
border-radius: 4px;
font-size: 0.85rem;
transition: all 0.3s ease;
}
.file-card .file-actions a:hover {
background: #e94560;
color: #fff;
}
/* Loading spinner */
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
display: inline-block;
width: 16px;
height: 16px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-top-color: #fff;
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin-right: 0.5rem;
}
/* Status indicator */
.status {
display: inline-block;
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.8rem;
margin-left: 0.5rem;
}
.status.downloading {
background: rgba(59, 130, 246, 0.2);
color: #3b82f6;
}
.status.transcribing {
background: rgba(168, 85, 247, 0.2);
color: #a855f7;
}
.status.complete {
background: rgba(16, 185, 129, 0.2);
color: #10b981;
}
/* Empty state */
.empty-state {
text-align: center;
padding: 3rem;
color: #8892b0;
}
.empty-state p {
margin-top: 1rem;
}
/* Progress Bar */
.progress-container {
margin-top: 1.5rem;
padding: 1.5rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 12px;
border: 1px solid #233554;
}
.progress-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.progress-header #progress-title {
font-weight: 600;
color: #ccd6f6;
font-size: 1rem;
}
.progress-header #progress-eta {
color: #e94560;
font-size: 0.9rem;
font-weight: 500;
}
.progress-bar {
width: 100%;
height: 12px;
background: rgba(255, 255, 255, 0.1);
border-radius: 6px;
overflow: hidden;
position: relative;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #e94560, #ff6b8a);
border-radius: 6px;
width: 0%;
transition: width 0.3s ease;
position: relative;
}
.progress-fill::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
animation: shimmer 2s infinite;
}
@keyframes shimmer {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
.progress-details {
display: flex;
justify-content: space-between;
margin-top: 0.75rem;
font-size: 0.85rem;
color: #8892b0;
}
.progress-details #progress-percent {
color: #ccd6f6;
font-weight: 600;
}
.progress-details #progress-speed {
color: #10b981;
}
.progress-current {
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
font-size: 0.9rem;
color: #8892b0;
}
.progress-current .video-title {
color: #ccd6f6;
font-weight: 500;
}
/* Drag and Drop Zone */
.drop-zone {
border: 2px dashed #233554;
border-radius: 12px;
padding: 3rem 2rem;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
margin-bottom: 1.5rem;
background: rgba(255, 255, 255, 0.02);
}
.drop-zone:hover {
border-color: #e94560;
background: rgba(233, 69, 96, 0.05);
}
.drop-zone.drag-over {
border-color: #e94560;
background: rgba(233, 69, 96, 0.1);
transform: scale(1.02);
}
.drop-zone-icon {
color: #8892b0;
margin-bottom: 1rem;
transition: color 0.3s ease;
}
.drop-zone:hover .drop-zone-icon {
color: #e94560;
}
.drop-zone-text {
color: #ccd6f6;
font-size: 1.1rem;
margin-bottom: 0.5rem;
}
.drop-zone-hint {
color: #8892b0;
font-size: 0.9rem;
}
.drop-zone-formats {
color: #64748b;
font-size: 0.75rem;
margin-top: 0.5rem;
font-style: italic;
}
/* Selected Files List */
.selected-files {
background: rgba(255, 255, 255, 0.05);
border-radius: 8px;
padding: 1rem;
margin-bottom: 1.5rem;
}
.selected-files h3 {
font-size: 0.9rem;
color: #8892b0;
margin-bottom: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.selected-files ul {
list-style: none;
margin-bottom: 1rem;
}
.selected-files li {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: #ccd6f6;
}
.selected-files li:last-child {
border-bottom: none;
}
.selected-files .file-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.selected-files .file-size {
color: #8892b0;
font-size: 0.85rem;
margin-left: 1rem;
}
.selected-files .remove-file {
background: none;
border: none;
color: #ef4444;
cursor: pointer;
padding: 0.25rem;
margin-left: 0.5rem;
font-size: 1.2rem;
line-height: 1;
}
.selected-files .remove-file:hover {
color: #ff6b6b;
}
/* Checkbox Group */
.checkbox-group {
margin-bottom: 1rem;
}
.checkbox-label {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
color: #ccd6f6;
font-size: 0.95rem;
}
.checkbox-label input[type="checkbox"] {
width: 18px;
height: 18px;
accent-color: #e94560;
cursor: pointer;
}
.translate-lang-select {
margin-top: 0.75rem;
width: auto;
min-width: 150px;
}
.translate-lang-select:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Translate Tab */
.translate-mode-selector {
display: flex;
gap: 0.5rem;
margin-bottom: 1.5rem;
}
.mode-btn {
padding: 0.6rem 1.25rem;
background: rgba(255, 255, 255, 0.05);
border: 1px solid #233554;
color: #8892b0;
border-radius: 8px;
cursor: pointer;
font-size: 0.95rem;
transition: all 0.3s ease;
}
.mode-btn:hover {
border-color: #e94560;
color: #ccd6f6;
}
.mode-btn.active {
background: rgba(233, 69, 96, 0.2);
border-color: #e94560;
color: #e94560;
}
.translate-mode {
animation: fadeIn 0.3s ease;
}
/* Textarea */
textarea {
width: 100%;
padding: 1rem;
background: rgba(255, 255, 255, 0.1);
border: 1px solid #233554;
border-radius: 8px;
color: #fff;
font-size: 1rem;
font-family: inherit;
resize: vertical;
min-height: 150px;
transition: all 0.3s ease;
}
textarea:focus {
outline: none;
border-color: #e94560;
background: rgba(233, 69, 96, 0.1);
}
textarea::placeholder {
color: #8892b0;
}
/* Translation Result */
.translation-output {
margin-top: 1rem;
padding: 1rem;
background: rgba(0, 0, 0, 0.3);
border-radius: 8px;
white-space: pre-wrap;
max-height: 400px;
overflow-y: auto;
color: #ccd6f6;
line-height: 1.6;
}
/* Summarize Tab */
.summarize-mode-selector {
display: flex;
gap: 0.5rem;
margin-bottom: 1.5rem;
}
.summarize-mode {
animation: fadeIn 0.3s ease;
}
/* Summary Result */
.summary-output {
margin-top: 1rem;
padding: 1rem;
background: rgba(0, 0, 0, 0.3);
border-radius: 8px;
white-space: pre-wrap;
max-height: 400px;
overflow-y: auto;
color: #ccd6f6;
line-height: 1.6;
}