/* ============================================================================
 * base.css · 复位 / 视口 / 安全区 / 屏状态机 / 通用按钮
 * ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* ---------------------------------------------------------------------------
 * 字体：OPPO Sans 3.0 子集（Regular / Medium / Bold）
 * Penpot 侧用的是同一个 fontId，所以设计稿里的 400 / 500 与这里一一对应。
 * weight 用区间声明（500-600 / 700-900），避免浏览器给 500 的字重合成加粗。
 * ------------------------------------------------------------------------- */
@font-face {
  font-family: "OPPOSans";
  src: url("../fonts/OPPOSans-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}@font-face {
  font-family: "OPPOSans";
  src: url("../fonts/OPPOSans-Medium.woff2") format("woff2");
  font-weight: 500 600;
  font-display: swap;
}
@font-face {
  font-family: "OPPOSans";
  src: url("../fonts/OPPOSans-Bold.woff2") format("woff2");
  font-weight: 700 900;
  font-display: swap;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  background: #eef2fa;
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
input { font: inherit; color: inherit; }
img, svg, video, canvas { display: block; max-width: 100%; }

/* ★ `hidden` 必须真的隐藏。
   `img { display: block }` 是**作者样式**，优先级高于浏览器 UA 的
   `[hidden] { display: none }` —— 于是所有带 hidden 的 <img> 其实都在显示：
     · P3 那个还没有 src 的预览图 → 渲染成一张 **broken image**（用户报的「选照片后出现坏图」）
     · P4 的静帧兜底图 → 一直**盖在视频上面**（视频在播，但看到的是一张静止图）
   这一行是这类问题的标准修法。 */
[hidden] { display: none !important; }

/* 全站图片一律按 EXIF 方向渲染。现代浏览器默认就是它，这里显式钉死是为了
   「手机竖拍照片上传后转了 90°」这类问题不因默认值变化而复现。 */
img { image-orientation: from-image; }

/* 标题类元素的浏览器默认 margin 必须清掉。
   ★ 这一条是量出来的：`.up-sub` 实测比设计低 **18.09px**，正好是 h1 的
     默认 margin-block-end `0.67em × 27px = 18.09px` —— 只 reset `p` 是不够的。 */
h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }

/* ---------------------------------------------------------------------------
 * 舞台（H5 Design Stage）
 *
 * 坐标系就是 Penpot 的正式移动端画板 **390 × 844.5**（--stage-w / --stage-h）。
 * 屏内所有元素都用**设计稿的绝对坐标**摆放，不再逐个元素写弹性留白或 media query。
 * 装不下时只做一件事：把整个舞台等比缩小（--stage-k，由 layout.js 算）。
 *
 * 两层结构的理由：
 *   .stage        布局盒 = **缩放后**的尺寸（宽高都乘 k）
 *   .stage__inner 设计尺寸 390×844.5，transform: scale(k)
 * 这样布局盒和视觉盒永远一致 —— 不会出现「子元素比屏幕大」导致的溢出、
 * 也不会出现「overflow:hidden 把投影切掉」这类连锁问题。
 *
 * 底部/顶部的安全区在 .screen 上一次性留出（padding），
 * 于是「刘海不压内容、Home Indicator 不压按钮」对五个屏同时成立。
 * ------------------------------------------------------------------------- */
.app {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  margin: 0 auto;
  overflow: hidden;
  isolation: isolate;

  /* 设计画板 */
  --stage-w: 390;
  --stage-h: 844.5;
  /* 由 layout.js 写：min(可用宽/--stage-w, 可用高/--stage-h)
     ★ 只给**桌面 9:16 手机框**用。手机端不再整体等比缩放。 */
  --stage-k: 1;

  /* ── 短屏重分配系统（C02 short viewport）──────────────────────────────
     手机端不再「整页等比缩小」，而是按可用高度**重分配垂直空间**：
       1) 先压掉无效间隙 / 过大的 gap         → --gap-scale
       2) 间隙压到底还不够，才适度缩主视觉      → --visual-k
       3) 文字与按钮**完全不参与**这两个缩放（保持可读 / 可点）
     --usable-h 由 layout.js 用 100dvh + visualViewport 同步写入。 */
  --usable-h: 100dvh;
  --gap-scale: 1;
  --visual-k: 1;

  /* 手机端：设计里的 `h5背景` 直接**整屏铺**（cover），内容舞台叠在上面。
     这样屏幕比例接近 9:16 时整张背景图完整可见、没有任何接缝；
     而在 390×844.5 设计口径下，cover 会把两侧各裁 42.5px —— 与设计稿一致。 */
  background-image: url("../img/bg-app.webp");
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  background-color: #e8eef9;
}

/* PC / 宽屏：背景换成「桌面」（用设计 app-bg-gradient 的色标），
   手机舞台自己带设计背景 —— 于是舞台边界是**有意为之**的手机轮廓。
   这是全站唯一的一处 media query，切的是「手机模式 / 桌面模式」，不是逐元素补丁。 */
@media (min-width: 700px) {
  .app {
    background-image: none;
    background: linear-gradient(180deg, #f7f9fe 0%, #e8eef9 46%, #d9e3f6 100%);
  }
  /* PC 上背景图与投影都交给**风层**（.wind）去画 —— 见 wind.css 的同名媒体查询。
     这里保持透明，风墨迹才有地方显现；内容仍然在风层之上。 */
  .stage__inner {
    background-image: none;
    box-shadow: none;
  }

  /* ---- 可选：严格 9:16 手机框（?pcFrame=916）---------------------------------
     默认的 PC 舞台取**设计画板比例** 390:844.5（≈9:19.5）—— 既不裁也不拉伸，
     内容正好铺满。要求里点名的是 9:16，而画板比 9:16 更竖长：
     若把内容塞进严格 9:16 的框、还要「不裁不拉伸」，就必然空出两侧约 18% 的边。
     这个开关就是那种模式：外框 9:16，设计画板在其中水平居中，两侧用同一张
     背景图铺满（无缝）。两种模式都不裁、不拉伸，区别只是「要不要那圈边」。 */
  .app[data-pc-frame="916"] .stage {
    display: grid;
    place-items: center;
    width: calc(var(--stage-h) * var(--stage-k) * 9 / 16 * 1px);
    height: calc(var(--stage-h) * var(--stage-k) * 1px);
    background-image: url("../img/bg-app.webp");
    background-size: cover;
    background-position: center top;
    background-repeat: no-repeat;
    box-shadow: 0 24px 70px rgba(24, 40, 80, 0.16);
  }
  .app[data-pc-frame="916"] .stage__inner {
    position: relative;
    left: auto;
    top: auto;
    transform: scale(var(--stage-k));
    transform-origin: center center;
    background-image: none;
    box-shadow: none;
  }
}

.screen {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: start center;   /* 手机：舞台自己撑满，不需要再居中 */
  /* 安全区只在这里留一次；舞台整体落在安全区内 */
  padding-top: var(--safe-top);
  padding-bottom: var(--safe-bottom);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--t-screen) var(--ease-out), visibility 0s linear var(--t-screen);
}
.screen[data-active] {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--t-screen) var(--ease-out), visibility 0s;
}

