/* 🎤 语音录制组件样式 */ /* CSS变量定义 */ .voice-recorder-container { --primary-color: #007AFF; --primary-light: #5AC8FA; --primary-dark: #0051D5; --success-color: #34C759; --warning-color: #FF9500; --danger-color: #FF3B30; --background-color: #F2F2F7; --surface-color: #FFFFFF; --text-primary: #000000; --text-secondary: #8E8E93; --text-tertiary: #C7C7CC; --border-color: #E5E5EA; --shadow-light: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); --shadow-medium: 0 8rpx 24rpx rgba(0, 0, 0, 0.15); --radius-small: 8rpx; --radius-medium: 12rpx; --radius-large: 20rpx; --radius-xl: 32rpx; } /* 🌙 深色模式支持 */ @media (prefers-color-scheme: dark) { .voice-recorder-container { --primary-color: #0A84FF; --background-color: #000000; --surface-color: #1C1C1E; --text-primary: #FFFFFF; --text-secondary: #8E8E93; --text-tertiary: #48484A; --border-color: #38383A; --shadow-light: 0 2rpx 8rpx rgba(0, 0, 0, 0.3); --shadow-medium: 0 8rpx 24rpx rgba(0, 0, 0, 0.4); } } .voice-recorder-container { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; } .voice-recorder-container.visible { opacity: 1; pointer-events: auto; } .voice-recorder-container.hidden { opacity: 0; pointer-events: none; } /* 🎨 录音遮罩 */ .recorder-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(10rpx); } /* 🎨 录音内容 */ .recorder-content { width: 640rpx; max-width: 90vw; background: var(--surface-color); border-radius: var(--radius-xl); box-shadow: var(--shadow-medium); padding: 60rpx 40rpx 40rpx; position: relative; animation: slideUp 0.3s ease-out; } @keyframes slideUp { from { opacity: 0; transform: translateY(100rpx) scale(0.9); } to { opacity: 1; transform: translateY(0) scale(1); } } /* 🎤 录音状态 */ .recorder-status { display: flex; flex-direction: column; align-items: center; margin-bottom: 40rpx; } .status-icon { width: 120rpx; height: 120rpx; border-radius: 60rpx; display: flex; align-items: center; justify-content: center; margin-bottom: 24rpx; transition: all 0.3s ease; position: relative; } .status-icon.idle { background: var(--background-color); border: 2rpx solid var(--border-color); } .status-icon.recording { background: linear-gradient(135deg, var(--danger-color) 0%, #FF6B6B 100%); animation: pulse 2s infinite; } .status-icon.paused { background: var(--warning-color); } .status-icon.completed { background: var(--success-color); } .status-icon.error { background: var(--danger-color); } @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } } .icon-microphone { font-size: 48rpx; } .icon-recording { position: relative; } .recording-dot { width: 24rpx; height: 24rpx; border-radius: 12rpx; background: white; animation: blink 1s infinite; } @keyframes blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0.3; } } .icon-paused, .icon-completed, .icon-error { font-size: 48rpx; color: white; } .status-text { font-size: 32rpx; font-weight: 600; color: var(--text-primary); text-align: center; } /* ⏱️ 录音时长 */ .recording-duration { display: flex; align-items: center; justify-content: center; margin-bottom: 40rpx; gap: 8rpx; } .duration-text { font-size: 48rpx; font-weight: 700; color: var(--primary-color); font-family: 'SF Mono', 'Monaco', 'Consolas', monospace; } .max-duration-text { font-size: 28rpx; color: var(--text-secondary); font-family: 'SF Mono', 'Monaco', 'Consolas', monospace; } /* 🌊 实时波形 */ .realtime-waveform { height: 120rpx; margin-bottom: 40rpx; display: flex; align-items: center; justify-content: center; } .waveform-container { display: flex; align-items: center; justify-content: center; gap: 6rpx; height: 100%; } .wave-bar { width: 8rpx; border-radius: 4rpx; transition: all 0.2s ease; min-height: 16rpx; } .wave-bar.realtime { background: var(--primary-color); animation: waveAnimation 1s ease-in-out infinite; } .wave-bar.preview { background: var(--text-tertiary); } @keyframes waveAnimation { 0%, 100% { transform: scaleY(0.5); } 50% { transform: scaleY(1); } } /* 📊 录音预览 */ .recording-preview { margin-bottom: 40rpx; } .preview-waveform { height: 80rpx; margin-bottom: 24rpx; display: flex; align-items: center; justify-content: center; } .preview-info { display: flex; justify-content: space-between; align-items: center; padding: 0 20rpx; } .file-size, .quality-text { font-size: 24rpx; color: var(--text-secondary); } /* 🎛️ 录音控制 */ .recorder-controls { margin-bottom: 32rpx; } .control-button { height: 88rpx; border-radius: var(--radius-medium); display: flex; align-items: center; justify-content: center; margin-bottom: 16rpx; transition: all 0.3s ease; user-select: none; -webkit-user-select: none; } .control-button:last-child { margin-bottom: 0; } .control-button.primary { background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-light) 100%); color: white; box-shadow: var(--shadow-light); } .control-button.secondary { background: var(--background-color); color: var(--text-primary); border: 1rpx solid var(--border-color); } .control-button.danger { background: rgba(255, 59, 48, 0.1); color: var(--danger-color); border: 1rpx solid rgba(255, 59, 48, 0.3); } .control-button:active { transform: scale(0.98); } .control-button.primary:active { background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 100%); } .button-text { font-size: 32rpx; font-weight: 600; } /* 录音中的控制按钮 */ .recording-controls, .paused-controls, .completed-controls { display: flex; gap: 16rpx; } .recording-controls .control-button, .paused-controls .control-button, .completed-controls .control-button { flex: 1; margin-bottom: 0; } /* 💡 录音提示 */ .recorder-tips { text-align: center; margin-bottom: 20rpx; } .tip-text { font-size: 26rpx; color: var(--text-secondary); line-height: 1.4; } .tip-text.error { color: var(--danger-color); } /* ❌ 关闭按钮 */ .close-button { position: absolute; top: 20rpx; right: 20rpx; width: 60rpx; height: 60rpx; border-radius: 30rpx; background: var(--background-color); display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; } .close-button:active { background: var(--border-color); transform: scale(0.95); } .close-icon { font-size: 36rpx; color: var(--text-secondary); font-weight: 300; } /* 🔐 权限引导 */ .permission-guide { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.8); display: flex; align-items: center; justify-content: center; border-radius: var(--radius-xl); } .guide-content { background: var(--surface-color); border-radius: var(--radius-large); padding: 60rpx 40rpx 40rpx; margin: 40rpx; text-align: center; box-shadow: var(--shadow-medium); } .guide-icon { font-size: 80rpx; margin-bottom: 24rpx; } .guide-title { font-size: 36rpx; font-weight: 600; color: var(--text-primary); margin-bottom: 16rpx; display: block; } .guide-desc { font-size: 28rpx; color: var(--text-secondary); line-height: 1.4; margin-bottom: 40rpx; display: block; } .guide-buttons { display: flex; gap: 16rpx; } .guide-button { flex: 1; height: 80rpx; border-radius: var(--radius-medium); display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; } .guide-button.primary { background: var(--primary-color); color: white; } .guide-button.secondary { background: var(--background-color); color: var(--text-primary); border: 1rpx solid var(--border-color); } .guide-button:active { transform: scale(0.98); } /* 📱 响应式设计 */ @media screen and (max-width: 375px) { .recorder-content { width: 560rpx; padding: 50rpx 30rpx 30rpx; } .status-icon { width: 100rpx; height: 100rpx; } .duration-text { font-size: 40rpx; } .realtime-waveform { height: 100rpx; } .control-button { height: 76rpx; } .button-text { font-size: 28rpx; } } @media screen and (min-width: 414px) { .recorder-content { width: 720rpx; padding: 70rpx 50rpx 50rpx; } .status-icon { width: 140rpx; height: 140rpx; } .duration-text { font-size: 56rpx; } .realtime-waveform { height: 140rpx; } .control-button { height: 96rpx; } .button-text { font-size: 36rpx; } } /* 🎭 动画增强 */ .voice-recorder-container.visible .recorder-content { animation: slideUp 0.3s ease-out; } .voice-recorder-container.hidden .recorder-content { animation: slideDown 0.3s ease-in; } @keyframes slideDown { from { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 0; transform: translateY(100rpx) scale(0.9); } } /* 触摸反馈 */ .control-button { -webkit-tap-highlight-color: transparent; } /* 可访问性 */ .control-button[aria-pressed="true"] { outline: 2rpx solid var(--primary-color); outline-offset: 4rpx; }