Files
OSGKeyboard/docs/assets/site.css
T
Rocky a9bf57ccf7 docs(pages): use real iPhone bezel and on-device keyboard recordings
Replace the HTML-drawn phone and keyboard mockups with Apple's iPhone 17 Pro
bezel and simulator recordings of the real keyboard extension (zh/en, light/dark).
Halve the marquee type and drop the credits image from the account section.
2026-10-01 13:23:57 +08:00

2643 lines
56 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*!
* 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 图标库容器:不可见但可被 <use> 引用 */
.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;
}