/*! * 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; /* 嵌入式手机演示的配色(随主题切换) */ /* 键盘复刻色:取自 App 源码 ColorLibrary(brandAccent / aiTeal / recordRed)与原生键面色 */ --kb-accent: #3aa05a; --kb-teal: #2bafa4; --kb-red: #ff3b30; } 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); } /* -------------------------------------------------------------------------- * 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: 12px 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: 16px; padding-right: 16px; color: var(--ink-3); font-size: clamp(0.6rem, 0.9vw, 0.72rem); font-weight: 650; letter-spacing: -0.01em; white-space: nowrap; } .marquee li:nth-child(-n + 3) { color: var(--ink); } .marquee li::after { width: 4px; height: 4px; 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; } /* 账号段落只保留文字,限制行宽保证可读性 */ .account-layout .feature-copy { max-width: 760px; } .split-layout.reverse .feature-copy { order: 2; } .split-layout.reverse .media-frame, .split-layout.reverse .device-stage { 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. 滚动叙事(三幕剧) * 滚动进度决定当前幕;手机里播放这一幕的真机录屏,幕内进度条跟随播放进度(--ap)。 * 无 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; transition: transform 0.3s linear; } /* 舞台:真机 + 背后呼吸光晕 */ .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); animation: device-glow 6s ease-in-out infinite; } @keyframes device-glow { 0%, 100% { opacity: 0.45; transform: scale(1); } 50% { opacity: 0.85; transform: scale(1.08); } } /* -------------------------------------------------------------------------- * 真机外框:Apple 官方 iPhone 17 Pro 机框图(原图 1350 × 2760)。 * 屏幕开口为 1206 × 2622、起点 (72, 69),换算成百分比后放置录屏; * 模拟器录屏正是这个分辨率,像素一一对应。机框自带灵动岛与圆角,叠在录屏之上。 * -------------------------------------------------------------------------- */ .iphone { --w: min(330px, calc((100svh - 150px) * 0.489)); position: relative; width: var(--w); aspect-ratio: 1350 / 2760; filter: drop-shadow(0 40px 48px rgba(8, 12, 16, 0.26)) drop-shadow(0 12px 16px rgba(8, 12, 16, 0.14)); } .iphone-screen { position: absolute; top: 2.5%; left: 5.333%; width: 89.333%; height: 95%; overflow: hidden; /* 开口圆角约 230px:230 / 1206 与 230 / 2622 */ border-radius: 19% / 8.8%; background: #000; } /* 同一屏幕里叠放多段录屏,当前一段淡入 */ .iphone-clip { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.5s var(--ease-out); } .iphone-clip.is-on { opacity: 1; } .iphone-bezel { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; user-select: none; } /* 分栏区块里的真机:与文案并排居中 */ .device-stage { display: grid; margin: 0; place-items: center; } .device-stage .iphone { --w: min(320px, 76vw); } /* -------------------------------------------------------------------------- * 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, .split-layout.reverse .device-stage { 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; } .iphone { --w: min(260px, calc((100svh - 360px) * 0.489)); } .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; }