/* 手机：舞台 = 满宽（最多 390）× 真实可用高。**不缩放**。 */
.stage {
  position: relative;
  flex: 0 0 auto;
  width: min(calc(var(--stage-w) * 1px), 100%);
  height: 100%;
  /* 不要 overflow:hidden —— P5 海报的投影要溢到舞台外 */
}
/* 舞台内部是一个纵向弹性列：DOM 顺序 = 视觉顺序（五个屏都成立）。
   顶部区、主视觉、底部区依次排布；
   底部区用 margin-top:auto 顶到下方，中间空间自动让给主视觉。 */
.stage__inner {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 桌面 / 宽屏：仍然是「居中的 9:16 手机框」，内部按设计画板等比缩放。
   短屏那套 CSS 变量在桌面一律为 1，互不干扰。 */
@media (min-width: 700px) {
  .stage {
    width: calc(var(--stage-w) * var(--stage-k) * 1px);
    height: calc(var(--stage-h) * var(--stage-k) * 1px);
  }
  .stage__inner {
    position: absolute;
    top: 0;
    left: 0;
    width: calc(var(--stage-w) * 1px);
    height: calc(var(--stage-h) * 1px);
    transform: scale(var(--stage-k));
    transform-origin: top left;
    display: block;          /* 桌面沿用设计稿的绝对坐标 */
  }
}


/* 屏内元素的统一入场：`.rise` 在自己所在的屏激活后逐个浮上来 */
.rise {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
  transition-delay: var(--rise-delay, 0ms);
}
.screen[data-active] .rise { opacity: 1; transform: none; }

/* ---------------------------------------------------------------------------
 * 通用：顶栏（返回 / 回到主页）
 * ------------------------------------------------------------------------- */
/* 顶栏：设计 (22,28)，高 34 —— 绝对定位在舞台坐标系里 */
.topbar {
  position: absolute;
  left: 22px;
  top: 28px;
  height: 34px;
  z-index: 3;
  display: flex;
  align-items: center;
}

.pill {
  display: inline-flex;
  align-items: center;
  height: 34px;
  border: 1px solid var(--ink);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  transition: transform 0.18s var(--ease-out), background-color 0.18s var(--ease-out);
}
.pill:active { transform: scale(0.96); background: rgba(255, 255, 255, 0.5); }
.pill__icon { flex: 0 0 auto; }
.pill__text {
  font-size: var(--fs-pill);
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
}

/* 返回：设计 pill 69.92×34 @(22,28)；雪佛龙中心线盒 (39.375,40.625) 4.375×8.75、描边 1.6。
   ★ icon-back.svg 的导出尺寸是 **12.375×16.75**（viewBox 从 -4,-4 起，Penpot 为描边留了白），
     所以盒子左上角 = (39.375-4, 40.625-4) = (35.375,36.625) → pill 内 (13.375, 8.625)。
     上一版按 4.375×8.75 渲染，箭头只剩应有的 35%（用户看到的「箭头过小」）。
     pill 内 flex 垂直居中正好给出 8.625 = (34-16.75)/2 ✓ */
/* ★ padding 要减掉 1px 边框（box-sizing: border-box，内容从边框内侧起算），
   否则图标整体右移 1px —— 实测 14.375 而非 13.375 */
.pill--back { padding: 0 15px 0 12.375px; gap: 4.25px; }
.pill--back .pill__icon { width: 12.375px; height: 16.75px; }

/* 回到主页：设计 95×34，图标 9.625×9.975 @ 左 15.188，文字顶左 32 */
.pill--home { padding: 0 13px 0 14.188px; gap: 7.187px; }   /* 同样减 1px 边框 */
.pill--home .pill__icon { width: 9.625px; height: 9.975px; }

/* OnePlus 组合标：设计 101×24，居中 */
.brand {
  flex: 0 0 auto;
  width: 101px;
  height: 24px;
}
.brand img { width: 100%; height: 100%; }

/* ---------------------------------------------------------------------------
 * 通用：CTA
 * 设计：竖向渐变 #9cbdfa → #032a8e，圆角 4，投影 0 22 46 / .36
 * ------------------------------------------------------------------------- */
.cta {
  /* 统一按钮规范：文字必须视觉居中、禁止换行（需求 §七） */
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  flex: 0 0 auto;
  height: var(--btn-h);
  border-radius: var(--btn-radius);
  background: linear-gradient(180deg, var(--brand-hi) 0%, var(--brand-ink) 100%);
  box-shadow: var(--sh-cta);
  color: var(--ink-invert);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  line-height: var(--btn-lh);
  letter-spacing: var(--btn-ls);
  text-align: center;
  transition: transform 0.16s var(--ease-out), opacity 0.2s linear, box-shadow 0.2s linear;
}
/* ── CTA 文字「视觉居中」校正（全项目唯一一处，集中定义）─────────────────
 *
 * 问题：全角收尾标点（」』）的字形把墨迹放在 em 盒**左半**，右半是约 0.74em 的空白。
 *       `justify-content: center` 居中的是**布局盒**，于是墨迹整体偏左。
 *       实测 P2「锁定手持「性能直升机」」：布局盒 175.66 / 墨迹 163.87 / 墨迹中心偏左 5.60px。
 *
 * 依据：这不是空格问题 —— 前端 textContent 与 Penpot 原始文字图层**都没有末尾空格**
 *       （Penpot 该图层 last=U+300D，len=11，无任何空白字符）。
 *       设计稿里设计师也是把文字图层右移来补偿的：文字盒中心 716 vs 按钮中心 709.5。
 *
 * 做法：只对**确实以全角收尾标点结尾**的按钮，从行内末端扣掉这份字形留白。
 *       用属性显式声明，不写死到某个 id，也不逐页随手偏移。
 *
 * ★ 若将来 text-spacing-trim: trim-both 得到广泛支持（Chrome 123+ / Safari 18.2+），
 *   可把下面两条换成一条 `text-spacing-trim: trim-both` 并删掉本属性。
 *   （实测当前测试浏览器 CSS.supports('text-spacing-trim','trim-both') === false，故暂不依赖。）
 * ------------------------------------------------------------------------- */
.cta[data-opt-center] {
  /* 左侧补 0.74em、右侧不补 → 内容整体右移 0.37em（16px 字号 ≈ 5.9px），正好抵消字形留白 */
  padding-left: 0.74em;
  padding-right: 0;
}

.cta:active:not([disabled]) { transform: scale(0.975); }

.cta[disabled],
.cta[aria-disabled="true"] {
  background: var(--disabled-bg);
  box-shadow: none;
  color: var(--disabled-ink);
  cursor: default;
}

/* ---------------------------------------------------------------------------
 * 通用：toast
 * ------------------------------------------------------------------------- */
.toast {
  position: absolute;
  left: 50%;
  bottom: calc(18px + var(--safe-bottom));
  transform: translate(-50%, 8px);
  z-index: 40;
  max-width: min(86%, 340px);
  padding: 9px 16px;
  border-radius: 18px;
  background: rgba(8, 14, 32, 0.86);
  color: #fff;
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.24s var(--ease-out), transform 0.24s var(--ease-out), visibility 0s linear 0.24s;
}
.toast[data-show] {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity 0.24s var(--ease-out), transform 0.24s var(--ease-out), visibility 0s;
}

/* ---------------------------------------------------------------------------
 * 可访问性
 * ------------------------------------------------------------------------- */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
 * iOS / Android 软键盘弹出时的滚动许可
 *
 * 背景：键盘弹出时 visualViewport 高度骤降。layout.js 已**冻结布局**
 * （不再重算 --usable-h / 缩放变量），所以卡片内元素相对关系不变、不会重叠。
 * 但页面默认 `overflow: hidden`，iOS 就没法把聚焦的输入框滚进可视区。
 * 这里只在键盘期间解除这条限制：文档高度 = 冻结的 --usable-h，
 * 于是页面可以正常上下滚动，输入框始终滚得到；键盘收起后属性移除，一切复原。
 *
 * ★ 不做整体缩小、不改任何元素尺寸，未弹键盘时的 Penpot 版面完全不受影响。
 * ═══════════════════════════════════════════════════════════════════════════ */
html[data-keyboard],
html[data-keyboard] body {
  height: auto;
  min-height: 100%;
  overflow: visible;
}
html[data-keyboard] .app {
  height: var(--usable-h);
  min-height: var(--usable-h);
}


}

.screen {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: start center;   /* 手机：舞台自己撑满，不需要再居中 */
  /* 安全区只在这里留一次；舞台整体落在安全区内 */
  padding-top: var(--safe-top);
  padding-bottom: var(--safe-bottom);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--t-screen) var(--ease-out), visibility 0s linear var(--t-screen);
}
.screen[data-active] {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--t-screen) var(--ease-out), visibility 0s;
}

/* 手机：舞台 = 满宽（最多 390）× 真实可用高。**不缩放**。 */
.stage {
  position: relative;
  flex: 0 0 auto;
  width: min(calc(var(--stage-w) * 1px), 100%);
  height: 100%;
  /* 不要 overflow:hidden —— P5 海报的投影要溢到舞台外 */
}
/* 舞台内部是一个纵向弹性列：DOM 顺序 = 视觉顺序（五个屏都成立）。
   顶部区、主视觉、底部区依次排布；
   底部区用 margin-top:auto 顶到下方，中间空间自动让给主视觉。 */
.stage__inner {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 桌面 / 宽屏：仍然是「居中的 9:16 手机框」，内部按设计画板等比缩放。
   短屏那套 CSS 变量在桌面一律为 1，互不干扰。 */
@media (min-width: 700px) {
  .stage {
    width: calc(var(--stage-w) * var(--stage-k) * 1px);
    height: calc(var(--stage-h) * var(--stage-k) * 1px);
  }
  .stage__inner {
    position: absolute;
    top: 0;
    left: 0;
    width: calc(var(--stage-w) * 1px);
    height: calc(var(--stage-h) * 1px);
    transform: scale(var(--stage-k));
    transform-origin: top left;
    display: block;          /* 桌面沿用设计稿的绝对坐标 */
  }
}


/* 屏内元素的统一入场：`.rise` 在自己所在的屏激活后逐个浮上来 */
.rise {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
  transition-delay: var(--rise-delay, 0ms);
}
.screen[data-active] .rise { opacity: 1; transform: none; }

/* ---------------------------------------------------------------------------
 * 通用：顶栏（返回 / 回到主页）
 * ------------------------------------------------------------------------- */
/* 顶栏：设计 (22,28)，高 34 —— 绝对定位在舞台坐标系里 */
.topbar {
  position: absolute;
  left: 22px;
  top: 28px;
  height: 34px;
  z-index: 3;
  display: flex;
  align-items: center;
}

.pill {
  display: inline-flex;
  align-items: center;
  height: 34px;
  border: 1px solid var(--ink);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  transition: transform 0.18s var(--ease-out), background-color 0.18s var(--ease-out);
}
.pill:active { transform: scale(0.96); background: rgba(255, 255, 255, 0.5); }
.pill__icon { flex: 0 0 auto; }
.pill__text {
  font-size: var(--fs-pill);
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
}

/* 返回：设计 pill 69.92×34 @(22,28)；雪佛龙中心线盒 (39.375,40.625) 4.375×8.75、描边 1.6。
   ★ icon-back.svg 的导出尺寸是 **12.375×16.75**（viewBox 从 -4,-4 起，Penpot 为描边留了白），
     所以盒子左上角 = (39.375-4, 40.625-4) = (35.375,36.625) → pill 内 (13.375, 8.625)。
     上一版按 4.375×8.75 渲染，箭头只剩应有的 35%（用户看到的「箭头过小」）。
     pill 内 flex 垂直居中正好给出 8.625 = (34-16.75)/2 ✓ */
/* ★ padding 要减掉 1px 边框（box-sizing: border-box，内容从边框内侧起算），
   否则图标整体右移 1px —— 实测 14.375 而非 13.375 */
.pill--back { padding: 0 15px 0 12.375px; gap: 4.25px; }
.pill--back .pill__icon { width: 12.375px; height: 16.75px; }

/* 回到主页：设计 95×34，图标 9.625×9.975 @ 左 15.188，文字顶左 32 */
.pill--home { padding: 0 13px 0 14.188px; gap: 7.187px; }   /* 同样减 1px 边框 */
.pill--home .pill__icon { width: 9.625px; height: 9.975px; }

/* OnePlus 组合标：设计 101×24，居中 */
.brand {
  flex: 0 0 auto;
  width: 101px;
  height: 24px;
}
.brand img { width: 100%; height: 100%; }

/* ---------------------------------------------------------------------------
 * 通用：CTA
 * 设计：竖向渐变 #9cbdfa → #032a8e，圆角 4，投影 0 22 46 / .36
 * ------------------------------------------------------------------------- */
.cta {
  /* 统一按钮规范：文字必须视觉居中、禁止换行（需求 §七） */
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  flex: 0 0 auto;
  height: var(--btn-h);
  border-radius: var(--btn-radius);
  background: linear-gradient(180deg, var(--brand-hi) 0%, var(--brand-ink) 100%);
  box-shadow: var(--sh-cta);
  color: var(--ink-invert);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  line-height: var(--btn-lh);
  letter-spacing: var(--btn-ls);
  text-align: center;
  transition: transform 0.16s var(--ease-out), opacity 0.2s linear, box-shadow 0.2s linear;
}
/* ── CTA 文字「视觉居中」校正（全项目唯一一处，集中定义）─────────────────
 *
 * 问题：全角收尾标点（」』）的字形把墨迹放在 em 盒**左半**，右半是约 0.74em 的空白。
 *       `justify-content: center` 居中的是**布局盒**，于是墨迹整体偏左。
 *       实测 P2「锁定手持「性能直升机」」：布局盒 175.66 / 墨迹 163.87 / 墨迹中心偏左 5.60px。
 *
 * 依据：这不是空格问题 —— 前端 textContent 与 Penpot 原始文字图层**都没有末尾空格**
 *       （Penpot 该图层 last=U+300D，len=11，无任何空白字符）。
 *       设计稿里设计师也是把文字图层右移来补偿的：文字盒中心 716 vs 按钮中心 709.5。
 *
 * 做法：只对**确实以全角收尾标点结尾**的按钮，从行内末端扣掉这份字形留白。
 *       用属性显式声明，不写死到某个 id，也不逐页随手偏移。
 *
 * ★ 若将来 text-spacing-trim: trim-both 得到广泛支持（Chrome 123+ / Safari 18.2+），
 *   可把下面两条换成一条 `text-spacing-trim: trim-both` 并删掉本属性。
 *   （实测当前测试浏览器 CSS.supports('text-spacing-trim','trim-both') === false，故暂不依赖。）
 * ------------------------------------------------------------------------- */
.cta[data-opt-center] {
  /* 左侧补 0.74em、右侧不补 → 内容整体右移 0.37em（16px 字号 ≈ 5.9px），正好抵消字形留白 */
  padding-left: 0.74em;
  padding-right: 0;
}

.cta:active:not([disabled]) { transform: scale(0.975); }

.cta[disabled],
.cta[aria-disabled="true"] {
  background: var(--disabled-bg);
  box-shadow: none;
  color: var(--disabled-ink);
  cursor: default;
}

/* ---------------------------------------------------------------------------
 * 通用：toast
 * ------------------------------------------------------------------------- */
.toast {
  position: absolute;
  left: 50%;
  bottom: calc(18px + var(--safe-bottom));
  transform: translate(-50%, 8px);
  z-index: 40;
  max-width: min(86%, 340px);
  padding: 9px 16px;
  border-radius: 18px;
  background: rgba(8, 14, 32, 0.86);
  color: #fff;
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.24s var(--ease-out), transform 0.24s var(--ease-out), visibility 0s linear 0.24s;
}
.toast[data-show] {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity 0.24s var(--ease-out), transform 0.24s var(--ease-out), visibility 0s;
}

/* ---------------------------------------------------------------------------
 * 可访问性
 * ------------------------------------------------------------------------- */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
 * iOS / Android 软键盘弹出时的滚动许可
 *
 * 背景：键盘弹出时 visualViewport 高度骤降。layout.js 已**冻结布局**
 * （不再重算 --usable-h / 缩放变量），所以卡片内元素相对关系不变、不会重叠。
 * 但页面默认 `overflow: hidden`，iOS 就没法把聚焦的输入框滚进可视区。
 * 这里只在键盘期间解除这条限制：文档高度 = 冻结的 --usable-h，
 * 于是页面可以正常上下滚动，输入框始终滚得到；键盘收起后属性移除，一切复原。
 *
 * ★ 不做整体缩小、不改任何元素尺寸，未弹键盘时的 Penpot 版面完全不受影响。
 * ═══════════════════════════════════════════════════════════════════════════ */
html[data-keyboard],
html[data-keyboard] body {
  height: auto;
  min-height: 100%;
  overflow: visible;
}
html[data-keyboard] .app {
  height: var(--usable-h);
  min-height: var(--usable-h);
}


/* 竖屏锁定（screen.orientation.lock + 横屏 rotate 90deg）已按要求**彻底移除**：
   它曾导致 iPhone 微信下页面主体消失；现在手机横屏走浏览器自然布局。 */



/* ═══════════════════════════════════════════════════════════════════════════
 * 背景按页面状态切换（<html data-bg="global|video|white">，由 main.js 设置）
 *
 *   global → P1/P2/P3：全局白蓝渐变背景 + 风线动画（保持原样）
 *   video  → P4：**只有全屏视频**，全局背景图与风线整层移出渲染树
 *   white  → P5：**只有纯白**
 *
 * ★ 用 `display: none` 而不是把风线透明度调 0 ——
 *   前者是「这个背景组件在当前页面**不参与渲染**」，后者只是看不见、仍在画。
 * ═══════════════════════════════════════════════════════════════════════════ */

/* 非 P1–P3：全局背景图与风线不渲染 */
html[data-bg="video"] .wind,
html[data-bg="white"] .wind { display: none; }

html[data-bg="video"] .app,
html[data-bg="white"] .app {
  background-image: none;
  background-color: transparent;
}

/* ★ 深色底 / 纯白底只作用在**手机端**：
   PC 上 .app 是整个浏览器窗口，若把 body/.app 刷成 #0d0f14，
   手机容器外侧会变成一大片黑（用户报的「PC 宽屏下背景大面积变黑」）。
   PC 的场景底色由它自己的规则管（舞台居中 + 中性底）。 */
@media (max-width: 699px) {
  html[data-bg="white"],
  html[data-bg="white"] body,
  html[data-bg="white"] .app { background: #ffffff; }

  html[data-bg="video"],
  html[data-bg="video"] body,
  html[data-bg="video"] .app { background: #0d0f14; }
}
