@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;700;800&family=Noto+Sans+SC:wght@400;500;700&display=swap"); :root { --vv-offset-top: 0px; --vv-height: 100dvh; --bg: #f3f7fc; --bg-accent: #dff4ef; --card: rgba(255, 255, 255, 0.92); --card-border: rgba(19, 35, 58, 0.12); --ink: #1a2c42; --muted: #5f7084; --brand: #0f766e; --brand-strong: #0a5a55; --accent: #ea580c; --danger: #be123c; --shadow: 0 18px 45px rgba(25, 43, 72, 0.14); --radius-xl: 18px; --radius-md: 12px; } * { box-sizing: border-box; } html, body, #root { margin: 0; height: 100%; } body { font-family: "Manrope", "Noto Sans SC", "PingFang SC", sans-serif; color: var(--ink); background: radial-gradient(circle at 0% 0%, #edf4ff 0, transparent 45%), radial-gradient(circle at 100% 100%, #d7f7ee 0, transparent 42%), var(--bg); overflow: hidden; } .page { width: min(1180px, calc(100% - 28px)); margin: 12px auto; height: calc(100dvh - 24px); display: flex; flex-direction: column; min-height: 0; animation: page-in 0.45s ease; } .hero { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 10px; padding: 6px 2px; } .hero-tag { margin: 0; color: #0c5f58; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; font-size: 11px; opacity: 0.9; } .hero h1 { margin: 6px 0 4px; font-size: clamp(22px, 3vw, 34px); line-height: 1.15; font-weight: 800; } .hero-sub { margin: 0; color: var(--muted); font-size: 14px; } .status-chip { display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 999px; border: 1px solid var(--card-border); background: rgba(255, 255, 255, 0.9); font-size: 12px; font-weight: 700; white-space: nowrap; } .dot { width: 9px; height: 9px; border-radius: 50%; } .status-chip.loading .dot { background: var(--accent); } .status-chip.ok .dot { background: var(--brand); } .status-chip.bad .dot { background: var(--danger); } .layout { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 14px; flex: 1; min-height: 0; } .chat-card, .side-card { border-radius: var(--radius-xl); border: 1px solid var(--card-border); background: var(--card); box-shadow: var(--shadow); backdrop-filter: blur(6px); } .chat-card { min-height: 0; height: 100%; display: flex; flex-direction: column; overflow: hidden; } .chat-head { display: flex; justify-content: space-between; gap: 16px; align-items: center; padding: 14px 16px 12px; border-bottom: 1px solid var(--card-border); background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(255, 255, 255, 0.85)); box-shadow: inset 0 -1px 0 rgba(19, 35, 58, 0.04); } .chat-head strong { display: block; font-size: 16px; } .chat-head p { margin: 3px 0 0; color: var(--muted); font-size: 12px; } .chat-peer { display: flex; align-items: center; gap: 10px; min-width: 0; } .chat-avatar { width: 34px; height: 34px; min-width: 34px; min-height: 34px; aspect-ratio: 1 / 1; flex: 0 0 34px; border-radius: 50%; display: grid; place-items: center; font-size: 12px; font-weight: 800; color: #fff; background: linear-gradient(130deg, var(--brand), #14b8a6); } .head-actions { display: flex; gap: 8px; align-items: center; } .icon-btn { padding: 8px; min-width: 40px; min-height: 40px; border-radius: 12px; } .icon-svg { width: 18px; height: 18px; display: block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; } .btn { border: 0; border-radius: var(--radius-md); font: inherit; font-size: 13px; font-weight: 700; padding: 9px 13px; cursor: pointer; transition: transform 0.18s ease, opacity 0.18s ease, box-shadow 0.18s ease; } .btn:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(19, 35, 58, 0.14); } .btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; } .btn-main { background: linear-gradient(130deg, var(--brand), var(--brand-strong)); color: #fff; } .btn-ghost { background: #edf3f8; color: var(--ink); } .desktop-only { display: inline-flex; } .message-list { overflow: auto; overflow-x: hidden; scrollbar-gutter: stable; min-height: 0; flex: 1; padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; background: radial-gradient(circle at 0% 0%, rgba(15, 118, 110, 0.08), transparent 42%), linear-gradient(180deg, rgba(248, 252, 255, 0.84), rgba(241, 250, 248, 0.84)); } .empty-tip { color: var(--muted); margin: 20px auto 0; text-align: center; border: 1px dashed rgba(95, 112, 132, 0.4); border-radius: 16px; padding: 16px 14px; width: min(460px, calc(100% - 10px)); background: rgba(255, 255, 255, 0.78); } .msg { border-radius: 16px; padding: 10px 40px 10px 12px; max-width: 80%; min-width: 0; animation: msg-in 0.28s ease; box-shadow: 0 6px 12px rgba(18, 37, 61, 0.06); position: relative; } .msg.system { align-self: center; max-width: min(88%, 520px); background: rgba(255, 255, 255, 0.92); color: #50647f; border: 1px solid #dbe5f1; border-radius: 999px; padding: 8px 34px 8px 12px; } .msg.incoming { background: #ffffff; border: 1px solid #dceaf5; align-self: flex-start; border-top-left-radius: 8px; } .msg.outgoing { background: #dcf8c6; border: 1px solid #bde9a1; align-self: flex-end; border-top-right-radius: 8px; } .msg-head { display: flex; gap: 8px; align-items: center; color: var(--muted); font-size: 12px; margin-bottom: 2px; } .msg-head strong { color: var(--ink); font-size: 13px; } .msg-head time { margin-left: auto; } .msg p { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; line-height: 1.5; font-size: 14px; } .audio-message { width: min(260px, 100%); border: 0; border-radius: 12px; padding: 8px 10px; margin-top: 2px; background: rgba(8, 27, 52, 0.08); color: #143556; display: inline-flex; align-items: center; gap: 10px; cursor: pointer; } .msg.outgoing .audio-message { background: rgba(57, 139, 18, 0.14); } .audio-message:hover { filter: brightness(0.98); } .audio-icon { width: 24px; height: 24px; border-radius: 50%; display: inline-grid; place-items: center; background: rgba(20, 53, 86, 0.14); font-size: 12px; font-weight: 700; } .audio-waves { flex: 1; min-width: 44px; display: inline-flex; align-items: center; gap: 3px; } .audio-waves i { width: 3px; border-radius: 999px; background: #1887ff; display: block; transform-origin: center bottom; } .audio-waves i:nth-child(1) { height: 9px; } .audio-waves i:nth-child(2) { height: 15px; } .audio-waves i:nth-child(3) { height: 11px; } .audio-waves i:nth-child(4) { height: 13px; background: #13bca8; } .audio-message.playing .audio-waves i { animation: audio-wave 0.75s ease-in-out infinite alternate; } .audio-message.playing .audio-waves i:nth-child(2) { animation-delay: 0.08s; } .audio-message.playing .audio-waves i:nth-child(3) { animation-delay: 0.16s; } .audio-message.playing .audio-waves i:nth-child(4) { animation-delay: 0.24s; } .audio-duration { color: #4d6684; font-size: 12px; font-weight: 700; } .msg-actions { margin-top: 0; display: flex; justify-content: flex-end; position: absolute; top: 8px; right: 8px; } .btn-copy { background: rgba(19, 35, 58, 0.08); color: #2f4769; padding: 2px 8px; border-radius: 999px; font-size: 11px; line-height: 1.2; min-height: 22px; box-shadow: none; } @media (hover: hover) and (pointer: fine) { .msg .msg-actions { opacity: 0; transition: opacity 0.16s ease; } .msg:hover .msg-actions { opacity: 1; } } .composer { border-top: 1px solid var(--card-border); padding: 10px 12px; display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; background: rgba(255, 255, 255, 0.96); box-shadow: inset 0 1px 0 rgba(19, 35, 58, 0.06); } .composer.audio-mode { grid-template-columns: auto 1fr; } .composer-input-wrap { border: 1px solid rgba(19, 35, 58, 0.18); border-radius: 15px; background: #fff; padding: 6px 10px; } .btn-input-switch { min-width: 56px; min-height: 38px; border-radius: 12px; padding: 0 12px; align-self: stretch; } .btn-input-switch.active { background: #dff4ff; color: #145184; } .hold-to-talk { border: 1px solid rgba(19, 35, 58, 0.16); border-radius: 15px; min-height: 42px; background: #f6fbff; color: #1a426b; font-size: 14px; font-weight: 700; } .hold-to-talk.recording { background: rgba(21, 132, 255, 0.14); border-color: rgba(21, 132, 255, 0.36); color: #0e4d84; } .hold-to-talk.cancel { background: rgba(216, 56, 99, 0.14); border-color: rgba(216, 56, 99, 0.34); color: #8f1534; } .composer textarea { width: 100%; resize: none; border: 0; box-shadow: none; padding: 4px 2px; min-height: 36px; max-height: 120px; overflow: auto; line-height: 1.45; } .composer textarea:focus { border: 0; box-shadow: none; } .btn-send { min-width: 78px; border-radius: 14px; align-self: stretch; } .side-card { padding: 16px; display: flex; flex-direction: column; gap: 14px; height: 100%; min-height: 0; overflow: auto; } .field { display: flex; flex-direction: column; gap: 6px; } .field label { font-size: 12px; color: var(--muted); font-weight: 700; } input, textarea, select { border: 1px solid var(--card-border); border-radius: 11px; padding: 10px 11px; font: inherit; color: var(--ink); outline: none; background: #fff; } input:focus, textarea:focus, select:focus { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.15); } .advanced { border: 1px dashed rgba(19, 35, 58, 0.2); border-radius: 12px; padding: 9px 10px; background: rgba(239, 247, 255, 0.7); } .advanced summary { cursor: pointer; font-weight: 700; font-size: 13px; color: #2f4769; } .advanced .field { margin-top: 10px; } .inline-actions { display: flex; align-items: center; gap: 8px; } .mode-switch { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .server-list-row select { width: 100%; } .server-actions { margin-top: 8px; display: flex; gap: 8px; } .btn-mode { background: #edf3f8; color: var(--muted); } .btn-mode.active { background: linear-gradient(130deg, var(--brand), var(--brand-strong)); color: #fff; } .btn-sm { padding: 6px 9px; font-size: 12px; } .btn-disconnect { width: 100%; justify-content: center; } .copy-notice { color: var(--brand); font-size: 12px; font-weight: 700; } .readonly-text { background: #f8fbff; font-size: 12px; } .meta { display: grid; gap: 8px; border-top: 1px solid var(--card-border); padding-top: 12px; } .meta p { margin: 0; display: flex; justify-content: space-between; gap: 8px; align-items: center; } .meta span { color: var(--muted); font-size: 13px; } .meta strong { font-size: 13px; word-break: break-all; text-align: right; max-width: 70%; } .toggle-row { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; font-weight: 600; } .toggle-row input { width: 16px; height: 16px; } .mobile-only, .mobile-nav { display: none; } .message-list::-webkit-scrollbar, .side-card::-webkit-scrollbar { width: 10px; } .message-list::-webkit-scrollbar-thumb, .side-card::-webkit-scrollbar-thumb { background: rgba(92, 116, 142, 0.28); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; } .message-list::-webkit-scrollbar-track, .side-card::-webkit-scrollbar-track { background: transparent; } .settings-head { align-items: center; justify-content: space-between; } @keyframes page-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } @keyframes msg-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } } @keyframes audio-wave { from { transform: scaleY(0.62); } to { transform: scaleY(1.12); } } @media (max-width: 980px) { html, body, #root { overflow: hidden; } .page { width: 100%; height: var(--vv-height); margin: 0; border-radius: 0; position: fixed; top: var(--vv-offset-top); left: 0; right: 0; } .hero { display: none; } .layout { display: block; position: relative; flex: 1; min-height: 0; } .layout.mobile-chat .side-card { display: none; } .layout.mobile-settings .chat-card { display: none; } .layout.mobile-chat .chat-card { padding-top: calc(env(safe-area-inset-top) + 54px); } .chat-card, .side-card { height: 100%; border-radius: 0; box-shadow: none; border-left: 0; border-right: 0; } .side-card { padding: 12px 12px 76px; gap: 12px; } .chat-head { display: none; } .chat-mode-strip.mobile-only { display: flex; justify-content: space-between; gap: 8px; padding: calc(env(safe-area-inset-top) + 7px) 10px 7px; border-bottom: 1px solid rgba(19, 35, 58, 0.1); background: rgba(255, 255, 255, 0.94); backdrop-filter: blur(8px); align-items: center; position: fixed; top: var(--vv-offset-top); left: 0; right: 0; z-index: 26; } .chat-mode-left { display: flex; gap: 6px; align-items: center; background: #edf3f8; border-radius: 14px; padding: 3px; } .mode-strip-icon { width: 28px; height: 28px; min-width: 28px; min-height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 10px; font-weight: 800; color: #fff; background: linear-gradient(130deg, var(--brand), #14b8a6); flex: 0 0 28px; } .chat-mode-strip .btn-mode { padding: 6px 9px; font-size: 11px; line-height: 1.2; border-radius: 11px; min-width: 56px; flex: 0 0 auto; background: transparent; color: #5f7084; box-shadow: none; } .chat-mode-strip .btn-mode.active { background: #ffffff; color: #0a5a55; box-shadow: 0 2px 8px rgba(18, 37, 61, 0.12); } .chat-mode-right { margin-left: auto; display: flex; align-items: center; gap: 6px; } .mobile-conn-btn { display: inline-flex; align-items: center; justify-content: center; gap: 5px; min-height: 30px; padding: 0 11px; border-radius: 11px; background: #f7fafc; color: #5f7084; font-size: 10px; font-weight: 800; border: 1px solid rgba(19, 35, 58, 0.12); white-space: nowrap; min-width: 94px; box-shadow: none; } .mobile-conn-btn .dot { width: 7px; height: 7px; background: #8da0b5; } .mobile-conn-btn.ok .dot { background: #0f766e; } .mobile-conn-btn.bad .dot { background: #be123c; } .mobile-conn-btn.loading .dot { background: #ea580c; } .mobile-conn-btn.ok { color: #0a5a55; background: rgba(15, 118, 110, 0.1); border-color: rgba(15, 118, 110, 0.28); } .mobile-conn-btn.bad { color: #9f1239; background: rgba(190, 18, 60, 0.08); border-color: rgba(190, 18, 60, 0.22); } .mobile-conn-btn.loading { color: #9a5800; background: rgba(234, 88, 12, 0.1); border-color: rgba(234, 88, 12, 0.24); } .mobile-conn-btn.actionable { color: #0a5a55; background: rgba(15, 118, 110, 0.14); border-color: rgba(15, 118, 110, 0.32); cursor: pointer; } .chat-target-box.mobile-only { display: block; padding: 8px 12px; border-bottom: 1px solid var(--card-border); background: rgba(255, 255, 255, 0.92); } .chat-target-box textarea { width: 100%; min-height: 64px; } .message-list { padding: 10px 10px calc(8px + 92px + env(safe-area-inset-bottom)); scroll-padding-bottom: calc(92px + env(safe-area-inset-bottom)); } .composer { position: sticky; bottom: 56px; grid-template-columns: auto 1fr auto; align-items: center; padding: 6px 8px; gap: 6px; background: rgba(247, 250, 253, 0.98); border-top: 1px solid rgba(19, 35, 58, 0.08); } .composer.audio-mode { grid-template-columns: auto 1fr; } .btn-send { width: auto; min-width: 56px; min-height: 34px; border-radius: 17px; align-self: center; padding: 0 12px; font-size: 12px; } .composer-input-wrap { border-radius: 22px; min-height: 40px; display: flex; align-items: center; padding: 6px 12px; } .btn-input-switch { min-width: 52px; min-height: 38px; border-radius: 19px; font-size: 12px; padding: 0 10px; } .hold-to-talk { min-height: 40px; border-radius: 20px; font-size: 13px; } .composer textarea { min-height: 20px; max-height: 88px; padding: 0; font-size: 16px; line-height: 1.35; } .mobile-only { display: inline-flex; } .desktop-only { display: none !important; } .settings-head.mobile-only { display: flex; } .mobile-nav { position: fixed; left: 0; right: 0; bottom: 0; height: 54px; display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--card-border); background: rgba(255, 255, 255, 0.96); backdrop-filter: blur(8px); z-index: 20; box-shadow: 0 -8px 18px rgba(21, 39, 64, 0.08); } .mobile-nav-btn { border: 0; background: transparent; font: inherit; color: #607086; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 3px 6px; } .mobile-nav-btn.active { color: #0a5a55; background: rgba(15, 118, 110, 0.12); } .mobile-nav-icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; } .mobile-nav-label { font-size: 10px; font-weight: 700; line-height: 1.1; } } @media (max-width: 640px) { .msg { max-width: 88%; padding-right: 38px; } .btn-copy { font-size: 10px; min-height: 20px; padding: 2px 7px; } }