/*! * OSGKeyboard 主页设计系统(2026-10 动效版) * 方向:Apple 式产品页 —— 深色产品舞台 + 实机画面优先 + 滚动叙事。 * 动效母题:「声音变成文字」—— 声波、涟漪、逐字浮现、流式转写。 * 主题跟随系统(site.js 可手动覆盖);Hero / 隐私 / 下载区块在两种 * 主题下都使用固定的深色「舞台」调色板,与新应用图标同一语言。 * * 渐进增强约定:所有「先隐藏、再显现」的初始态都挂在 html.js 之下; * 无 JavaScript 或开启「减弱动态效果」时,页面以完整静态形态呈现。 */ /* -------------------------------------------------------------------------- * 1. 设计令牌 * -------------------------------------------------------------------------- */ :root { color-scheme: light dark; --canvas: #f3f5f7; --surface: #ffffff; --surface-soft: #eceff3; --surface-strong: #e4e9ee; --ink: #0f1214; --ink-2: #55606a; --ink-3: #8a939c; --line: rgba(15, 18, 20, 0.09); --line-strong: rgba(15, 18, 20, 0.16); --accent: #2c8a52; --accent-strong: #217142; --accent-soft: rgba(44, 138, 82, 0.12); /* 深色舞台:Hero / 隐私 / 下载共用,两种主题下保持一致 */ --stage-1: #272d35; --stage-2: #14171c; --stage-3: #0c0e12; --stage-ink: #f4f6f7; --stage-ink-2: #a7b0b9; --stage-line: rgba(255, 255, 255, 0.1); --stage-accent: #6fc491; --content: min(1120px, calc(100vw - 48px)); --radius-xl: 28px; --radius-lg: 22px; --radius-md: 14px; --shadow-card: 0 28px 56px -28px rgba(16, 20, 24, 0.25); --shadow-media: 0 32px 64px -32px rgba(16, 20, 24, 0.35); /* 动效令牌:统一的缓动曲线与时长,所有组件只引用这里 */ --ease-out: cubic-bezier(0.16, 1, 0.3, 1); --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* 物理弹簧(linear() 采样),用于需要「落定感」的元素:气泡、芯片、胶囊 */ --ease-spring: linear( 0, 0.009, 0.035 2.1%, 0.141, 0.281 6.7%, 0.723 12.9%, 0.938 16.7%, 1.017, 1.077, 1.121, 1.149 24.3%, 1.159, 1.163, 1.161, 1.154 29.9%, 1.129 32.8%, 1.051 39.6%, 1.017 43.1%, 0.991, 0.977 51%, 0.974 53.8%, 0.975 57.1%, 0.997 69.8%, 1.003 76.9%, 1.004 83.8%, 1 ); --dur-fast: 0.22s; --dur-base: 0.5s; --dur-slow: 0.95s; /* 嵌入式手机演示的配色(随主题切换) */ --ph-bg: #ffffff; --ph-ink: #0f1214; --ph-muted: #8a939c; --ph-line: rgba(15, 18, 20, 0.1); --ph-in: #e9ecef; --ph-out: #2c8a52; /* 键盘复刻色:取自 App 源码 ColorLibrary(brandAccent / aiTeal / recordRed)与原生键面色 */ --kb-accent: #3aa05a; --kb-teal: #2bafa4; --kb-red: #ff3b30; --ph-kb: #efeeec; --ph-key: #ffffff; --ph-key-ink: #1c1c1e; --ph-key-off: #d6d6d6; --ph-track: rgba(0, 0, 0, 0.1); --ph-glass: rgba(255, 255, 255, 0.66); } html[data-theme="dark"] { --canvas: #0e1013; --surface: #16191d; --surface-soft: #12151a; --surface-strong: #20252b; --ink: #f2f4f5; --ink-2: #a4adb5; --ink-3: #7c858d; --line: rgba(255, 255, 255, 0.09); --line-strong: rgba(255, 255, 255, 0.16); --accent: #68bf8d; --accent-strong: #7dcd9e; --accent-soft: rgba(104, 191, 141, 0.14); --shadow-card: 0 28px 56px -28px rgba(0, 0, 0, 0.6); --shadow-media: 0 32px 64px -32px rgba(0, 0, 0, 0.65); --ph-bg: #0b0c0e; --ph-ink: #f2f4f5; --ph-muted: #7c858d; --ph-line: rgba(255, 255, 255, 0.1); --ph-in: #23262b; --ph-out: #2f9a5b; --ph-kb: #232324; --ph-key: #525252; --ph-key-ink: #ffffff; --ph-key-off: #3b3b3b; --ph-track: #1a1a1a; --ph-glass: rgba(255, 255, 255, 0.09); } /* -------------------------------------------------------------------------- * 2. 基础排版 * -------------------------------------------------------------------------- */ * { box-sizing: border-box; } html { scroll-behavior: smooth; scroll-padding-top: 84px; background: var(--canvas); } body { margin: 0; /* clip 不会生成滚动容器,滚动叙事的 position: sticky 才能正常工作 */ overflow-x: hidden; overflow-x: clip; background: var(--canvas); color: var(--ink); font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", "Hiragino Sans GB", "Helvetica Neue", Arial, sans-serif; font-size: 16px; line-height: 1.65; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } html[data-lang="en"] body { font-family: "Outfit", -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif; } a { color: inherit; text-decoration: none; } button, a { -webkit-tap-highlight-color: transparent; } button { color: inherit; font: inherit; } img, video { display: block; max-width: 100%; } h1, h2, h3, p { margin-top: 0; } h1, h2, h3 { text-wrap: balance; } html[data-lang="zh"] h1, html[data-lang="zh"] h2, html[data-lang="zh"] h3 { overflow-wrap: normal; word-break: keep-all; } ::selection { background: var(--accent); color: #fff; } :focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; } .skip-link { position: fixed; z-index: 100; top: 12px; left: 12px; padding: 9px 14px; border-radius: 999px; background: var(--ink); color: var(--canvas); transform: translateY(-160%); } .skip-link:focus { transform: translateY(0); } /* 仅供读屏:逐字拆分的标题由它提供完整句子 */ .sr-only { position: absolute; overflow: hidden; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; clip: rect(0 0 0 0); white-space: nowrap; } /* 内联 SVG 图标库容器:不可见但可被 引用 */ .svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; } /* 内联 SVG 图标系统:currentColor 描边,随主题变色 */ .i { width: 1.25em; height: 1.25em; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; vertical-align: -0.28em; } /* 页面滚动进度条:由 site.js 直接写 transform,避免每帧触发全局样式重算 */ .scroll-progress { position: fixed; z-index: 60; top: 0; right: 0; left: 0; height: 2px; background: linear-gradient(90deg, var(--stage-accent), #b5ecc9 60%, var(--stage-accent)); box-shadow: 0 0 12px rgba(111, 196, 145, 0.6); pointer-events: none; transform: scaleX(0); transform-origin: 0 50%; } /* -------------------------------------------------------------------------- * 3. 导航 * -------------------------------------------------------------------------- */ /* Hero 是深色舞台:导航在页面顶部时按深色舞台配色,滚动后切换为主题色 */ .site-nav { position: fixed; z-index: 50; top: 0; right: 0; left: 0; border-bottom: 1px solid transparent; color: var(--stage-ink); transition: background 0.35s ease, border-color 0.35s ease, color 0.35s ease; } .site-nav.is-scrolled { border-bottom-color: var(--line); background: color-mix(in srgb, var(--canvas) 78%, transparent); color: var(--ink); -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6); } .nav-shell { display: flex; width: var(--content); height: 64px; align-items: center; justify-content: space-between; margin: 0 auto; gap: 24px; } .brand { display: inline-flex; align-items: center; gap: 10px; font-size: 0.98rem; font-weight: 650; letter-spacing: -0.01em; } .brand img { width: 30px; height: 30px; border-radius: 8px; transition: transform var(--dur-base) var(--ease-spring); } .brand:hover img { transform: rotate(-8deg) scale(1.06); } .nav-links { position: relative; display: flex; align-items: center; gap: 4px; } .nav-links a { position: relative; z-index: 1; padding: 8px 14px; border-radius: 999px; font-size: 0.92rem; opacity: 0.72; transition: opacity 0.2s ease; } .nav-links a:hover, .nav-links a.is-active { opacity: 1; } /* 导航滑块:位置与宽度由 site.js 写入,弹簧曲线让它「跟手」 */ .nav-indicator { position: absolute; top: 50%; left: 0; width: var(--iw, 0px); height: 34px; border-radius: 999px; background: color-mix(in srgb, currentColor 11%, transparent); opacity: 0; pointer-events: none; transform: translate3d(var(--ix, 0px), -50%, 0); transition: transform 0.55s var(--ease-spring), width 0.55s var(--ease-spring), opacity 0.3s ease; } .nav-links.has-indicator .nav-indicator { opacity: 1; } .nav-actions { display: flex; align-items: center; gap: 8px; } .icon-button, .language-button { display: inline-grid; min-width: 38px; height: 38px; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 999px; background: transparent; cursor: pointer; opacity: 0.78; transition: opacity 0.2s ease, background 0.2s ease, transform 0.4s var(--ease-spring); } .language-button { font-size: 0.82rem; font-weight: 650; letter-spacing: 0.02em; } .icon-button:hover, .language-button:hover { background: color-mix(in srgb, currentColor 9%, transparent); opacity: 1; } .icon-button:active, .language-button:active { transform: scale(0.9); } .icon-button .i { width: 19px; height: 19px; transition: transform 0.6s var(--ease-spring); } #themeToggle:hover .i { transform: rotate(-24deg); } .mobile-menu-button { display: none; } .mobile-nav { display: none; } /* -------------------------------------------------------------------------- * 4. Hero —— 深色产品舞台 * -------------------------------------------------------------------------- */ .hero { position: relative; display: flex; min-height: 100svh; flex-direction: column; align-items: center; padding: 136px 0 0; overflow: hidden; isolation: isolate; background: radial-gradient(120% 90% at 50% 110%, rgba(111, 196, 145, 0.14), transparent 55%), linear-gradient(180deg, var(--stage-1) 0%, var(--stage-2) 52%, var(--stage-3) 100%); color: var(--stage-ink); text-align: center; } /* 背景层:极光 + 声波涟漪 + 点阵 + 指针光斑 */ .hero-backdrop { position: absolute; z-index: -1; inset: 0; overflow: hidden; pointer-events: none; } .aurora { position: absolute; border-radius: 50%; filter: blur(70px); mix-blend-mode: screen; opacity: 0.6; will-change: transform; } .aurora-a { top: -220px; left: calc(50% - 640px); width: 640px; height: 640px; background: radial-gradient(circle, rgba(111, 196, 145, 0.5), transparent 66%); animation: aurora-a 24s ease-in-out infinite alternate; } .aurora-b { top: 40px; right: calc(50% - 660px); width: 560px; height: 560px; background: radial-gradient(circle, rgba(70, 150, 190, 0.42), transparent 66%); animation: aurora-b 28s ease-in-out infinite alternate; } .aurora-c { bottom: -220px; left: 50%; width: 900px; height: 460px; margin-left: -450px; background: radial-gradient(closest-side, rgba(111, 196, 145, 0.32), transparent); animation: aurora-c 19s ease-in-out infinite alternate; } @keyframes aurora-a { 0% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(140px, 80px, 0) scale(1.18); } 100% { transform: translate3d(60px, 160px, 0) scale(0.94); } } @keyframes aurora-b { 0% { transform: translate3d(0, 0, 0) scale(1.05); } 50% { transform: translate3d(-120px, 60px, 0) scale(0.9); } 100% { transform: translate3d(-40px, -60px, 0) scale(1.15); } } @keyframes aurora-c { 0% { transform: translate3d(-80px, 0, 0) scale(1); } 100% { transform: translate3d(80px, -40px, 0) scale(1.12); } } /* 声波涟漪:三圈错相扩散,像一次持续的「开口」 */ .hero-rings i { position: absolute; top: 36%; left: 50%; width: 560px; height: 560px; margin: -280px 0 0 -280px; border: 1px solid rgba(111, 196, 145, 0.28); border-radius: 50%; opacity: 0; animation: ring-pulse 7.5s cubic-bezier(0.2, 0.6, 0.3, 1) infinite; } .hero-rings i:nth-child(2) { animation-delay: 2.5s; } .hero-rings i:nth-child(3) { animation-delay: 5s; } @keyframes ring-pulse { 0% { opacity: 0; transform: scale(0.3); } 14% { opacity: 0.9; } 100% { opacity: 0; transform: scale(2); } } .hero-grid { position: absolute; inset: 0; background-image: radial-gradient(rgba(255, 255, 255, 0.09) 1px, transparent 1px); background-size: 28px 28px; -webkit-mask-image: radial-gradient(ellipse 70% 55% at 50% 28%, #000 25%, transparent 75%); mask-image: radial-gradient(ellipse 70% 55% at 50% 28%, #000 25%, transparent 75%); } /* 指针光斑:--hx / --hy 由 site.js 以插值方式写入,移动有「拖尾」 */ .hero-spot { position: absolute; inset: 0; background: radial-gradient( 560px circle at var(--hx, 50%) var(--hy, 30%), rgba(111, 196, 145, 0.13), transparent 62% ); } /* 文字层随滚动轻微上移淡出(--hp 为 Hero 滚动进度 0 → 1) */ .hero-inner { position: relative; width: var(--content); opacity: calc(1 - var(--hp, 0) * 1.15); transform: translate3d(0, calc(var(--hp, 0) * -70px), 0); } .launch-pill { display: inline-flex; align-items: center; gap: 9px; margin-bottom: 26px; padding: 8px 16px; border: 1px solid var(--stage-line); border-radius: 999px; background: rgba(255, 255, 255, 0.06); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); color: var(--stage-ink-2); font-size: 0.82rem; font-weight: 550; letter-spacing: 0.01em; } .launch-dot { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--stage-accent); box-shadow: 0 0 12px rgba(111, 196, 145, 0.9); } .launch-dot::after { position: absolute; inset: 0; border-radius: 50%; background: var(--stage-accent); content: ""; animation: ping 2.4s cubic-bezier(0, 0, 0.2, 1) infinite; } @keyframes ping { 0% { opacity: 0.8; transform: scale(1); } 80%, 100% { opacity: 0; transform: scale(3); } } /* H1 承载品类关键词;视觉上是一行流光小标,主口号在其下方 */ .hero-kicker { margin: 0 auto 18px; background: linear-gradient( 100deg, var(--stage-accent) 0%, var(--stage-accent) 38%, #e2f7ea 50%, var(--stage-accent) 62%, var(--stage-accent) 100% ); background-size: 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; font-size: clamp(0.92rem, 1.4vw, 1.06rem); font-weight: 650; letter-spacing: 0.04em; line-height: 1.5; animation: shimmer 6.5s linear infinite; } @keyframes shimmer { from { background-position: 125% 0; } to { background-position: -125% 0; } } .hero-slogan { margin: 0 0 24px; } .slogan-main { display: block; font-size: clamp(3rem, 7.6vw, 5.7rem); font-weight: 700; letter-spacing: -0.045em; line-height: 1.02; text-shadow: 0 0 60px rgba(111, 196, 145, 0.18); } .slogan-sub { display: block; margin-top: 14px; color: var(--stage-ink-2); font-size: clamp(1.35rem, 2.8vw, 2.1rem); font-weight: 600; letter-spacing: -0.02em; line-height: 1.25; } .hero-copy { max-width: 640px; margin: 0 auto 34px; color: var(--stage-ink-2); font-size: 1.08rem; line-height: 1.7; } .hero-actions { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 18px; margin-bottom: 28px; } .store-badge { display: inline-flex; border-radius: 12px; transition: transform 0.5s var(--ease-spring), filter 0.3s ease; } .store-badge:hover { filter: drop-shadow(0 10px 24px rgba(111, 196, 145, 0.25)); } .store-badge img { width: 171px; height: 48px; } .ghost-action { display: inline-flex; align-items: center; gap: 8px; padding: 12px 22px; border: 1px solid var(--stage-line); border-radius: 999px; background: rgba(255, 255, 255, 0.06); color: var(--stage-ink); font-size: 0.95rem; font-weight: 600; transition: background 0.25s ease, border-color 0.25s ease, transform 0.5s var(--ease-spring); } .ghost-action:hover { border-color: rgba(111, 196, 145, 0.45); background: rgba(111, 196, 145, 0.12); } .ghost-action .i { width: 17px; height: 17px; transition: transform 0.5s var(--ease-spring); } .ghost-action:hover .i { transform: translate(3px, -3px) rotate(-8deg); } .text-action { color: var(--stage-ink-2); font-size: 0.95rem; font-weight: 550; text-decoration: underline; text-decoration-color: var(--stage-line); text-underline-offset: 5px; transition: color 0.2s ease, text-decoration-color 0.2s ease; } .text-action:hover { color: var(--stage-ink); text-decoration-color: var(--stage-accent); } .hero-trust { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 10px 28px; margin: 0 0 44px; padding: 0; color: var(--stage-ink-2); font-size: 0.86rem; list-style: none; } .hero-trust li { display: inline-flex; align-items: center; gap: 7px; } .hero-trust .i { width: 16px; height: 16px; color: var(--stage-accent); } /* 主视觉舞台:透视容器,内部设备图随滚动从后仰 14° 立到正视 */ .hero-stage { position: relative; width: min(1060px, 94vw); margin: auto 0 0; perspective: 1600px; } .hero-devices { transform: rotateX(calc((1 - var(--hp, 0)) * 14deg)) scale(calc(0.92 + var(--hp, 0) * 0.08)); transform-origin: 50% 100%; will-change: transform; } .hero-devices img { width: 100%; height: auto; filter: drop-shadow(0 48px 80px rgba(0, 0, 0, 0.5)); } /* 语音胶囊:毛玻璃深色药丸,悬浮在 Mac 屏幕下沿 */ .voice-capsule { position: absolute; z-index: 2; bottom: 22%; left: 50%; display: flex; max-width: 92%; align-items: center; gap: 14px; padding: 9px 22px 9px 10px; border: 1px solid rgba(255, 255, 255, 0.12); border-radius: 999px; background: rgba(14, 16, 19, 0.74); -webkit-backdrop-filter: blur(18px) saturate(1.6); backdrop-filter: blur(18px) saturate(1.6); box-shadow: 0 28px 60px -18px rgba(0, 0, 0, 0.75), inset 0 1px 0 rgba(255, 255, 255, 0.08); color: var(--stage-ink); translate: -50% 0; } /* * 麦克风胶囊:与键盘真实组件同色同形(156×60pt 的胶囊按比例缩小)。 * 待机 = 品牌绿 + 麦克风;录音 = 红色 + 7 条声波;长按问 AI = 青色 + 声波; * 处理中 = 半透明红 + 转圈;插入成功 = 品牌绿 + 对勾。状态类由 site.js 切换。 */ .capsule-mic { position: relative; display: grid; width: 78px; height: 32px; flex: none; place-items: center; border-radius: 999px; background: var(--kb-accent); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 6px 18px -6px color-mix(in srgb, var(--kb-accent) 80%, transparent); color: #fff; transition: background-color 0.35s ease, box-shadow 0.35s ease, transform 0.5s var(--ease-spring); } .capsule-mic > * { grid-area: 1 / 1; transition: opacity 0.25s ease, transform 0.45s var(--ease-spring); } .cap-mic { width: 17px; height: 17px; stroke-width: 2.2; } .cap-check { width: 18px; height: 18px; stroke-width: 3; } .capsule-wave, .capsule-spin, .cap-check { opacity: 0; transform: scale(0.6); } .voice-capsule.is-rec .capsule-mic { background: var(--kb-red); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 6px 22px -6px color-mix(in srgb, var(--kb-red) 85%, transparent); } .voice-capsule.is-ai .capsule-mic { background: var(--kb-teal); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 6px 22px -6px color-mix(in srgb, var(--kb-teal) 85%, transparent); transform: scale(1.04); } .voice-capsule.is-busy .capsule-mic { background: color-mix(in srgb, var(--kb-red) 72%, #2a2d31); } .voice-capsule:is(.is-rec, .is-ai, .is-busy, .is-done) .cap-mic { opacity: 0; transform: scale(0.6); } .voice-capsule:is(.is-rec, .is-ai) .capsule-wave, .voice-capsule.is-busy .capsule-spin, .voice-capsule.is-done .cap-check { opacity: 1; transform: none; } /* 声波条:site.js 每帧写 scaleY,只动 transform,不触发布局 */ .capsule-wave, .mic-wave { display: flex; align-items: center; } .capsule-wave { height: 16px; gap: 2.5px; } .capsule-wave i { width: 2.5px; height: 100%; border-radius: 2px; background: #ffc7c7; transform: scaleY(0.14); } .voice-capsule.is-ai .capsule-wave i { background: #fff; } /* 系统风格的转圈:处理中状态 */ .capsule-spin, .mic-spin { width: 15px; height: 15px; border: 2px solid rgba(255, 255, 255, 0.35); border-top-color: #fff; border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { rotate: 1turn; } } .capsule-body { display: flex; min-width: min(400px, 52vw); align-items: center; gap: 10px; font-size: 0.98rem; text-align: left; white-space: nowrap; } .capsule-tag { flex: none; padding: 3px 10px; border-radius: 999px; background: rgba(111, 196, 145, 0.16); color: var(--stage-accent); font-size: 0.74rem; font-weight: 700; letter-spacing: 0.04em; transition: background 0.3s ease, color 0.3s ease; } /* 标签颜色跟随胶囊状态:问 AI 用青色,与麦克风胶囊呼应 */ .voice-capsule:is(.is-ai, .is-ai-busy) .capsule-tag { background: color-mix(in srgb, var(--kb-teal) 22%, transparent); color: #7fded4; } .capsule-line { overflow: hidden; min-width: 0; text-overflow: ellipsis; } .caret { display: inline-block; width: 2px; height: 1.1em; flex: none; margin-left: 1px; border-radius: 1px; background: var(--stage-accent); vertical-align: -0.18em; animation: caret-blink 1.05s steps(1) infinite; } @keyframes caret-blink { 50% { opacity: 0; } } .scroll-cue { position: absolute; z-index: 3; right: 32px; bottom: 30px; display: grid; width: 24px; height: 38px; justify-items: center; padding-top: 7px; border: 1.5px solid rgba(255, 255, 255, 0.28); border-radius: 999px; opacity: calc(1 - var(--hp, 0) * 4); } .scroll-cue span { width: 3px; height: 8px; border-radius: 3px; background: var(--stage-ink); animation: cue 2s var(--ease-in-out) infinite; } @keyframes cue { 0% { opacity: 0; transform: translateY(-3px); } 30% { opacity: 1; } 100% { opacity: 0; transform: translateY(12px); } } /* 首屏进场:Hero 元素按 --d 错峰「浮现 + 去模糊」 */ html.js .hero-in { animation: rise-in 1.1s var(--ease-out) var(--d, 0s) both; } @keyframes rise-in { from { opacity: 0; filter: blur(8px); translate: 0 26px; } to { opacity: 1; filter: none; translate: 0 0; } } html.js .voice-capsule { animation: capsule-in 1.1s var(--ease-spring) 1.6s both; } @keyframes capsule-in { from { opacity: 0; transform: translateY(24px) scale(0.86); } to { opacity: 1; transform: none; } } /* -------------------------------------------------------------------------- * 5. 逐字动效(data-split) * site.js 把文字拆成 .w(词,防止英文断词)与 .ch(字符), * 每个字符带 --ci 序号,延迟 = 基础延迟 + 序号 × 步长。 * -------------------------------------------------------------------------- */ [data-split] .w { display: inline-block; white-space: nowrap; } [data-split] .ch { display: inline-block; } /* 拆分完成前先隐藏,避免「整句出现 → 被拆开重播」的闪烁 */ html.js [data-split]:not(.is-split) { opacity: 0; } /* Hero 口号:页面加载即播放 */ html.js .hero-slogan .ch { animation: char-in 1s var(--ease-out) both; animation-delay: calc(var(--base, 0.2s) + var(--ci) * var(--step, 45ms)); } .slogan-main { --base: 0.22s; --step: 52ms; } .slogan-sub { --base: 0.52s; --step: 24ms; } @keyframes char-in { from { opacity: 0; filter: blur(10px); transform: translateY(0.55em) rotate(3deg); } to { opacity: 1; filter: none; transform: none; } } /* 区块标题:所在 .reveal 进入视口时播放 */ html.js .reveal [data-split] .ch { opacity: 0; filter: blur(8px); transform: translateY(0.5em); transition: opacity 0.7s ease-out, filter 0.7s ease-out, transform 0.95s var(--ease-out); transition-delay: calc(var(--d, 0s) + 0.08s + var(--ci) * 24ms); } html.js .reveal.is-visible [data-split] .ch { opacity: 1; filter: blur(0); transform: none; } /* -------------------------------------------------------------------------- * 6. 能力跑马灯 * -------------------------------------------------------------------------- */ .marquee { overflow: hidden; padding: 20px 0; border-bottom: 1px solid var(--line); background: var(--canvas); -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent); mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent); } .marquee-track { display: flex; width: max-content; animation: marquee 52s linear infinite; } .marquee:hover .marquee-track { animation-play-state: paused; } .marquee ul { display: flex; margin: 0; padding: 0; list-style: none; } .marquee li { display: flex; align-items: center; gap: 30px; padding-right: 30px; color: var(--ink-3); font-size: clamp(1.05rem, 1.8vw, 1.4rem); font-weight: 650; letter-spacing: -0.01em; white-space: nowrap; } .marquee li:nth-child(-n + 3) { color: var(--ink); } .marquee li::after { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); content: ""; opacity: 0.55; } @keyframes marquee { to { transform: translateX(-50%); } } /* -------------------------------------------------------------------------- * 7. 通用区块节奏 * -------------------------------------------------------------------------- */ .section { padding: clamp(88px, 11vw, 136px) 0; } .section-alt { background: var(--surface-soft); } .section-inner { width: var(--content); margin: 0 auto; } .eyebrow { margin-bottom: 14px; color: var(--accent); font-size: 0.82rem; font-weight: 650; letter-spacing: 0.06em; } h2 { margin-bottom: 18px; font-size: clamp(1.9rem, 3.8vw, 2.8rem); font-weight: 700; letter-spacing: -0.024em; line-height: 1.14; } h3 { font-size: 1.12rem; font-weight: 650; letter-spacing: -0.01em; } .center-heading { max-width: 700px; margin: 0 auto clamp(48px, 6vw, 72px); text-align: center; } .center-heading p:not(.eyebrow) { color: var(--ink-2); font-size: 1.05rem; } /* 分栏布局:文案 + 媒体 */ .split-layout { display: grid; align-items: center; gap: clamp(40px, 6vw, 88px); grid-template-columns: 1.02fr 1fr; } .split-layout.reverse .feature-copy { order: 2; } .split-layout.reverse .media-frame { order: 1; } .feature-copy > p:not(.eyebrow) { color: var(--ink-2); font-size: 1.05rem; } .feature-note { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); color: var(--ink-3); font-size: 0.92rem; } /* 实机媒体框:边框 + 定向长投影,呼应 iOS 端 2.1 的卡片层次 */ .media-frame { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface-strong); box-shadow: var(--shadow-media); } .media-frame video, .media-frame img { width: 100%; height: auto; } /* -------------------------------------------------------------------------- * 8. 四种输入方式速览 * -------------------------------------------------------------------------- */ .ways-section { padding: clamp(64px, 8vw, 96px) 0; } .ways-grid { display: grid; gap: 16px; grid-template-columns: repeat(4, 1fr); } .way-card { display: block; padding: 26px 24px 24px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); transition: transform 0.5s var(--ease-out), box-shadow 0.35s ease, border-color 0.35s ease; } .way-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-card); } .way-icon { position: relative; display: inline-grid; width: 46px; height: 46px; margin-bottom: 18px; place-items: center; border-radius: 14px; background: var(--accent-soft); color: var(--accent); } .way-icon .i { width: 23px; height: 23px; } /* 图标微动效:每张卡片一个与功能对应的小动作 */ .way-icon-mic::after { position: absolute; inset: 0; border: 1.5px solid var(--accent); border-radius: inherit; content: ""; opacity: 0; } .way-card:hover .way-icon-mic::after { animation: orb-ripple 1.4s cubic-bezier(0.2, 0.6, 0.3, 1) infinite; } .way-card:hover .way-icon-sparkle .i { animation: twinkle 0.9s var(--ease-spring); } .way-card:hover .way-icon-bubble .i { animation: bob 0.9s var(--ease-spring); } .way-card:hover .way-icon-paste .i { animation: drop 0.9s var(--ease-spring); } @keyframes twinkle { 0% { transform: scale(1) rotate(0); } 40% { transform: scale(0.7) rotate(-40deg); } 100% { transform: scale(1) rotate(0); } } @keyframes bob { 0% { transform: translateY(0); } 35% { transform: translateY(-5px) rotate(-6deg); } 100% { transform: translateY(0); } } @keyframes drop { 0% { transform: translateY(0); } 35% { transform: translateY(4px) scale(0.92); } 100% { transform: translateY(0); } } .way-card h3 { margin-bottom: 6px; } .way-card p { margin: 0; color: var(--ink-2); font-size: 0.92rem; line-height: 1.55; } /* -------------------------------------------------------------------------- * 9. 滚动叙事(三幕剧) * 消息类 m1/o1/m2/c2/o2/m3/c3/ev 与键盘 data-* 状态由 site.js 依滚动进度写到 .story 上; * 只有 .story.is-live(脚本已接管)时才进入「未发生 → 隐藏」的初始态, * 无 JavaScript 时手机直接展示最终画面。 * -------------------------------------------------------------------------- */ .story-section { padding-bottom: 0; } .story-section .center-heading { margin-bottom: 0; } .story { position: relative; height: 430vh; } .story-sticky { position: sticky; top: 0; display: flex; height: 100vh; height: 100svh; align-items: center; padding-top: 64px; } .story-layout { display: grid; width: var(--content); align-items: center; gap: clamp(40px, 7vw, 120px); margin: 0 auto; grid-template-columns: 1fr auto; } .story-acts { display: grid; max-width: 540px; gap: 12px; margin: 0; padding: 0; list-style: none; } .story-act { display: flex; gap: 22px; padding: 22px 24px; border-radius: var(--radius-lg); opacity: 0.36; transition: opacity 0.5s ease, background 0.5s ease, box-shadow 0.5s ease, transform 0.7s var(--ease-out); } .story-act.is-active { background: var(--surface); box-shadow: var(--shadow-card), inset 0 0 0 1px var(--line); opacity: 1; transform: translateX(6px); } .act-index { padding-top: 3px; color: var(--accent); font-size: 0.82rem; font-variant-numeric: tabular-nums; font-weight: 700; letter-spacing: 0.04em; } .act-body { flex: 1; } .act-kicker { margin: 0 0 6px; color: var(--accent); font-size: 0.8rem; font-weight: 700; letter-spacing: 0.06em; } .act-body h3 { margin-bottom: 8px; font-size: clamp(1.22rem, 2vw, 1.55rem); letter-spacing: -0.02em; } .act-body > p:not(.act-kicker) { margin: 0; color: var(--ink-2); font-size: 0.97rem; } /* 幕内进度条:--ap 由 site.js 写入(0 → 1) */ .act-bar { display: block; overflow: hidden; height: 2px; margin-top: 16px; border-radius: 2px; background: var(--line); } .act-bar i { display: block; height: 100%; background: var(--accent); transform: scaleX(var(--ap, 0)); transform-origin: left; } /* 舞台:手机 + 背后呼吸光晕 */ .story-device { position: relative; display: grid; place-items: center; } .story-device::before { position: absolute; width: 140%; height: 80%; border-radius: 50%; background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 26%, transparent), transparent); content: ""; filter: blur(30px); opacity: 0.55; transition: opacity 0.6s ease, transform 0.8s var(--ease-out); } .story:is([data-mic="rec"], [data-mic="busy"]) .story-device::before { opacity: 1; transform: scale(1.08); } /* 手机外壳:容器查询单位(cqw)让内部 UI 随机身等比缩放 */ .phone { --w: min(340px, calc((100svh - 150px) * 0.468)); position: relative; width: var(--w); aspect-ratio: 9 / 19.2; padding: calc(var(--w) * 0.034); border-radius: calc(var(--w) * 0.16); background: linear-gradient(145deg, #39404a, #0d0f12 60%); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 60px 100px -40px rgba(0, 0, 0, 0.5), 0 30px 60px -30px rgba(16, 20, 24, 0.35); container-type: inline-size; } .phone-screen { position: relative; display: flex; overflow: hidden; height: 100%; flex-direction: column; border-radius: 12.6cqw; background: var(--ph-bg); color: var(--ph-ink); font-size: 4cqw; line-height: 1.38; text-align: left; } .phone-status { display: flex; height: 12cqw; flex: none; align-items: center; justify-content: space-between; padding: 1.6cqw 8cqw 0; font-size: 3.6cqw; font-weight: 650; } .phone-island { position: absolute; top: 2.8cqw; left: 50%; width: 27cqw; height: 7.6cqw; margin-left: -13.5cqw; border-radius: 99px; background: #000; } .phone-signal { display: flex; align-items: flex-end; gap: 0.7cqw; height: 2.8cqw; } .phone-signal i { width: 0.9cqw; border-radius: 0.4cqw; background: currentColor; } .phone-signal i:nth-child(1) { height: 40%; } .phone-signal i:nth-child(2) { height: 70%; } .phone-signal i:nth-child(3) { height: 100%; } .chat-head { display: flex; flex: none; flex-direction: column; align-items: center; gap: 1.2cqw; padding: 1.2cqw 0 3cqw; border-bottom: 1px solid var(--ph-line); } .chat-avatar { display: grid; width: 11cqw; height: 11cqw; place-items: center; border-radius: 50%; background: linear-gradient(145deg, #7fd0a0, #2c8a52); color: #fff; font-size: 4.4cqw; font-weight: 700; } .chat-name { display: grid; justify-items: center; line-height: 1.2; } .chat-name b { font-size: 3.4cqw; font-weight: 650; } .chat-name small { color: var(--ph-muted); font-size: 2.7cqw; } /* 底部对齐:新消息出现时把旧消息向上推,和真实聊天一样 */ .chat-body { display: flex; overflow: hidden; min-height: 0; flex: 1; flex-direction: column; justify-content: flex-end; padding: 1cqw 4.4cqw 3cqw; } .bubble { position: relative; flex: none; max-width: 76%; margin-top: 2.4cqw; padding: 2.1cqw 3.4cqw; border-radius: 5cqw; font-size: 3.6cqw; transition: opacity 0.35s ease, transform 0.7s var(--ease-spring), box-shadow 0.4s ease, max-height 0.5s var(--ease-out), margin 0.5s var(--ease-out), padding 0.5s var(--ease-out); } .bubble.in { align-self: flex-start; border-bottom-left-radius: 1.4cqw; background: var(--ph-in); transform-origin: 0 100%; } .bubble.out { align-self: flex-end; border-bottom-right-radius: 1.4cqw; background: var(--ph-out); color: #fff; transform-origin: 100% 100%; } /* 未出现的气泡不占位(高度收为 0),出现时弹簧放大 */ .story.is-live .bubble { max-height: 0; margin-top: 0; padding-block: 0; opacity: 0; transform: translateY(3cqw) scale(0.6); } .story.is-live.m1 .b-m1, .story.is-live.o1 .b-o1, .story.is-live.m2 .b-m2, .story.is-live.o2 .b-o2, .story.is-live.m3 .b-m3 { max-height: 40cqw; margin-top: 2.4cqw; padding-block: 2.1cqw; opacity: 1; transform: none; } /* 长按复制:气泡描边高亮 + 「已复制」提示 */ .story.c2 .b-m2, .story.c3 .b-m3, .skills-demo.is-copied .sd-msg { box-shadow: 0 0 0 0.8cqw color-mix(in srgb, var(--kb-accent) 40%, transparent); } .copy-toast { position: absolute; top: -6.8cqw; left: 4cqw; display: flex; align-items: center; gap: 1cqw; padding: 1.1cqw 2.6cqw; border-radius: 99px; background: var(--ph-ink); color: var(--ph-bg); font-size: 2.9cqw; font-weight: 600; opacity: 0; transform: translateY(2cqw) scale(0.8); transition: opacity 0.3s ease, transform 0.6s var(--ease-spring); } .copy-toast .i { width: 3.4cqw; height: 3.4cqw; stroke-width: 2.4; } .story.c2 .b-m2 .copy-toast, .story.c3 .b-m3 .copy-toast, .skills-demo.is-copied .copy-toast { opacity: 1; transform: none; } /* 日历通知横幅:从刘海下方落下 */ .event-banner { position: absolute; z-index: 3; top: 2.6cqw; right: 3.4cqw; left: 3.4cqw; display: flex; align-items: center; gap: 3cqw; padding: 3cqw 3.4cqw; border-radius: 6cqw; background: color-mix(in srgb, var(--ph-bg) 82%, transparent); -webkit-backdrop-filter: blur(20px) saturate(1.5); backdrop-filter: blur(20px) saturate(1.5); box-shadow: 0 6cqw 12cqw -4cqw rgba(0, 0, 0, 0.35), inset 0 0 0 1px var(--ph-line); transition: transform 0.9s var(--ease-spring), opacity 0.4s ease; } .story.is-live .event-banner { opacity: 0; transform: translateY(-130%) scale(0.92); } .story.is-live.ev .event-banner { opacity: 1; transform: none; } .event-icon { display: grid; width: 10cqw; height: 10cqw; flex: none; place-items: center; border-radius: 2.8cqw; background: var(--ph-out); color: #fff; } .event-icon .i { width: 5.4cqw; height: 5.4cqw; } .event-copy { display: grid; min-width: 0; flex: 1; line-height: 1.3; } .event-copy small { color: var(--ph-muted); font-size: 2.7cqw; } .event-copy b { font-size: 3.5cqw; } .event-copy span { overflow: hidden; color: var(--ph-muted); font-size: 2.9cqw; text-overflow: ellipsis; white-space: nowrap; } .event-check { display: grid; width: 6.4cqw; height: 6.4cqw; flex: none; place-items: center; border-radius: 50%; background: color-mix(in srgb, var(--ph-out) 18%, transparent); color: var(--ph-out); transition: transform 0.7s var(--ease-spring) 0.35s; } .event-check .i { width: 4cqw; height: 4cqw; stroke-width: 2.6; } .story.is-live .event-check { transform: scale(0); } .story.is-live.ev .event-check { transform: none; } /* 输入框:文字由 site.js 按滚动进度逐字写入 */ .compose { display: flex; flex: none; align-items: flex-end; gap: 2.4cqw; padding: 2.4cqw 3.6cqw 2.8cqw; } .compose-field { position: relative; display: block; min-height: 9.4cqw; flex: 1; padding: 2cqw 3.6cqw; border-radius: 4.8cqw; box-shadow: inset 0 0 0 1px var(--ph-line); font-size: 3.7cqw; } .compose-placeholder { position: absolute; top: 2cqw; left: 3.6cqw; color: var(--ph-muted); transition: opacity 0.2s ease; } .story.has-text .compose-placeholder { opacity: 0; } .compose-text { position: relative; } .compose-text.is-swapping { animation: text-swap 0.45s var(--ease-out); } @keyframes text-swap { from { opacity: 0; filter: blur(4px); } to { opacity: 1; filter: blur(0); } } .compose .caret { background: var(--ph-out); visibility: hidden; } .story.has-text .compose .caret { visibility: visible; } .compose-send { display: grid; width: 9.4cqw; height: 9.4cqw; flex: none; place-items: center; border-radius: 50%; background: var(--ph-line); color: #fff; transition: background 0.3s ease, transform 0.6s var(--ease-spring); } .compose-send .i { width: 5cqw; height: 5cqw; stroke-width: 2.4; } .story.has-text .compose-send { background: var(--ph-out); transform: scale(1.05); } /* * 键盘:按 App 真实的「AI 助手」界面复刻(AIKeyboardView)。 * 尺寸以 cqw 表示,等比映射原生 pt 尺寸(顶栏 44pt、麦克风 156×60pt、圆键 48pt)。 * 所有状态都由祖先元素上的 data-* 属性驱动,故事区与技能区共用同一套样式: * data-bar 顶栏:tabs 常规 / cancel 录音中 / paste AI 结果 / skills 复制后 * data-mic 麦克风:idle / rec 听写 / ai 问 AI / busy 处理中 / done 已插入 * data-ctx 上下文区:hint / live / think / extract / tip / none * data-surface 主体:main 常规 / variants 回复候选 * data-pick 被点按的元素:0-2 回复卡片 / event 日程胶囊 * data-undo 插入后出现撤销与改写按钮;data-action 回车键可用 */ .kb { display: flex; flex: none; flex-direction: column; padding: 1cqw 3cqw 7cqw; background: var(--ph-kb); color: var(--ph-key-ink); transition: background 0.4s ease; } .kb .i { stroke-width: 2; } .kb-top { position: relative; height: 10.5cqw; flex: none; } .kb-bar { position: absolute; inset: 0; display: flex; align-items: center; gap: 1.6cqw; opacity: 0; pointer-events: none; transform: translateY(1.5cqw); transition: opacity 0.3s ease, transform 0.55s var(--ease-spring); } [data-bar="tabs"] .kb-bar-tabs, [data-bar="cancel"] .kb-bar-cancel, [data-bar="paste"] .kb-bar-paste, [data-bar="skills"] .kb-bar-skills { opacity: 1; transform: none; } .kb-bar-tabs, .kb-bar-paste { justify-content: space-between; } .kb-bar-cancel { justify-content: flex-end; } /* OSG 标志:两实一空的三个圆点 */ .kb-logo { display: flex; gap: 0.8cqw; } .kb-logo i { width: 3.4cqw; height: 3.4cqw; border-radius: 50%; background: currentColor; } .kb-logo i:nth-child(2) { background: transparent; box-shadow: inset 0 0 0 0.45cqw currentColor; } /* AI / 中文 / EN 分段切换:固定在键盘水平中心,与真实界面一致 */ .kb-seg { position: absolute; left: 50%; display: flex; gap: 0.5cqw; padding: 0.5cqw; border-radius: 99px; background: var(--ph-track); translate: -50% 0; } .kb-seg > span { display: grid; width: 11.4cqw; height: 7.2cqw; place-items: center; border-radius: 99px; color: color-mix(in srgb, var(--ph-key-ink) 55%, transparent); font-size: 2.85cqw; font-weight: 500; } .kb-seg > .is-on { background: var(--ph-key); box-shadow: 0 0 0 0.25cqw var(--ph-line); color: var(--ph-key-ink); } .kb-seg .i { width: 3.7cqw; height: 3.7cqw; } .kb-chips { display: flex; gap: 1.4cqw; } .kb-chip { display: grid; width: 8.2cqw; height: 8.2cqw; flex: none; place-items: center; border-radius: 50%; background: var(--ph-key); box-shadow: 0 0 0 0.25cqw var(--ph-line); color: color-mix(in srgb, var(--ph-key-ink) 60%, transparent); } .kb-chip .i { width: 3.8cqw; height: 3.8cqw; } /* 玻璃胶囊:粘贴与技能 */ .kb-cap { display: inline-flex; height: 7.2cqw; flex: none; align-items: center; padding: 0 3cqw; border-radius: 99px; background: var(--ph-glass); box-shadow: 0 0.6cqw 1.6cqw -0.6cqw rgba(0, 0, 0, 0.2), inset 0 0 0 0.25cqw var(--ph-line); font-size: 3cqw; font-weight: 650; white-space: nowrap; transition: background 0.25s ease, color 0.25s ease, transform 0.45s var(--ease-spring); } .kb-caps { display: flex; overflow: hidden; min-width: 0; flex: 1; gap: 1.4cqw; padding: 1cqw 0; -webkit-mask-image: linear-gradient(90deg, #000 86%, transparent); mask-image: linear-gradient(90deg, #000 86%, transparent); } /* 复制后技能胶囊依次弹出:模拟「按相关度挑出能用的技能」 */ [data-bar="skills"] .kb-caps .kb-cap { animation: cap-in 0.55s var(--ease-spring) both; } .kb-caps .kb-cap:nth-child(2) { animation-delay: 0.06s; } .kb-caps .kb-cap:nth-child(3) { animation-delay: 0.12s; } .kb-caps .kb-cap:nth-child(4) { animation-delay: 0.18s; } .kb-caps .kb-cap:nth-child(5) { animation-delay: 0.24s; } @keyframes cap-in { from { opacity: 0; transform: translateY(2cqw) scale(0.7); } to { opacity: 1; transform: none; } } [data-pick="event"] .cap-event { background: var(--kb-accent); color: #fff; transform: scale(0.94); } /* 主体:上下文区 + 两排操作键;回复候选出现时整体让位 */ .kb-stage { position: relative; height: 51cqw; flex: none; } .kb-main { position: absolute; inset: 0; display: flex; flex-direction: column; transition: opacity 0.3s ease, transform 0.5s var(--ease-out); } [data-surface="variants"] .kb-main { opacity: 0; transform: scale(0.97); } .kb-ctx { position: relative; flex: 1; } .ctx { position: absolute; top: 50%; left: 50%; max-width: 88%; font-size: 3.3cqw; opacity: 0; text-align: center; transform: translate(-50%, -30%); transition: opacity 0.3s ease, transform 0.5s var(--ease-out); white-space: nowrap; } [data-ctx="hint"] .ctx-hint, [data-ctx="live"] .ctx-live, [data-ctx="think"] .ctx-think, [data-ctx="extract"] .ctx-extract, [data-ctx="tip"] .ctx-tip { opacity: 1; transform: translate(-50%, -50%); } .ctx-hint { padding: 1.2cqw 3.2cqw; border-radius: 99px; box-shadow: inset 0 0 0 0.3cqw color-mix(in srgb, var(--ph-key-ink) 18%, transparent); color: color-mix(in srgb, var(--ph-key-ink) 55%, transparent); font-weight: 500; } /* 实时转写:听写时边说边出字 */ .ctx-live { width: 88%; font-size: 3.7cqw; line-height: 1.35; white-space: normal; } .ctx-think, .ctx-extract { color: color-mix(in srgb, var(--ph-key-ink) 55%, transparent); font-size: 3.6cqw; } .ctx-tip { padding: 1.6cqw 3.6cqw; border-radius: 99px; background: var(--ph-glass); box-shadow: 0 1cqw 3cqw -1cqw rgba(0, 0, 0, 0.22), inset 0 0 0 0.25cqw var(--ph-line); font-size: 3.6cqw; } .kb-row { display: flex; height: 14.3cqw; flex: none; align-items: center; justify-content: space-between; padding: 0 2cqw; } .kb-row-low { height: 11.4cqw; margin-top: 5.2cqw; } .kb-circle { display: grid; width: 11.4cqw; height: 11.4cqw; flex: none; place-items: center; border-radius: 50%; background: var(--ph-key); box-shadow: 0 1cqw 2.4cqw -1cqw rgba(0, 0, 0, 0.25), inset 0 0 0 0.25cqw var(--ph-line); transition: opacity 0.35s ease, scale 0.5s var(--ease-spring); } .kb-circle .i { width: 5cqw; height: 5cqw; } /* 撤销与口述改写只在刚插入过文字后出现 */ .kb-undo, .kb-edit { opacity: 0; scale: 0.7; } [data-undo="1"] .kb-undo, [data-undo="1"] .kb-edit { opacity: 1; scale: 1; } .kb-mic { position: relative; display: grid; width: 37cqw; height: 14.3cqw; flex: none; place-items: center; border-radius: 99px; background: var(--kb-accent); box-shadow: inset 0 0.3cqw 0 rgba(255, 255, 255, 0.3), 0 1.6cqw 4cqw -1.6cqw color-mix(in srgb, var(--kb-accent) 85%, transparent); color: #fff; transition: background-color 0.35s ease, box-shadow 0.35s ease, transform 0.5s var(--ease-spring); } .kb-mic > * { grid-area: 1 / 1; transition: opacity 0.25s ease, transform 0.45s var(--ease-spring); } .mic-icon { width: 6.6cqw; height: 6.6cqw; } .kb .mic-check { width: 7cqw; height: 7cqw; stroke-width: 3; } .mic-wave { height: 6.2cqw; gap: 1cqw; } .mic-wave i { width: 1cqw; height: 100%; border-radius: 1cqw; background: #ffc7c7; transform: scaleY(0.14); } .kb .mic-spin { width: 5.2cqw; height: 5.2cqw; border-width: 0.7cqw; } .mic-wave, .mic-spin, .mic-check { opacity: 0; transform: scale(0.6); } [data-mic="rec"] .kb-mic { background: var(--kb-red); box-shadow: inset 0 0.3cqw 0 rgba(255, 255, 255, 0.3), 0 1.6cqw 4.4cqw -1.6cqw color-mix(in srgb, var(--kb-red) 85%, transparent); } [data-mic="ai"] .kb-mic { background: var(--kb-teal); transform: scale(1.03); } [data-mic="ai"] .mic-wave i { background: #fff; } [data-mic="busy"] .kb-mic { background: color-mix(in srgb, var(--kb-red) 72%, var(--ph-kb)); box-shadow: none; } :is([data-mic="rec"], [data-mic="ai"], [data-mic="busy"], [data-mic="done"]) .mic-icon { opacity: 0; transform: scale(0.6); } :is([data-mic="rec"], [data-mic="ai"]) .mic-wave, [data-mic="busy"] .mic-spin, [data-mic="done"] .mic-check { opacity: 1; transform: none; } /* 回车 / 发送:无可发送内容时为浅灰禁用态 */ .kb-action { display: grid; width: 31.4cqw; height: 11.4cqw; flex: none; place-items: center; border-radius: 99px; background: var(--ph-key-off); color: color-mix(in srgb, var(--ph-key-ink) 45%, transparent); transition: background 0.3s ease, color 0.3s ease, transform 0.45s var(--ease-spring); } .kb-action .i { width: 5.4cqw; height: 5.4cqw; } [data-action="on"] .kb-action { background: var(--ph-key); box-shadow: 0 1cqw 2.4cqw -1cqw rgba(0, 0, 0, 0.25), inset 0 0 0 0.25cqw var(--ph-line); color: var(--ph-key-ink); } .story.press-send .kb-action { animation: key-press 0.5s var(--ease-out); } @keyframes key-press { 30% { transform: scale(0.9); } } /* 回复候选:三张玻璃卡片(普通 / 正式 / 轻松趣味),自下而上依次落定 */ .kb-variants { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 1.8cqw; padding: 1.2cqw 0.6cqw 0; pointer-events: none; } .kb-card { display: flex; align-items: flex-start; gap: 2.6cqw; padding: 2cqw 3cqw; border-radius: 3.6cqw; background: var(--ph-glass); box-shadow: 0 0.8cqw 2.4cqw -1.2cqw rgba(0, 0, 0, 0.2), inset 0 0 0 0.25cqw var(--ph-line); opacity: 0; transform: translateY(5cqw) scale(0.96); transition: opacity 0.35s ease, transform 0.6s var(--ease-spring), box-shadow 0.3s ease; } .kb-card:nth-child(2) { transition-delay: 0.07s; } .kb-card:nth-child(3) { transition-delay: 0.14s; } [data-surface="variants"] .kb-card { opacity: 1; transform: none; } .kb-card .i-solid { width: 4.6cqw; height: 4.6cqw; flex: none; margin-top: 0.4cqw; fill: currentColor; stroke: none; } .kb-card > span { display: grid; gap: 0.3cqw; line-height: 1.32; } .kb-card small { color: color-mix(in srgb, var(--ph-key-ink) 55%, transparent); font-size: 2.7cqw; } .kb-card b { font-size: 3.2cqw; font-weight: 500; } [data-pick="0"] .kb-card[data-card="0"], [data-pick="1"] .kb-card[data-card="1"], [data-pick="2"] .kb-card[data-card="2"] { box-shadow: 0 0 0 0.7cqw color-mix(in srgb, var(--kb-accent) 50%, transparent); transform: scale(0.97); transition-delay: 0s; } /* -------------------------------------------------------------------------- * 技能区演示:复用键盘复刻组件,独立的容器查询让它按自身宽度缩放 * -------------------------------------------------------------------------- */ .skills-frame { display: grid; place-items: center; padding: clamp(18px, 3vw, 34px); background: radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--accent) 14%, var(--surface)), var(--surface-soft)); } .skills-demo { display: flex; overflow: hidden; width: min(100%, 430px); flex-direction: column; border-radius: 22px; background: var(--ph-bg); box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.45), inset 0 0 0 1px var(--ph-line); color: var(--ph-ink); container-type: inline-size; text-align: left; } /* 消息来源区:被复制的那条消息,最后被「已添加到日历」横幅替换 */ .sd-source { position: relative; display: grid; min-height: 34cqw; align-items: center; padding: 7cqw 5cqw; } .sd-msg { position: relative; justify-self: start; max-width: 82%; padding: 2.4cqw 3.8cqw; border-radius: 5cqw 5cqw 5cqw 1.4cqw; background: var(--ph-in); font-size: 3.7cqw; line-height: 1.4; transition: box-shadow 0.4s ease, opacity 0.4s ease, transform 0.6s var(--ease-out); } .skills-demo .event-banner { top: 50%; right: 5cqw; left: 5cqw; translate: 0 -50%; } .skills-demo .event-banner, .skills-demo .event-check { opacity: 0; transform: translateY(-40%) scale(0.92); } .skills-demo .event-check { transform: scale(0); } .skills-demo.is-done .event-banner { opacity: 1; transform: none; } .skills-demo.is-done .event-check { opacity: 1; transform: none; } .skills-demo.is-done .sd-msg { opacity: 0; transform: translateY(6cqw) scale(0.94); } .skills-demo .kb { padding-bottom: 5cqw; } /* -------------------------------------------------------------------------- * 10. 数字带 * -------------------------------------------------------------------------- */ .numbers-section { padding: clamp(64px, 8vw, 104px) 0; } .numbers-grid { display: grid; gap: 28px; grid-template-columns: repeat(4, 1fr); } .number { position: relative; padding-top: 24px; } /* 顶部细线随进场从左向右「画」出 */ .number::before { position: absolute; top: 0; right: 0; left: 0; height: 1px; background: linear-gradient(90deg, var(--accent), var(--line-strong) 40%); content: ""; transform-origin: 0 50%; transition: transform 1.3s var(--ease-out) var(--d, 0s); } html.js .number:not(.is-visible)::before { transform: scaleX(0); } .number strong { display: block; margin-bottom: 12px; background: linear-gradient(180deg, var(--ink) 30%, color-mix(in srgb, var(--ink) 50%, var(--accent))); -webkit-background-clip: text; background-clip: text; color: transparent; font-size: clamp(2.4rem, 4.8vw, 3.7rem); font-variant-numeric: tabular-nums; font-weight: 700; letter-spacing: -0.045em; line-height: 1; } .number span { display: block; max-width: 24ch; color: var(--ink-2); font-size: 0.94rem; } /* -------------------------------------------------------------------------- * 11. 功能区块细节 * -------------------------------------------------------------------------- */ .step-list { display: grid; gap: 20px; margin: 30px 0 0; padding: 0; list-style: none; } .step-list li { display: flex; align-items: flex-start; gap: 18px; } .step-index { padding-top: 2px; color: var(--accent); font-size: 0.82rem; font-variant-numeric: tabular-nums; font-weight: 700; letter-spacing: 0.04em; } .step-list h3 { margin-bottom: 4px; } .step-list p { margin: 0; color: var(--ink-2); font-size: 0.95rem; } .mini-feature { margin-top: 24px; } .mini-feature h3 { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; } .mini-feature h3 .i { width: 19px; height: 19px; color: var(--accent); } .mini-feature p { margin: 0; color: var(--ink-2); font-size: 0.97rem; } .skill-chips { display: flex; flex-wrap: wrap; gap: 9px; margin: 26px 0 4px; } .skill-chips > span { display: inline-flex; align-items: center; gap: 7px; padding: 8px 15px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); font-size: 0.88rem; font-weight: 550; transition: transform 0.5s var(--ease-spring), border-color 0.25s ease, color 0.25s ease; } .skill-chips > span:hover { border-color: color-mix(in srgb, var(--accent) 50%, transparent); color: var(--accent); transform: translateY(-3px); } .skill-chips .i { width: 15px; height: 15px; color: var(--accent); } /* 进场用 animation 而非 transition,避免进场延迟拖慢之后的悬停反馈 */ html.js .reveal:not(.is-visible) .skill-chips > span { opacity: 0; } html.js .reveal.is-visible .skill-chips > span { animation: chip-in 0.8s var(--ease-spring) both; animation-delay: calc(0.3s + var(--ci, 0) * 60ms); } @keyframes chip-in { from { opacity: 0; transform: translateY(12px) scale(0.85); } to { opacity: 1; transform: none; } } .quiet-list { display: grid; gap: 12px; margin: 24px 0 0; padding: 0; color: var(--ink-2); font-size: 0.95rem; list-style: none; } .quiet-list li { position: relative; padding-left: 26px; } .quiet-list li::before { position: absolute; top: 2px; left: 0; width: 16px; height: 16px; color: var(--accent); /* 内联 check 图标,避免外部字体依赖 */ content: ""; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / contain no-repeat; background: currentColor; } /* -------------------------------------------------------------------------- * 12. 嘴替输入法(2.1 卖点) * -------------------------------------------------------------------------- */ .personal-grid { display: grid; gap: 20px; grid-template-columns: repeat(3, 1fr); } .personal-card { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-xl); background: var(--surface); transition: transform 0.5s var(--ease-out), box-shadow 0.35s ease; } .personal-card:hover { box-shadow: var(--shadow-card); transform: translateY(-6px); } .personal-media { overflow: hidden; aspect-ratio: 4 / 3; background: var(--surface-strong); } .personal-media img, .personal-media video { width: 100%; height: 100%; object-fit: cover; object-position: top center; transition: transform 1.2s var(--ease-out); } .personal-card:hover .personal-media img, .personal-card:hover .personal-media video { transform: scale(1.04); } .personal-card h3 { margin: 22px 24px 8px; } .personal-card p { margin: 0; padding: 0 24px 26px; color: var(--ink-2); font-size: 0.94rem; } /* -------------------------------------------------------------------------- * 13. 隐私:三种服务路径(深色舞台) * -------------------------------------------------------------------------- */ .privacy-section { --spot-color: var(--stage-accent); background: linear-gradient(180deg, var(--stage-2), var(--stage-3)); color: var(--stage-ink); } .center-heading.inverse p:not(.eyebrow) { color: var(--stage-ink-2); } .privacy-section .eyebrow { color: var(--stage-accent); } /* 端侧徽记:声波在设备轮廓内跳动,轨道粒子绕行但从不越界 */ .device-emblem { position: relative; width: 124px; height: 124px; margin: 0 auto 26px; } .device-emblem::before { position: absolute; inset: -20%; border-radius: 50%; background: radial-gradient(closest-side, rgba(111, 196, 145, 0.28), transparent); content: ""; animation: breathe 4s ease-in-out infinite; } @keyframes breathe { 50% { opacity: 0.45; transform: scale(0.9); } } .device-emblem svg { position: relative; width: 100%; height: 100%; overflow: visible; } .emblem-orbit { fill: none; stroke: rgba(111, 196, 145, 0.4); stroke-dasharray: 2 6; stroke-width: 1; } .emblem-spin { fill: var(--stage-accent); transform-origin: 80px 80px; animation: spin 10s linear infinite; } .emblem-spin-rev { opacity: 0.6; animation-direction: reverse; animation-duration: 15s; } @keyframes spin { to { transform: rotate(360deg); } } .emblem-device { fill: rgba(255, 255, 255, 0.04); stroke: rgba(255, 255, 255, 0.42); stroke-width: 1.5; } .emblem-wave rect { fill: var(--stage-accent); transform-box: fill-box; transform-origin: center; animation: eq 1.3s ease-in-out infinite; } .emblem-wave rect:nth-child(2) { animation-delay: -0.2s; } .emblem-wave rect:nth-child(3) { animation-delay: -0.45s; } .emblem-wave rect:nth-child(4) { animation-delay: -0.7s; } .emblem-wave rect:nth-child(5) { animation-delay: -0.95s; } @keyframes eq { 0%, 100% { transform: scaleY(0.45); } 50% { transform: scaleY(1); } } .service-paths { display: grid; align-items: stretch; gap: 18px; grid-template-columns: 1.25fr 1fr 1fr; } .service-paths article { position: relative; padding: 30px 28px 26px; border: 1px solid var(--stage-line); border-radius: var(--radius-xl); background: rgba(255, 255, 255, 0.045); } .service-paths .path-primary { border-color: rgba(111, 196, 145, 0.35); background: rgba(111, 196, 145, 0.08); } .path-badge { position: absolute; top: 22px; right: 24px; padding: 4px 11px; border-radius: 999px; background: var(--stage-accent); color: #0c0e12; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em; } .path-icon { width: 26px; height: 26px; margin-bottom: 18px; color: var(--stage-accent); } .service-paths h3 { margin-bottom: 10px; font-size: 1.25rem; } .service-paths p { color: var(--stage-ink-2); font-size: 0.95rem; } .path-note { display: block; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--stage-line); color: var(--stage-ink-2); font-size: 0.82rem; letter-spacing: 0.01em; } .privacy-proof { display: flex; align-items: center; justify-content: space-between; gap: 32px; margin-top: 22px; padding: 26px 30px; border: 1px solid var(--stage-line); border-radius: var(--radius-xl); background: rgba(255, 255, 255, 0.045); } .privacy-proof > div { display: flex; align-items: center; gap: 16px; } .privacy-proof .i { width: 26px; height: 26px; flex: none; color: var(--stage-accent); } .privacy-proof h3 { margin: 0; font-size: 1.02rem; font-weight: 600; letter-spacing: 0; } .inverse-link { display: inline-flex; flex: none; align-items: center; gap: 7px; color: var(--stage-ink); font-size: 0.92rem; font-weight: 600; text-decoration: underline; text-decoration-color: var(--stage-line); text-underline-offset: 5px; transition: text-decoration-color 0.2s ease; } .inverse-link:hover { text-decoration-color: var(--stage-ink); } .inverse-link .i { width: 15px; height: 15px; transition: transform 0.5s var(--ease-spring); } .inverse-link:hover .i { transform: translate(3px, -3px); } /* -------------------------------------------------------------------------- * 14. 平台 * -------------------------------------------------------------------------- */ .platform-grid { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; } .platform-card { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-xl); background: var(--surface); transition: box-shadow 0.35s ease; } .platform-card:hover { box-shadow: var(--shadow-card); } .platform-card .media-frame { margin: 14px 14px 0; aspect-ratio: 4 / 3; border-radius: var(--radius-md); box-shadow: none; } .platform-card .media-frame img { width: 100%; height: 100%; object-fit: cover; object-position: top center; transition: transform 1.4s var(--ease-out); } .platform-card:hover .media-frame img { transform: scale(1.035); } .platform-label { display: block; margin: 24px 28px 8px; color: var(--accent); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.07em; } .platform-card h3 { margin: 0 28px 10px; } .platform-card > p { margin: 0; padding: 0 28px 30px; color: var(--ink-2); font-size: 0.95rem; } .platform-footnote { max-width: 720px; margin: 28px auto 0; color: var(--ink-3); font-size: 0.88rem; text-align: center; } /* -------------------------------------------------------------------------- * 15. 稳定性信任条 * -------------------------------------------------------------------------- */ .reliability-section { padding: clamp(48px, 6vw, 72px) 0; } .reliability-strip { display: flex; align-items: center; justify-content: space-between; gap: 20px 40px; padding: 26px 32px; border: 1px solid var(--line); border-radius: var(--radius-xl); background: var(--surface); } .strip-title { flex: none; font-size: 0.95rem; font-weight: 650; } .reliability-strip ul { display: flex; flex-wrap: wrap; gap: 8px 26px; margin: 0; padding: 0; color: var(--ink-2); font-size: 0.88rem; list-style: none; } .reliability-strip li { display: inline-flex; align-items: center; gap: 8px; } .reliability-strip li::before { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); content: ""; } /* -------------------------------------------------------------------------- * 16. FAQ(展开高度由 site.js 用 Web Animations 过渡) * -------------------------------------------------------------------------- */ .faq-layout { display: grid; align-items: start; gap: clamp(40px, 6vw, 80px); grid-template-columns: 1fr 1.4fr; } .faq-heading { position: sticky; top: 100px; } .faq-item { overflow: hidden; border-top: 1px solid var(--line); } .faq-item:last-child { border-bottom: 1px solid var(--line); } .faq-item summary { position: relative; padding: 20px 40px 20px 0; cursor: pointer; font-size: 1.02rem; font-weight: 600; letter-spacing: -0.005em; list-style: none; transition: color 0.2s ease; } .faq-item summary::-webkit-details-marker { display: none; } .faq-item summary::after { position: absolute; top: 22px; right: 4px; width: 18px; height: 18px; color: var(--ink-3); content: ""; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9.5l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9.5l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat; background: currentColor; transition: transform 0.5s var(--ease-spring); } .faq-item[open] summary::after { transform: rotate(180deg); } .faq-item summary:hover { color: var(--accent); } .faq-item p { margin: 0; padding: 0 32px 22px 0; color: var(--ink-2); font-size: 0.95rem; } .faq-item[open] p { animation: faq-in 0.5s var(--ease-out); } @keyframes faq-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } } /* -------------------------------------------------------------------------- * 17. 下载 CTA(深色舞台,与 Hero 呼应) * -------------------------------------------------------------------------- */ .download-section { padding-top: 0; } .faq-section + .download-section { padding-top: clamp(72px, 9vw, 120px); } .download-panel { position: relative; display: flex; overflow: hidden; align-items: center; justify-content: space-between; gap: 40px; padding: clamp(40px, 6vw, 80px); border-radius: calc(var(--radius-xl) + 4px); isolation: isolate; background: radial-gradient(110% 130% at 90% 120%, rgba(111, 196, 145, 0.16), transparent 55%), linear-gradient(160deg, var(--stage-1), var(--stage-3)); color: var(--stage-ink); } .download-backdrop { position: absolute; z-index: -1; inset: 0; pointer-events: none; } .download-backdrop .aurora-a { top: -60%; left: -12%; width: 520px; height: 520px; } .download-backdrop .aurora-b { top: auto; right: -14%; bottom: -70%; width: 520px; height: 520px; } /* 声波路径:虚线沿曲线流动,两条反向错速 */ .download-wave { position: absolute; right: 0; bottom: 0; left: 0; width: 100%; height: 55%; opacity: 0.45; } .download-wave path { fill: none; stroke: var(--stage-accent); stroke-dasharray: 6 12; stroke-width: 1.5; vector-effect: non-scaling-stroke; animation: dash-flow 5s linear infinite; } .download-wave path:nth-child(2) { opacity: 0.5; animation-direction: reverse; animation-duration: 8s; } @keyframes dash-flow { to { stroke-dashoffset: -180; } } .download-copy h2 { margin-bottom: 12px; font-size: clamp(2rem, 4.2vw, 3.1rem); } .download-copy p { max-width: 460px; margin: 0; color: var(--stage-ink-2); } .download-panel .eyebrow { color: var(--stage-accent); } .download-actions { display: flex; flex: none; flex-direction: column; align-items: stretch; gap: 14px; } .outline-action { display: inline-flex; align-items: center; justify-content: center; gap: 9px; padding: 13px 22px; border: 1px solid var(--stage-line); border-radius: 999px; color: var(--stage-ink); font-size: 0.92rem; font-weight: 600; transition: background 0.25s ease, border-color 0.25s ease, transform 0.5s var(--ease-spring); } .outline-action:hover { border-color: rgba(111, 196, 145, 0.45); background: rgba(255, 255, 255, 0.08); } .outline-action .i { width: 16px; height: 16px; } /* -------------------------------------------------------------------------- * 18. 页脚 * -------------------------------------------------------------------------- */ .site-footer { padding: 44px 0 52px; } .footer-inner { display: flex; width: var(--content); align-items: center; justify-content: space-between; gap: 20px; margin: 0 auto; color: var(--ink-3); font-size: 0.86rem; } .footer-links { display: flex; gap: 26px; } .footer-links a { transition: color 0.2s ease; } .footer-links a:hover { color: var(--ink); } /* -------------------------------------------------------------------------- * 19. 动效系统:滚动显现 / 遮罩揭示 / 光斑 / 倾斜 / 磁吸 / 主题过渡 * -------------------------------------------------------------------------- */ /* * 进场只动 opacity + translate(独立属性),把 transform 留给悬停倾斜与视差, * 两套动效互不覆盖。进场延迟只作用在进场属性上,悬停反馈始终即时。 */ html.js .reveal { opacity: 0; translate: 0 30px; transition-delay: var(--d, 0s), var(--d, 0s), 0s, 0s, 0s, var(--d, 0s); transition-duration: 0.9s, 1.05s, 0.5s, 0.35s, 0.35s, 1.25s; transition-property: opacity, translate, transform, box-shadow, border-color, clip-path; transition-timing-function: ease-out, var(--ease-out), var(--ease-out), ease, ease, var(--ease-out); } html.js .reveal.is-visible { opacity: 1; translate: 0 0; } /* 视差元素的 transform 每帧由脚本写入,不再叠加过渡 */ html.js .reveal[data-parallax] { transition-duration: 0.9s, 1.05s, 0s, 0.35s, 0.35s, 1.25s; } /* 遮罩揭示:媒体框从内缩的圆角矩形展开,内部画面同时从 112% 回落 */ html.js .unmask.reveal { clip-path: inset(9% 7% 9% 7% round var(--radius-lg)); } html.js .unmask.reveal.is-visible { clip-path: inset(0 0 0 0 round var(--radius-lg)); } html.js .unmask > video, html.js .unmask > img { transform: scale(1.12); transition: transform 1.6s var(--ease-out) var(--d, 0s); } html.js .unmask.is-visible > video, html.js .unmask.is-visible > img { transform: none; } /* 指针光斑:卡片内部高光 + 边框描光,--mx / --my 由脚本写入 */ .spot { position: relative; isolation: isolate; } .spot::before, .spot::after { position: absolute; inset: 0; border-radius: inherit; content: ""; opacity: 0; pointer-events: none; transition: opacity 0.4s ease; } .spot::before { z-index: -1; background: radial-gradient( 420px circle at var(--mx, 50%) var(--my, 50%), color-mix(in srgb, var(--spot-color, var(--accent)) 13%, transparent), transparent 46% ); } .spot::after { z-index: 2; padding: 1px; background: radial-gradient( 260px circle at var(--mx, 50%) var(--my, 50%), color-mix(in srgb, var(--spot-color, var(--accent)) 70%, transparent), transparent 62% ); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); } .spot:hover::before, .spot:hover::after { opacity: 1; } /* 3D 倾斜:--rx / --ry 由脚本根据指针位置写入 */ .tilt { transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--lift, 0px)); transform-style: preserve-3d; } .tilt:hover { --lift: -5px; } /* 主题切换:View Transitions 以按钮为圆心扩散(site.js 驱动 clip-path) */ html.vt-theme::view-transition-old(root), html.vt-theme::view-transition-new(root) { animation: none; mix-blend-mode: normal; } html.vt-theme::view-transition-new(root) { z-index: 1; } /* -------------------------------------------------------------------------- * 20. 减弱动态效果:所有持续动画停止,内容以最终态直接呈现 * -------------------------------------------------------------------------- */ @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; } html.js .reveal, html.js .hero-in { opacity: 1; translate: none; filter: none; } html.js .unmask.reveal { clip-path: none; } html.js .unmask > video, html.js .unmask > img { transform: none; } html.js .reveal [data-split] .ch { opacity: 1; filter: none; transform: none; } .hero-inner, .hero-devices { opacity: 1; transform: none; } .marquee-track { width: auto; flex-wrap: wrap; justify-content: center; } .marquee ul[aria-hidden="true"] { display: none; } .marquee ul { flex-wrap: wrap; justify-content: center; } .tilt { transform: none; } } /* -------------------------------------------------------------------------- * 21. 响应式 * -------------------------------------------------------------------------- */ @media (max-width: 960px) { .nav-links { display: none; } .mobile-menu-button { display: inline-grid; } .mobile-nav { display: block; padding: 8px 24px 18px; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--canvas) 88%, transparent); -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6); color: var(--ink); } .mobile-nav[hidden] { display: none; } .mobile-nav a { display: block; padding: 12px 8px; border-radius: 10px; font-size: 1rem; } .split-layout, .faq-layout { grid-template-columns: 1fr; } .faq-heading { position: static; } .split-layout.reverse .feature-copy { order: 1; } .split-layout.reverse .media-frame { order: 2; } .ways-grid, .numbers-grid { grid-template-columns: 1fr 1fr; } .personal-grid { grid-template-columns: 1fr; } .service-paths { grid-template-columns: 1fr; } .platform-grid { grid-template-columns: 1fr; } .download-panel { flex-direction: column; align-items: flex-start; } .download-actions { align-items: flex-start; } .reliability-strip { flex-direction: column; align-items: flex-start; } /* 滚动叙事:手机在上,当前一幕的文案在下方叠放切换 */ .story { height: 400vh; } .story-layout { align-content: center; gap: 22px; grid-template-columns: 1fr; justify-items: center; } .story-device { order: -1; } .phone { --w: min(290px, calc((100svh - 360px) * 0.468)); } .story-acts { position: relative; display: block; width: 100%; max-width: 520px; height: 196px; } .story-act { position: absolute; inset: 0; padding: 16px 20px; opacity: 0; pointer-events: none; transform: translateY(14px); } .story-act.is-active { opacity: 1; pointer-events: auto; transform: none; } .act-body > p:not(.act-kicker) { font-size: 0.92rem; } .scroll-cue { display: none; } } @media (max-width: 600px) { :root { --content: calc(100vw - 40px); } .hero { padding-top: 116px; } .ways-grid { grid-template-columns: 1fr; } .hero-actions { gap: 14px; } .voice-capsule { bottom: 12%; gap: 10px; padding: 6px 14px 6px 6px; } .capsule-mic { width: 62px; height: 28px; } .capsule-body { min-width: min(260px, 70vw); font-size: 0.84rem; } .privacy-proof { flex-direction: column; align-items: flex-start; } .footer-inner { flex-direction: column; align-items: flex-start; } } /* 无 JavaScript:滚动叙事退化为静态展示,不保留 430vh 的空白滚动距离 */ html.no-js .story { height: auto; } html.no-js .story-sticky { position: static; height: auto; padding: 48px 0 0; } html.no-js .story-act { position: static; opacity: 1; transform: none; } html.no-js .story-acts { height: auto; }