@import "tailwindcss"; /* ─── Design Tokens ─── */ @theme { --color-bg: #08080d; --color-surface: #111117; --color-surface-hover: #17171e; --color-surface-active: #1c1c25; --color-edge: #1e1e2a; --color-edge-active: #2c2c3e; --color-fg: #eaeaef; --color-fg-secondary: #9e9eb5; --color-fg-dim: #5a5a6e; --color-accent: #6366f1; --color-accent-hover: #818cf8; --color-danger: #f43f5e; --color-success: #34d399; --radius-card: 14px; } /* ─── Base ─── */ @layer base { html, body { font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; } body::after { content: ""; @apply fixed pointer-events-none z-0; top: -30%; left: 50%; transform: translateX(-50%); width: 600px; height: 600px; background: radial-gradient( circle, rgba(99, 102, 241, 0.04) 0%, transparent 70% ); } } /* ─── App Container (safe-area padding) ─── */ #app { padding: calc(16px + env(safe-area-inset-top, 0px)) 20px calc(16px + env(safe-area-inset-bottom, 0px)); } /* ─── Connection Status States ─── */ .status.connected { @apply border-success/15; } .status.connected .dot { @apply bg-success; box-shadow: 0 0 6px rgba(52, 211, 153, 0.5); } .status.disconnected .dot { @apply bg-danger; box-shadow: 0 0 6px rgba(244, 63, 94, 0.4); } .status.connecting .dot { @apply bg-accent; animation: pulse 1.4s ease-in-out infinite; } /* ─── Preview Active State ─── */ .preview-box.active { border-color: rgba(99, 102, 241, 0.4); box-shadow: 0 0 0 1px rgba(99, 102, 241, 0.2), 0 4px 24px -4px rgba(99, 102, 241, 0.15); background: linear-gradient( 180deg, rgba(99, 102, 241, 0.03) 0%, var(--color-surface) 100% ); } /* ─── Placeholder Text ─── */ #preview-text.placeholder { @apply text-fg-dim; } /* ─── Mic Button ─── */ #mic-btn { background: linear-gradient( 145deg, var(--color-surface-hover), var(--color-surface) ); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.04); transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); } #mic-btn:disabled { @apply opacity-30 cursor-not-allowed; } #mic-btn:not(:disabled):active, #mic-btn.recording { @apply bg-accent border-accent-hover text-white; transform: scale(1.06); box-shadow: 0 0 32px rgba(99, 102, 241, 0.35), 0 0 80px rgba(99, 102, 241, 0.2); } #mic-btn.recording { animation: mic-breathe 1.8s ease-in-out infinite; } /* ─── Wave Rings ─── */ #mic-btn.recording + .mic-rings .ring { animation: ring-expand 2.4s cubic-bezier(0.2, 0, 0.2, 1) infinite; } #mic-btn.recording + .mic-rings .ring:nth-child(2) { animation-delay: 0.8s; } #mic-btn.recording + .mic-rings .ring:nth-child(3) { animation-delay: 1.6s; } /* ─── History Items (dynamically created) ─── */ #history-list li { @apply bg-surface border border-edge rounded-card cursor-pointer flex items-start gap-3 transition-all duration-150; padding: 14px 16px; margin-bottom: 8px; font-size: 14px; line-height: 1.5; animation: slide-up 0.35s cubic-bezier(0.16, 1, 0.3, 1) both; animation-delay: calc(var(--i, 0) * 40ms); } #history-list li:active { @apply bg-surface-active border-edge-active; transform: scale(0.985); } #history-list li .hist-text { @apply flex-1 break-words; } #history-list li .hist-time { @apply text-fg-dim whitespace-nowrap shrink-0; font-size: 11px; padding-top: 2px; font-variant-numeric: tabular-nums; } /* ─── Text Button Active State ─── */ .text-btn:active { @apply text-danger; background: rgba(244, 63, 94, 0.08); } /* ─── Scrollbar ─── */ .preview-box::-webkit-scrollbar, #history-list::-webkit-scrollbar { width: 3px; } .preview-box::-webkit-scrollbar-track, #history-list::-webkit-scrollbar-track { background: transparent; } .preview-box::-webkit-scrollbar-thumb, #history-list::-webkit-scrollbar-thumb { @apply bg-edge; border-radius: 3px; } /* ─── Toast ─── */ .toast { bottom: calc(80px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%) translateY(8px); background: rgba(28, 28, 37, 0.85); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1); } .toast.show { @apply opacity-100; transform: translateX(-50%) translateY(0); } /* ─── Keyframes ─── */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } } @keyframes mic-breathe { 0%, 100% { box-shadow: 0 0 32px rgba(99, 102, 241, 0.35), 0 0 80px rgba(99, 102, 241, 0.2); } 50% { box-shadow: 0 0 48px rgba(99, 102, 241, 0.35), 0 0 120px rgba(99, 102, 241, 0.2), 0 0 200px rgba(99, 102, 241, 0.08); } } @keyframes ring-expand { 0% { transform: scale(1); opacity: 0.35; } 100% { transform: scale(2); opacity: 0; } } @keyframes slide-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }