/* 主布局 - 竖屏居中自适应 */

#app {
  width: 100%;
  height: 100%;
  max-width: 500px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

/* === 共享缩放容器 === */
/*
 * #app-scale-inner 同时包住「游戏视图」与「编辑器视图」。JS 根据窗口大小给它写 layout height 和
 * transform:scale，两个视图的外层占位始终完全一致：
 * - 整卡理论高度 hNeeded = wAvail × 16/9
 * - 宽屏（hAvail < hNeeded）：inner.height = hNeeded + transform:scale(hAvail/hNeeded)，整卡宽高一起等比例缩小
 * - 窄屏（hAvail > hNeeded）：inner.height = hNeeded，不 transform。inner 在 #app 顶部，下方空白即底边栏
 * - 恰好：inner.height = hNeeded = hAvail，无 transform
 * 因 inner 用 position:absolute，scale-down 时显式像素高度不会被 flex-shrink 拉回。
 */
#app > #app-scale-inner {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-left: 1px solid var(--border-color);
  border-right: 1px solid var(--border-color);
  /* 避免 JS 还没设 9:16 高度时闪一下原比例的满屏；JS 在首次 _syncViewGameUniformScale 后会移除 */
  visibility: hidden;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  transform-origin: top center;
  box-sizing: border-box;
  /*
   * 把 inner 定义为尺寸查询容器：子节点的 cqmin / cqb / cqi 单位跟随 inner 的 layout 尺寸变化，
   * 实现「字体和按钮高度跟随页面大小自动缩放」。
   * 用 container-type:size 需要元素有显式宽高 —— inner 100%/100% 已满足。
   */
  container-type: size;
  container-name: stage-card;
  /* 基础字体大小：用户设置的 --font-size 略放大作为整卡基准，子节点继承作为 1em 缩放基准 */
  font-size: calc(var(--font-size) * 1.375);
}

/* 两 view 始终 absolute 撑满 inner，不靠 flex 分配空间。
   active/hidden 只翻 visibility（见 base.css），让 view-editor 在没切到时也保持 layout/paint，
   避免首次切到编辑器时浏览器全量 layout + 新建合成层导致的 1 帧延迟闪烁。
   z-index 高于 #app-scale-inner 内魔药泡泡等绝对层；active 比 hidden 高一档避免堆叠歧义。 */
#app-scale-inner > #view-game,
#app-scale-inner > #view-editor {
  position: absolute;
  inset: 0;
  display: flex;
  min-height: 0;
  width: 100%;
  z-index: 3;
}
#app-scale-inner > #view-game.view-active,
#app-scale-inner > #view-editor.view-active {
  z-index: 4;
}

/* === 游戏视图内部 === */
#view-game {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  position: relative;
  box-sizing: border-box;
  /*
   * 按卡片（#app-scale-inner）尺寸百分比分配：
   *   顶栏：卡片 6% 高度
   *   点击继续 / 选项按钮行最小：卡片 7% 高度
   * 用 cqb（container query block size = 卡片自身高度）自动跟随卡片大小变化。
   */
  /* 顶栏高度随容器宽度等比缩放：12.8cqmin ≈ 500px 宽时 64px、375px 宽时 48px、300px 宽时 38px */
  --game-nav-h: clamp(28px, 12.8cqmin, 64px);
  --game-bottom-tap-min: clamp(28px, 5cqb, 44px);
  gap: clamp(2px, 0.4cqb, 5px);
  padding: clamp(1px, 0.3cqb, 4px) 0;
}

#view-game > .nav-bar,
#view-game > .tap-continue,
#view-game > .choice-area {
  width: 100%;
  max-width: 100%;
  align-self: stretch;
  flex-shrink: 0;
  box-sizing: border-box;
}

@media (min-aspect-ratio: 3/4) {
  #view-game.view-active {
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
    box-sizing: border-box;
  }
}

/* 顶部导航栏（四键）：高度随视口变化，避免纯 px 在大屏上过矮、小屏上过高 */
.nav-bar {
  display: flex;
  align-items: stretch;
  flex-shrink: 0;
  box-sizing: border-box;
  height: var(--game-nav-h);
  min-height: var(--game-nav-h);
  max-height: var(--game-nav-h);
  padding: 0;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-light);
}
.nav-bar .btn {
  flex: 1;
  align-self: stretch;
  min-height: 0;
  height: 100%;
  margin: 0 clamp(2px, 0.5cqmin, 6px);
  font-size: var(--font-size);
  padding: 0 clamp(6px, 1cqmin, 12px);
  box-sizing: border-box;
}
@media (max-width: 640px) {
  /*
   * base.css 在窄屏对 .btn 写了 min-height / padding 的 !important，
   * 顶栏按钮需撑满 --game-nav-h，否则会出现比编辑器顶栏按钮更矮的一条。
   */
  .nav-bar .btn {
    min-height: 0 !important;
    height: 100% !important;
    padding: 0 clamp(6px, 1cqmin, 12px) !important;
    font-size: var(--font-size) !important;
  }
}

/* 状态栏：纯粹的 flex 行，收起时 display:none 彻底消失，不留任何残余行。
   收起/展开只能通过 .status-bar-toggle 按钮，整条栏点击不响应（不设 cursor:pointer） */
.status-bar {
  display: flex;
  flex-shrink: 0;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-light);
  max-height: clamp(60px, 12cqb, 120px);
  min-height: 0;
  overflow: hidden;
  box-sizing: border-box;
}
.status-bar.has-avatar {
  min-height: clamp(48px, 10cqb, 96px);
}
.status-avatar {
  width: clamp(48px, 10cqb, 96px);
  height: clamp(48px, 10cqb, 96px);
  min-width: 40px;
  min-height: 40px;
  flex-shrink: 0;
  background: var(--bg-tertiary);
  border-right: 1px solid var(--border-light);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.status-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.status-values {
  flex: 1;
  min-width: 0;
  padding: clamp(4px, 2cqmin, 12px) clamp(6px, 3cqmin, 16px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: flex-start;
  column-gap: clamp(4px, 2cqmin, 10px);
  row-gap: clamp(2px, 1.3cqmin, 6px);
}
.status-item {
  font-size: calc(var(--font-size) * 1);
  color: var(--text-primary);
}
.status-item .var-name {
  color: var(--text-secondary);
}
.status-item .var-value {
  color: inherit;
}
.status-item-inline {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  padding: 0;
}
.status-item-progress {
  width: 100%;
  margin-top: clamp(1px, 0.5cqmin, 3px);
}
.status-progress-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: clamp(1px, 0.5cqmin, 3px);
  gap: clamp(4px, 2cqmin, 10px);
}
.status-progress-head .var-value {
  font-variant-numeric: tabular-nums;
}
.status-progress-bar {
  width: 100%;
  height: clamp(4px, 2cqmin, 10px);
  border-radius: 999px;
  background: var(--progress-bg);
  overflow: hidden;
}
.status-progress-fill {
  height: 100%;
  background: var(--progress-fill);
  transition: width 0.25s ease;
}
.status-bar:empty, .status-bar.hidden {
  display: none;
}

/* === 列表/物品栏统一展示样式 === */
.status-item-list {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: clamp(2px, 1cqmin, 5px);
}
.list-display-title {
  font-size: clamp(11px, 3.4cqmin, 15px);
  color: var(--text-secondary);
  line-height: 1.3;
}
.list-display {
  display: flex;
  gap: clamp(3px, 1.4cqmin, 8px);
  width: 100%;
  box-sizing: border-box;
}
.list-display-horizontal {
  flex-direction: row;
  align-items: flex-start;
}
.list-display-horizontal.list-display-wrap {
  flex-wrap: wrap;
}
.list-display-horizontal.list-display-scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.list-display-vertical {
  flex-direction: column;
  align-items: stretch;
}
/* .list-cell：仅控制布局/尺寸，不写背景/边框/字色，让 .tag 全局美化接管。
   .tag 在 components.css 是基础风格，主题里（txtbread / deathgame / ocean / spring 等）会进一步覆盖，
   保证列表 cell 跟项目其它 chip 同款，主题切换时自动跟随。 */
.list-cell {
  /* 用 inline-flex 而非 block-flex，避免单物品引用 [列表+物品] 嵌进正文段落（block 上下文）时 chip 被撑成整行宽。
     在父级 .list-display（flex 容器）内，inline-flex item 仍按 flex item 处理，宽度按内容自适应。 */
  display: inline-flex;
  align-items: center;
  gap: clamp(2px, 1cqmin, 6px);
  padding: clamp(2px, 0.8cqmin, 5px) clamp(4px, 1.4cqmin, 8px);
  font-size: clamp(11px, 3.2cqmin, 14px);
  box-sizing: border-box;
  min-width: 0;
  vertical-align: middle;
}
.list-cell-text-only {
  /* 横向纯文字 chip：允许文字稍微换行而不被截断（用 break-word 而非 nowrap） */
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
}
.list-display-horizontal.list-display-scroll .list-cell-text-only {
  /* 仅"横向滚动"模式才强制 nowrap，让文字在框内可以横向滚动而不换行 */
  white-space: nowrap;
}
/* 横向滚动模式下：单个 chip 不被 flex-shrink 压缩，按内容宽度，超出整体由父容器横向滚动 */
.list-display-horizontal.list-display-scroll .list-cell {
  flex-shrink: 0;
}
.list-display-vertical .list-cell-text-only {
  white-space: normal;
  word-break: break-word;
}
.list-cell-with-image {
  flex-direction: column;
  align-items: center;
  text-align: center;
}
/* 横向布局 + 有图模式：所有 cell 同宽（含空位占位），保持网格"装备格"视觉一致 */
.list-display-horizontal .list-cell-with-image {
  width: clamp(56px, 14cqmin, 80px);
  flex-shrink: 0;
}
.list-display-horizontal .list-cell-with-image .list-cell-text {
  width: 100%;
  text-align: center;
}
.list-display-vertical .list-cell-with-image {
  flex-direction: row;
  width: 100%;
  align-items: center;
  text-align: left;
}
/* 竖向布局：每个 cell 占一整行（左图右名+数量），无论有图无图都撑满父容器宽 */
.list-display-vertical .list-cell {
  display: flex;
  width: 100%;
}
.list-cell-img {
  width: clamp(28px, 9cqmin, 46px);
  height: clamp(28px, 9cqmin, 46px);
  object-fit: cover;
  border-radius: var(--radius-sm);
  /* 透明 PNG/SVG 应该真透明，让父级 .tag 的主题色透出来，不要硬设底色 */
  background: transparent;
  flex-shrink: 0;
}
.list-cell-img-empty {
  /* 空格子占位：保留虚线边框 + 浅底色，让作者一眼看出"这是空位" */
  border: 1px dashed var(--border-light);
  background: var(--bg-secondary);
}
.list-cell-text {
  font-size: clamp(10px, 3cqmin, 13px);
  line-height: 1.25;
  word-break: break-word;
  overflow-wrap: anywhere;
  flex: 1;
  min-width: 0;
  /* 保证空位 cell 的文字行也至少占一行高度，与有文字的 cell 等高 */
  min-height: 1.25em;
}
.list-cell-placeholder {
  /* 仅淡化背景色，不要把图框/文字行也变模糊 */
  opacity: 0.45;
}
.list-empty-text {
  font-size: clamp(11px, 3cqmin, 13px);
  color: var(--text-muted);
  padding: clamp(2px, 1cqmin, 5px) 0;
}
/* 末尾提示行：贴在 list 容器底部的小字（如"新加的物品会出现在末尾"） */
.list-tail-hint {
  font-size: clamp(10px, 2.6cqmin, 12px);
  color: var(--text-muted);
  margin-top: clamp(2px, 0.6cqmin, 4px);
  line-height: 1.4;
  opacity: 0.85;
}
.list-display-root {
  display: inline-block;
  vertical-align: middle;
  width: 100%;
  margin: clamp(2px, 0.6cqmin, 4px) 0;
}

/*
 * 收起/展开按钮：纯文字模式挂在 #game-area；图片模式（顶/左/右）挂在 #status-bar 内，
 * 顶栏用 top:100% 贴在栏底外、收起态用 .status-bar--collapsed 保留钮。game-area 已有 position:relative。
 */
.status-bar-toggle {
  position: absolute;
  top: clamp(4px, 0.5cqb, 8px);
  /* 离右边远一些，避免按钮和卡片右边框 / 状态栏底线视觉合并、不好点 */
  right: clamp(24px, 5cqmin, 40px);
  /* 仅在 #status-bar 栏体内叠在头像/数值之上，勿与 --gm-z-cg 同数值以免误解全局层级 */
  z-index: 3;
  box-sizing: border-box;
  min-width: clamp(22px, 3.5cqmin, 36px);
  min-height: clamp(22px, 3.5cqmin, 36px);
  padding: 0;
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--bg-secondary) 90%, transparent);
  color: var(--text-primary);
  font-size: calc(var(--font-size) * 1.125);
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  font-family: inherit;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-glow, var(--accent-color, #88aaff)) 25%, transparent),
              0 2px 8px color-mix(in srgb, var(--accent-glow, var(--accent-color, #88aaff)) 18%, transparent);
}
.status-bar-toggle:active {
  opacity: 0.9;
}

/* 收起态：status-bar.hidden → display:none（已由 .status-bar.hidden 规则处理） */

/* 变量状态栏：挂在 game-media-layer 内，叠在背景与立绘之上，低于 CG（见 .game-media-cg）；美化仍沿用 .status-bar 与主题变量 */
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  z-index: var(--gm-z-status, 9);
  box-sizing: border-box;
  pointer-events: auto;
  max-height: clamp(60px, 32cqb, 120px);
  border-bottom: 1px solid var(--border-light);
  /* 覆盖 .status-bar 的 overflow:hidden，否则绝对定位的收起钮伸出栏体时被裁掉，看起来像在栏内 */
  overflow: visible;
}
/* 顶栏展开：收起钮为 #status-bar 子节点，top:100% 相对真实栏底，随栏高变化 */
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-top:not(.status-bar--collapsed) .status-bar-toggle {
  top: 100%;
  margin-top: clamp(4px, 0.8cqb, 8px);
  right: clamp(24px, 5cqmin, 40px);
  left: auto;
  bottom: auto;
}
/* 顶栏收起：栏体压到顶边一条，变量与头像不占位；收起钮贴在媒体层最上沿（JS 用 collapsed，不用整栏 hidden） */
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-top.status-bar--collapsed:not(.hidden) {
  max-height: none !important;
  min-height: 0 !important;
  height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: none !important;
  border-bottom: none !important;
  background: transparent !important;
  box-shadow: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  overflow: visible !important;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-top.status-bar--collapsed:not(.hidden) .status-avatar,
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-top.status-bar--collapsed:not(.hidden) .status-values {
  display: none !important;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-top.status-bar--collapsed:not(.hidden) .status-bar-toggle {
  top: 0 !important;
  margin-top: 0 !important;
  right: clamp(24px, 5cqmin, 40px);
  left: auto;
  bottom: auto;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.has-avatar {
  min-height: 0;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar .status-avatar {
  width: clamp(40px, 22cqmin, 96px);
  height: clamp(40px, 22cqmin, 96px);
}

/* 图片模式收起：同样用 .hidden（统一机制） */

/*
 * 状态栏方向（仅图片模式生效）：
 *   top   = 固定顶边栏（默认）
 *   left  = 左侧悬浮面板
 *   right = 右侧悬浮面板
 * 纯文字模式一律强制为 top（JS 在 updateStatusBar 里兜底）。
 */
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left,
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right {
  z-index: var(--gm-z-status, 9);
  top: 2%;
  bottom: auto;
  width: auto;
  min-width: min(28%, 140px);
  max-width: 30%;
  min-height: clamp(120px, 52cqb, 420px);
  max-height: min(88%, 560px);
  padding: clamp(6px, 3cqmin, 16px) clamp(8px, 3.5cqmin, 18px);
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--accent-color) 45%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-glow) 18%, transparent),
              0 0 14px color-mix(in srgb, var(--accent-glow) 22%, transparent);
  background: color-mix(in srgb, var(--visual-textbox-bg, var(--bg-secondary)) 62%, transparent);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  flex-direction: column;
  align-items: stretch;
  /* 外侧收起钮不参与裁剪；纵向滚动交给 .status-values */
  overflow: visible;
  box-sizing: border-box;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left {
  left: 3%;
  right: auto;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right {
  right: 3%;
  left: auto;
}
/* 左右悬浮：收起钮在面板外侧（左栏→钮靠右缘朝内；右栏→钮靠左缘朝内），不占面板内宽度 */
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left .status-bar-toggle,
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right .status-bar-toggle {
  top: clamp(6px, 3cqmin, 14px);
  margin-top: 0;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left .status-bar-toggle {
  left: 100%;
  right: auto;
  margin-left: clamp(3px, 1.5cqmin, 8px);
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right .status-bar-toggle {
  right: 100%;
  left: auto;
  margin-right: clamp(3px, 1.5cqmin, 8px);
}
/* 左右悬浮模式下，头像改成独立小块放在顶部，值列表竖向排布 */
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left .status-avatar,
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right .status-avatar {
  width: clamp(40px, 24cqmin, 96px);
  height: clamp(40px, 24cqmin, 96px);
  border-right: none;
  border-bottom: 1px solid var(--border-light);
  align-self: center;
  margin-bottom: clamp(4px, 2cqmin, 10px);
  flex-shrink: 0;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left .status-values,
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right .status-values {
  flex: 1;
  flex-direction: column;
  align-items: stretch;
  align-content: flex-start;
  row-gap: clamp(3px, 1.5cqmin, 8px);
  padding: clamp(3px, 1.5cqmin, 8px) clamp(2px, 1cqmin, 6px);
  min-height: 0;
}

/* 左右悬浮收起：占位压成 0，不保留第二层面板框，只留外侧一颗钮贴在边线 */
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left.status-bar--collapsed:not(.hidden),
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right.status-bar--collapsed:not(.hidden) {
  overflow: visible !important;
  width: 0 !important;
  min-width: 0 !important;
  max-width: 0 !important;
  height: 0 !important;
  min-height: 0 !important;
  max-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  top: 2% !important;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left.status-bar--collapsed:not(.hidden) {
  left: 0 !important;
  right: auto !important;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right.status-bar--collapsed:not(.hidden) {
  right: 0 !important;
  left: auto !important;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-left.status-bar--collapsed:not(.hidden) .status-bar-toggle {
  left: 0;
  right: auto;
  top: 0;
  margin: 0;
  transform: none;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--dir-right.status-bar--collapsed:not(.hidden) .status-bar-toggle {
  right: 0;
  left: auto;
  top: 0;
  margin: 0;
  transform: none;
}

/*
 * 中心带 #game-area：在 #view-game-scale-inner 内。纯文字：舞台撑满该带，不定 9:16。
 * 图片绑定：舞台宽 100% 定 9:16；视口不足时仅 inner（本区）由 JS scale；顶栏与点击继续/选项在 inner 外全宽。
 */
.game-area {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  overflow: hidden;
  touch-action: manipulation;
  background: color-mix(in srgb, var(--bg-tertiary) 50%, var(--bg-primary));
}

.game-area.is-media-mode {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: hidden;
  overscroll-behavior: none;
}

.game-area:not(.is-media-mode) .game-stage-aspect {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  max-width: 100%;
  align-self: stretch;
  box-sizing: border-box;
  overflow: hidden;
}

.game-area.is-media-mode .game-stage-aspect {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  align-self: stretch;
  overflow: hidden;
  overscroll-behavior: none;
}

/*
 * 图片模式：版面美化小组件挂在 .game-stage-aspect 或 .tester-stage-card 内全幅叠层
 *（高于 .choice-area 8 / .tap-continue 9），模拟「页面内」弹层而非 #modal-container。
 */
.media-beauty-inpage-layer {
  position: absolute;
  inset: 0;
  z-index: 12;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: min(5%, 20px) min(4%, 14px);
  box-sizing: border-box;
  background: color-mix(in srgb, var(--bg-primary) 50%, rgba(0, 0, 0, 0.42));
  pointer-events: auto;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}
.media-beauty-inpage-layer .media-beauty-inpage-layer__panel {
  margin: auto;
  width: min(94cqi, 520px);
  max-width: min(94cqi, 520px);
  max-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 0;
}
.media-beauty-inpage-layer .media-beauty-modal-host {
  position: relative;
  width: 100%;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  max-height: min(78vh, 100%);
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  box-sizing: border-box;
  min-width: 0;
}

/* 纯文字模式正文区：flex-basis:0 + flex-grow:1 确保从 0 开始只占「status-bar 占完之后的剩余空间」，
 * 不会跑到 status-bar 上面；overflow-y:auto 让长文本滚动。
 * 隐藏滚动条轨道，防止主题伪元素的微小溢出产生原生滚动条。 */
.game-area:not(.is-media-mode) .game-stage-aspect > .game-text-mode {
  flex: 1 1 0;
  margin-top: 0;
  min-height: 0;
  max-height: none;
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.game-area:not(.is-media-mode) .game-stage-aspect > .game-text-mode::-webkit-scrollbar {
  display: none;
}

/*
 * 图片模式下选项按钮：覆盖整个 stage 的绝对叠层，按钮网格居中显示（仿资源预览的 rp-preview-choice-layer）。
 * JS 在进入图片模式时把 #choice-area 从 view-game 子节点 reparent 到 .game-media-layer 内部。
 */
.game-media-layer > .choice-area {
  position: absolute;
  inset: 0;
  z-index: 8;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: min(10%, 72px) 6%;
  box-sizing: border-box;
  background: transparent;
  border-top: none;
  pointer-events: auto;
  max-height: none;
  overflow-y: visible;
  flex-direction: row;
}
.game-media-layer > .choice-area.hidden {
  display: none;
}
.game-media-layer > .choice-area > .choice-grid {
  display: grid;
  /* 默认每个选项独占一行：minmax 下限 280px 在 400px 容器内只能容下一列；
     容器若被拉宽到 ≥ 580px 才允许两列并排，不"硬塞二分" */
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(3px, 1.4cqmin, 10px);
  width: min(96%, 400px);
  max-width: 100%;
  flex: none;
  min-height: 0;
  max-height: 100%;
}
.game-media-layer > .choice-area > .choice-countdown {
  position: absolute;
  top: 4%;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  padding: clamp(2px, 1cqmin, 6px) clamp(6px, 2.5cqmin, 14px);
  background: color-mix(in srgb, var(--visual-textbox-bg, var(--bg-secondary)) 62%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-color, var(--border-color)) 45%, transparent);
  border-radius: var(--radius-sm);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
}
.game-media-layer > .tap-continue {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1%;
  z-index: 9;
  width: auto;
  max-width: 100%;
  margin: 0 6%;
  padding: clamp(2px, 1cqmin, 6px) clamp(6px, 2.5cqmin, 14px);
  text-align: center;
  background: transparent;
  border-top: none;
  pointer-events: none;
  font-size: calc(var(--font-size) * 1.125);
  color: var(--text-muted);
}
.game-media-layer > .tap-continue.hidden {
  display: none;
}

/*
 * 图片模式底部文本 dock（与资源预览弹窗的 .rp-media-text-dock 同结构）：
 * dock 覆盖 stage 的大部分区域（上 0、左右 6%、下 4%），内部用 flex column + justify-content:flex-end
 * 让文本框沉到底部。名字条（game-media-name）可以放在 dock 内浮在文本框上方。
 */
.game-media-layer > .game-media-text-dock {
  position: absolute;
  top: 0;
  left: 6%;
  right: 6%;
  bottom: 4%;
  z-index: 7;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: stretch;
  gap: clamp(3px, 1.5cqmin, 8px);
  pointer-events: none;
  box-sizing: border-box;
}
.game-media-text-dock .game-media-name {
  position: static !important;
  left: auto !important;
  top: auto !important;
  width: max-content;
  max-width: 100%;
  box-sizing: border-box;
  align-self: flex-start;
  pointer-events: auto;
}
/* 媒体模式：整个画面右下角的小方形时钟图标按钮，点开历史记录。
 *  layer 是 .game-media-layer（占满 stage），按钮 absolute 到 layer 的 right:1%/bottom:1%——
 *  贴在画面右下角，不挡正文，单手可达。 */
.game-history-btn {
  position: absolute;
  right: 1.5%;
  bottom: 1.5%;
  width: clamp(20px, 4.4cqmin, 28px);
  height: clamp(20px, 4.4cqmin, 28px);
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  box-shadow: var(--shadow);
  color: var(--text-primary);
  cursor: pointer;
  pointer-events: auto;
  z-index: 11;
}
.game-history-btn svg {
  width: 72%;
  height: 72%;
  display: block;
  stroke-width: 2.2;
}
.game-history-btn:active {
  opacity: 0.7;
}
/*
 * 图片模式文本框（与 .rp-preview-text、立绘位置弹窗「正文区」虚线同一套）：
 * 虚线框相对整格舞台为 22% 高；dock 为 top:0 + bottom:4% 即高度为舞台的 96%，故此处用 22/96 相对 dock，
 * 与 image-binding-tab 中立绘位置参考 ghost（left/right 6%、bottom 4%、height 22%）在垂直方向对齐。
 */
/* 对话框基础样式（不含定位/高度），移到 layer 直接子后仍生效 */
.game-text-mode {
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-y: auto;
  padding: clamp(6px, 2cqmin, 14px) clamp(8px, 2.5cqmin, 16px);
  margin: 0;
  background: color-mix(in srgb, var(--visual-textbox-bg, var(--bg-secondary)) 62%, transparent);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  border: 1px solid color-mix(in srgb, var(--accent-color, var(--border-color)) 45%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-glow, var(--accent-color, #88aaff)) 18%, transparent),
              0 0 16px color-mix(in srgb, var(--accent-glow, var(--accent-color, #88aaff)) 22%, transparent);
  border-radius: var(--radius-sm);
  pointer-events: auto;
  cursor: pointer;
}
/* dock 流式时对话框占 dock 22% 高度的流式定位 */
.game-media-text-dock > .game-text-mode {
  position: relative;
  flex-shrink: 0;
  width: 100%;
  height: calc(100% * 22 / 96);
  min-height: 0;
  max-height: calc(100% * 22 / 96);
}

/* 图片模式：段落间隙、出选项后、或本段无正文时收起底部文本框（仍可通过全屏点击继续） */
.game-media-text-dock > .game-text-mode.game-text-mode--collapsed {
  display: none !important;
  height: 0 !important;
  max-height: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: none !important;
  box-shadow: none !important;
  overflow: hidden !important;
  pointer-events: none !important;
  cursor: default !important;
}

/* 纯文字模式：正文区直接挂在 stage 下时，收起态同样不占 flex 高度（封面/结局/重置后避免空框） */
.game-stage-aspect > .game-text-mode.game-text-mode--collapsed {
  display: none !important;
  flex: 0 0 0 !important;
  min-height: 0 !important;
  max-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  overflow: hidden !important;
}

.game-stage-aspect > .game-cover {
  flex: 1 1 auto;
  min-height: 0;
}

/* 部分启用媒体模式的故事里，同一个故事的部件有的走立绘、有的走纯文字。
   媒体层是常驻的（状态栏就挂在它里面），画面状态也要留着——玩家从立绘页插一段
   纯文字再回来时，背景立绘应该还在，不该要求作者重写一遍指令。所以纯文字部件下
   不清状态、只把画面元素藏起来：不然上一页的背景和立绘会留在纯文字页面上。 */
.game-area:not(.is-media-mode) .game-media-layer > .game-media-bg,
.game-area:not(.is-media-mode) .game-media-layer > .game-media-character,
.game-area:not(.is-media-mode) .game-media-layer > .game-media-cg,
.game-area:not(.is-media-mode) .game-media-layer > .game-media-name,
.game-area:not(.is-media-mode) .game-media-layer > .game-screen-fx-overlay {
  display: none !important;
}

.game-media-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* 子节点 z-index 在同一层内比较，避免立绘 transform 合成层与状态栏叠放顺序异常 */
  isolation: isolate;
  pointer-events: none;
  /*
   * 媒体层内绘制顺序（数值越大越靠上）：
   * 背景 < 立绘 < 全屏闪屏等 FX < CG < 名字条 < 变量状态栏；
   * 状态栏数值上高于 CG，是为了非 CG 时高于 .choice-area(8)，否则出选项时栏体 + #status-bar-toggle
   * 全被选项层覆盖、收起按钮无法点；CG 显示时 .game-area.is-cg-mode 规则直接 display:none 状态栏，
   * 实现「CG 是独占的一页，没有任何其他东西」的语义。与 .tester-stage-card .game-media-layer /
   * .rp-preview-game-area 保持一致（z=9）。
   */
  --gm-z-bg: 0;
  --gm-z-character: 2;
  --gm-z-fx: 3;
  --gm-z-cg: 5;
  --gm-z-name: 6;
  --gm-z-status: 9;
}

.game-media-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: var(--gm-z-bg, 0);
  pointer-events: none;
}

.game-media-character {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  /*
   * contain 时默认 object-position 居中，高宽比与舞台不一致会在元素框内上下留白，贴底的是「空框底」而非「图里脚底」，立绘会整体偏上；
   * JS 还会写 transform: translateX(-50%) scale(pos.scale)，默认 transform-origin 为元素中心，缩放时等价于以腰为轴上下胀缩，底边会跑出或顶进裁切区，与立绘位置弹窗里用宽高表现缩放、以底对齐的观感不一致。
   * 底对齐绘制 + 缩放锚在底边中点，与弹窗内 chBody bottom:0 + 定宽高 contain 的语义一致。
   */
  transform-origin: 50% 100%;
  max-height: 95%;
  max-width: 95%;
  object-fit: contain;
  object-position: bottom center;
  display: none;
  z-index: var(--gm-z-character, 2);
}

.game-media-cg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: none;
  z-index: var(--gm-z-cg, 5);
  pointer-events: none;
}

.game-media-name {
  position: absolute;
  left: clamp(6px, 2.5cqmin, 14px);
  top: clamp(6px, 2.5cqmin, 14px);
  z-index: var(--gm-z-name, 6);
  display: none;
  max-width: 70%;
  padding: clamp(2px, 1cqmin, 6px) clamp(4px, 2cqmin, 10px);
  border-radius: var(--radius-sm);
  /* 与 .game-media-text-dock > .game-text-mode 同背景 + 同款微弱发光描边 */
  border: 1px solid color-mix(in srgb, var(--accent-color, var(--border-color)) 45%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-glow, var(--accent-color, #88aaff)) 18%, transparent),
              0 0 14px color-mix(in srgb, var(--accent-glow, var(--accent-color, #88aaff)) 22%, transparent);
  background: color-mix(in srgb, var(--visual-textbox-bg, var(--bg-secondary)) 62%, transparent);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  color: var(--text-primary);
  font-size: calc(var(--font-size) * 1);
  font-weight: 600;
}

.game-screen-fx-overlay {
  position: absolute;
  inset: 0;
  z-index: var(--gm-z-fx, 3);
  pointer-events: none;
  overflow: hidden;
}

.game-screen-fx-overlay.fx-once-flash-white {
  animation: gamefx-flash-white 0.18s ease-out 1;
  background: #fff;
}

.game-screen-fx-overlay.fx-once-flash-rgb {
  animation: gamefx-flash-rgb 0.28s ease-out 1;
}

@keyframes gamefx-flash-white {
  0% { opacity: 0; }
  40% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes gamefx-flash-rgb {
  0% { opacity: 0; }
  35% { opacity: 1; }
  100% { opacity: 0; }
}

.game-stage-aspect.fx-once-shake {
  animation: gamefx-shake-once 0.4s ease-in-out 1;
}

@keyframes gamefx-shake-once {
  0%, 100% { transform: translate(0, 0); }
  15% { transform: translate(-6px, 3px); }
  30% { transform: translate(5px, -4px); }
  45% { transform: translate(-4px, -3px); }
  60% { transform: translate(4px, 3px); }
  75% { transform: translate(-2px, -2px); }
  90% { transform: translate(2px, 1px); }
}

.game-screen-fx-overlay.fx-bounce {
  animation: gamefx-bounce 0.55s ease-in-out infinite;
}

@keyframes gamefx-bounce {
  0%, 100% { transform: translateY(0) scale(1); }
  40% { transform: translateY(-2.5%) scale(1.02); }
  70% { transform: translateY(1%) scale(0.99); }
}

.game-screen-fx-overlay.fx-shake {
  animation: gamefx-shake 0.12s linear infinite;
}

@keyframes gamefx-shake {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-4px, 2px); }
  50% { transform: translate(3px, -3px); }
  75% { transform: translate(-2px, -2px); }
}

.game-screen-fx-overlay.fx-psy {
  animation: gamefx-psy 2.2s ease-in-out infinite;
  backdrop-filter: blur(1px);
}

@keyframes gamefx-psy {
  0% { filter: hue-rotate(0deg) saturate(1.2); }
  50% { filter: hue-rotate(180deg) saturate(1.6); }
  100% { filter: hue-rotate(360deg) saturate(1.2); }
}

.game-screen-fx-overlay.fx-pixel {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  image-rendering: pixelated;
  filter: contrast(1.15);
}

.game-screen-fx-overlay.fx-blur {
  backdrop-filter: blur(6px);
}

.game-screen-fx-overlay.fx-invert {
  mix-blend-mode: difference;
  background: rgba(255, 255, 255, 0.06);
}

.game-screen-fx-overlay.fx-vignette {
  box-shadow: inset 0 0 min(45cqi, 220px) rgba(0, 0, 0, 0.55);
}

.game-screen-fx-overlay.fx-scan::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    transparent,
    transparent 2px,
    rgba(0, 0, 0, 0.12) 2px,
    rgba(0, 0, 0, 0.12) 4px
  );
  opacity: 0.45;
}

.game-screen-fx-overlay.fx-glitch {
  animation: gamefx-glitch 0.4s steps(2, end) infinite;
}

@keyframes gamefx-glitch {
  0% { transform: translate(0, 0); filter: none; }
  20% { transform: translate(-2px, 1px); filter: hue-rotate(90deg); }
  40% { transform: translate(2px, -1px); filter: hue-rotate(-40deg); }
  60% { transform: translate(-1px, 2px); }
  100% { transform: translate(0, 0); }
}

/* 纯文字模式 */
/* 纯文字模式：不设 z-index（默认 auto），避免遮住 status-bar 的收起按钮（status-bar z-index:3） */
.game-text-mode {
  padding: 2cqmin;
  font-size: var(--font-size);
}
/* 图片模式的 dock / media-layer 内的文本框需要 position:relative + z-index 叠在背景之上 */
.game-media-text-dock > .game-text-mode {
  position: relative;
  z-index: 1;
}

/* CG 模式独占：除了 CG 和点击关闭的提示，其他 UI 全部隐藏（正文、状态栏、选项）。
   状态栏默认 z=9 是为了非 CG 时高于 choice-area(8) 让收起按钮可点，CG 时直接 display:none
   实现「CG 是单独一页」语义 —— 比降低 status-bar z 让 CG 盖更稳，且保留用户的展开/收起 class。 */
.game-area.is-cg-mode .game-text-mode,
.game-area.is-cg-mode #status-bar,
.game-area.is-cg-mode .choice-area {
  display: none;
}
.game-text-mode .text-paragraph {
  margin-bottom: clamp(6px, 3cqmin, 16px);
  line-height: 1.8;
  font-size: inherit;
  opacity: 0;
  /* 勿对 opacity 做过渡：与打字机并行时，0.3s 淡入会把已打出的字一起「延后显现」，观感像整段瞬出、没有逐字 */
}
.game-text-mode .text-paragraph.visible {
  opacity: 1;
}

/* 美化：整段颤抖（始终生效） */
.beauty-shake {
  display: inline-block;
  animation: beauty-shake 0.28s linear infinite;
}

/* 文字效果配置面板里：字体单选 chip 选中态 */
.beauty-font-chip.beauty-font-chip-active {
  background: var(--accent-color);
  color: #fff;
  border-color: var(--accent-color);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.3);
}
@keyframes beauty-shake {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-1px, 1px); }
  50% { transform: translate(1px, -1px); }
  75% { transform: translate(-1px, -1px); }
}

/* 打字机逐字入场（仅打字机模式逐字输出时由脚本包一层） */
.tw-fx-char {
  display: inline-block;
}
.tw-fx-jump {
  animation: tw-fx-jump 0.38s ease-out both;
}
@keyframes tw-fx-jump {
  from {
    opacity: 0.35;
    transform: translateY(0.4em) scale(0.9);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
.tw-fx-fall {
  animation: tw-fx-fall 0.42s ease-out both;
}
@keyframes tw-fx-fall {
  from {
    opacity: 0;
    transform: translateY(-1.15em);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.tw-fx-flip {
  animation: tw-fx-flip 0.45s ease-out both;
  transform-style: preserve-3d;
}
@keyframes tw-fx-flip {
  from {
    opacity: 0.4;
    transform: perspective(140px) rotateY(-88deg);
  }
  to {
    opacity: 1;
    transform: perspective(140px) rotateY(0deg);
  }
}
.tw-fx-invert {
  animation: tw-fx-invert 0.48s ease-out both;
}
@keyframes tw-fx-invert {
  from {
    opacity: 0.5;
    transform: rotate(180deg);
  }
  to {
    opacity: 1;
    transform: rotate(0deg);
  }
}
.tw-fx-vanish {
  animation: tw-fx-vanish 2.1s ease forwards;
}
@keyframes tw-fx-vanish {
  0%, 32% { opacity: 1; }
  100% { opacity: 0; }
}
/* 乱码：同一字位内字符切换 + 高对比闪烁/色相抖动 */
.tw-fx-glitch-slot {
  min-width: 1em;
  text-align: center;
  vertical-align: baseline;
}
.tw-fx-glitch-frag {
  color: var(--text-muted);
  text-shadow: 0 0 3px var(--accent-glow);
  animation: tw-fx-glitch-flicker 0.09s steps(1, end) infinite;
}
@keyframes tw-fx-glitch-flicker {
  0% {
    opacity: 1;
    transform: translate(0, 0) skewX(0deg);
    filter: brightness(1);
  }
  12% {
    opacity: 0.12;
    transform: translate(-1px, 1px) skewX(-10deg);
    filter: brightness(1.45) hue-rotate(85deg);
  }
  24% {
    opacity: 0.92;
    transform: translate(1px, -1px);
    filter: brightness(0.75);
  }
  36% {
    opacity: 0.2;
    transform: translate(0, 0) skewX(8deg);
    filter: hue-rotate(-55deg) contrast(1.2);
  }
  48% {
    opacity: 0.88;
    transform: translate(-1px, 0);
  }
  60% {
    opacity: 0.28;
    transform: translate(1px, 1px);
    filter: brightness(1.2) hue-rotate(40deg);
  }
  72% {
    opacity: 0.95;
    transform: translate(0, -1px) skewX(-4deg);
  }
  84% {
    opacity: 0.18;
    transform: translate(1px, 0);
    filter: brightness(0.9);
  }
  100% {
    opacity: 0.78;
    transform: translate(0, 0);
    filter: brightness(1.05);
  }
}
.tw-fx-glitch-final {
  text-shadow: none;
  animation: tw-fx-glitch-final 0.22s ease-out both;
}
@keyframes tw-fx-glitch-final {
  from {
    opacity: 0.55;
    transform: scale(0.9);
    filter: blur(1px);
  }
  to {
    opacity: 1;
    transform: scale(1);
    filter: none;
  }
}

/* 立绘模式 */
.game-visual-mode {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.visual-bg {
  flex: 1;
  position: relative;
  background-size: cover;
  background-position: center;
  min-height: 0;
}
.visual-character {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  max-height: 90%;
  pointer-events: none;
}
.visual-textbox {
  background: var(--visual-textbox-bg);
  padding: 12px 16px;
  min-height: 100px;
  flex-shrink: 0;
  position: relative;
}
.visual-name {
  font-size: calc(var(--font-size) * 0.9375);
  color: var(--color-preset-1);
  margin-bottom: clamp(2px, 1cqmin, 6px);
  font-weight: bold;
}
.visual-text {
  font-size: calc(var(--font-size) * 1);
  line-height: 1.7;
}
.visual-textbox.hidden {
  display: none;
}

/* 封面（仅自定义层） */
.game-cover {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  height: 100%;
  padding: 0;
  text-align: left;
  position: relative;
  overflow: hidden;
  overflow-x: hidden;
  touch-action: pan-y;
}
.game-cover-custom {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  flex: none;
  width: 100%;
  height: 100%;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
  z-index: 2;
  color: var(--text-primary);
}
.cover-custom-bg {
  position: absolute;
  inset: 0;
  background-size: contain;
  background-repeat: no-repeat;
  /* 底对齐：contain 时底部纹样锚在封面区底边，不随垂直居中整体上移 */
  background-position: center bottom;
  z-index: 0;
}
.cover-custom-scroll {
  position: relative;
  z-index: 1;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  padding: var(--ui-pad-md-x) var(--ui-pad-lg-x)
    calc(var(--ui-pad-md-x) + var(--safe-bottom, 0px));
  display: flex;
  flex-direction: column;
}
.cover-custom-stack {
  width: 100%;
  flex-shrink: 0;
  margin-top: auto;
  margin-bottom: auto;
}
.cover-custom-box {
  padding: var(--ui-pad-sm-y) 0;
  text-align: center;
}
.cover-custom-box-inner {
  display: flex;
  justify-content: center;
  width: 100%;
}
.cover-text-hug {
  display: inline-block;
  max-width: 100%;
  box-sizing: border-box;
  vertical-align: top;
  text-align: left;
}
.cover-text-hug--title {
  border: 1.5px solid var(--accent-color);
  border-radius: var(--radius);
  padding: 10px 16px;
  background: var(--bg-secondary);
}
.cover-text-hug--meta {
  border: 1px solid var(--border-light);
  border-radius: 999px;
  padding: 6px 14px;
  background: var(--bg-tertiary);
}
.cover-text-hug--meta .cover-custom-author {
  text-align: center;
}
.cover-text-hug--intro {
  border: 1px dashed var(--border-color);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  background: var(--bg-tertiary);
  text-align: left;
}
.cover-text-hug--intro .cover-custom-intro {
  text-align: left;
}
.cover-text-hug--comment {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  border-left: 3px solid var(--accent-color);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 6px 8px;
  background: var(--bg-tertiary);
}
.cover-text-hug--comment .cover-author-comment-acc {
  width: auto;
  max-width: min(100%, 520px);
  margin: 0 auto;
}
/* 关闭注释外层边框时，注释头/体不再自带边框并避免沾满整行 */
.cover-custom-box-inner .cover-author-comment-acc {
  width: auto;
  max-width: min(100%, 520px);
  margin: 0 auto;
}
.cover-custom-box-inner .cover-author-head {
  background: transparent;
  border: none;
  padding: 6px 0;
  border-radius: 0;
}
.cover-custom-box-inner .cover-author-body {
  padding: 6px 0 0 20px;
}
/* 中心图不再使用 hug 边框 */
/* 开始按钮：按文案宽度收缩，父级 flex 已居中，不拉满整行 */
.cover-custom-box-inner .cover-custom-start-btn,
.cover-custom-start-btn {
  width: fit-content;
  max-width: min(280px, 88cqi);
  min-width: 7.5em;
  min-height: var(--ui-comfort-tap, 44px);
  padding: 10px 22px;
  font-size: var(--ui-fs-15, 15px);
  font-weight: 600;
  box-sizing: border-box;
}
.cover-custom-bread {
  display: block;
  width: min(320px, 82cqi);
  max-width: 100%;
  height: auto;
  max-height: 46vh;
  object-fit: contain;
  border: none;
  background: transparent;
  margin: 0 auto;
}
.cover-custom-title {
  font-size: calc(var(--ui-fs-16) + 8px);
  font-weight: bold;
  line-height: 1.35;
  text-align: center;
}
.cover-custom-author {
  font-size: var(--ui-fs-13);
  color: var(--text-muted);
  line-height: 1.5;
  text-align: center;
}
.cover-custom-note {
  font-size: var(--ui-fs-14);
  color: var(--text-secondary);
  line-height: 1.65;
  white-space: pre-wrap;
  text-align: center;
}
.cover-custom-note--readonly {
  color: var(--text-muted);
  font-size: var(--ui-fs-13);
}
.cover-custom-intro {
  font-size: var(--ui-fs-14);
  color: var(--text-secondary);
  line-height: 1.7;
  white-space: pre-wrap;
  text-align: center;
}
.cover-custom-intro--readonly {
  color: var(--text-secondary);
  font-size: var(--ui-fs-13);
}
.cover-custom-author-comment {
  font-size: var(--ui-fs-13);
  color: var(--text-muted);
  font-style: italic;
  line-height: 1.65;
  white-space: pre-wrap;
  text-align: center;
}
.cover-author-comment-acc {
  width: 100%;
  text-align: left;
}
/* 游玩封面：每条注释 — 三角 + 作者名，正文在展开区 */
.cover-author-head {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  padding: 8px 10px;
  font-size: var(--ui-fs-13);
  font-weight: 600;
  color: var(--text-primary);
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  border: 1px solid var(--border-light);
}
.cover-author-head::-webkit-details-marker {
  display: none;
}
.cover-author-head::before {
  content: '';
  display: block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 5px 0 5px 7px;
  border-color: transparent transparent transparent var(--text-muted);
  flex-shrink: 0;
  transition: transform 0.15s ease;
  transform-origin: 30% 50%;
}
.cover-play-comment-item[open] > .cover-author-head::before {
  transform: rotate(90deg);
}
.cover-author-head__name {
  flex: 1;
  min-width: 0;
  word-break: break-word;
}
.cover-author-body {
  padding: 8px 10px 10px 28px;
  font-size: var(--ui-fs-13);
  color: var(--text-secondary);
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}
/* 封面设计页：同上结构，略紧凑 */
.cover-editor-comment-head {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  padding: 8px 10px;
  font-size: var(--ui-fs-13);
  font-weight: 600;
  color: var(--text-primary);
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  border: 1px solid var(--border-light);
}
.cover-editor-comment-head::-webkit-details-marker {
  display: none;
}
.cover-editor-comment-head::before {
  content: '';
  display: block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 5px 0 5px 7px;
  border-color: transparent transparent transparent var(--text-muted);
  flex-shrink: 0;
  transition: transform 0.15s ease;
  transform-origin: 30% 50%;
}
.cover-editor-comment-item[open] > .cover-editor-comment-head::before {
  transform: rotate(90deg);
}
.cover-editor-comment-author {
  flex: 1;
  min-width: 0;
  word-break: break-word;
}
.cover-editor-comment-body {
  padding: 6px 10px 10px 28px;
  font-size: var(--ui-fs-13);
  color: var(--text-secondary);
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}
.cover-editor-author-chain .cover-editor-comment-item {
  margin-bottom: 8px;
}
.cover-editor-author-chain .cover-editor-comment-item:last-child {
  margin-bottom: 0;
}
/* 自定义封面「开始」按钮已并入 cover-custom-stack，此处保留类名兼容 */
.cover-custom-footer {
  display: none;
}
.cover-custom-footer:empty {
  display: none;
}
/* 选项区（与顶栏同属 9:16 卡片内的底栏；跟随卡片缩放） */
.choice-area {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  padding: clamp(3px, 0.6cqb, 6px) clamp(3px, 0.8cqmin, 6px);
  padding-bottom: calc(clamp(3px, 0.6cqb, 6px) + var(--safe-bottom));
  background: var(--bg-secondary);
  border-top: 1px solid var(--border-light);
  min-height: 0;
  max-height: clamp(140px, 40cqb, 360px);
  overflow-y: auto;
}
.choice-grid {
  display: grid;
  /* 文字底栏模式的选项栅格：默认每个选项独占一行；容器够宽才并排，不"硬塞二分" */
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(3px, 0.5cqb, 5px);
  flex: 1 0 auto;
}
.choice-btn {
  padding: clamp(6px, 1cqb, 12px) clamp(4px, 0.6cqmin, 6px);
  font-size: var(--font-size);
  min-height: clamp(40px, 7cqb, 56px);
  text-align: center;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.1s, transform 0.1s;
  white-space: normal;
  word-break: break-all;
  overflow-wrap: break-word;
  line-height: 1.35;
  display: flex;
  align-items: center;
  justify-content: center;
}
.choice-btn:active {
  background: var(--bg-active);
  transform: scale(0.97);
}
.choice-btn.disabled {
  opacity: 0.3;
  pointer-events: none;
}
.choice-area:empty, .choice-area.hidden {
  display: none;
}

/* 限时选项倒计时（紧贴选项上方：按钮模式在 choice-area 内；文字模式在正文内） */
.choice-countdown {
  flex-shrink: 0;
  text-align: center;
  padding: clamp(4px, 1.2vmin, 8px) clamp(6px, 1.5vmin, 10px) clamp(6px, 1.5vmin, 10px);
  font-size: calc(var(--font-size) * 1.1875);
  font-weight: 600;
  color: var(--accent-color);
  border-bottom: 1px solid var(--border-light);
  margin: 0 -4px 6px;
}
.game-text-mode .choice-countdown-text {
  margin: 0 0 8px;
  padding: 6px 4px 8px;
  text-align: center;
  font-size: inherit;
  font-weight: 600;
  color: var(--accent-color);
  border-bottom: 1px solid var(--border-light);
}
.choice-countdown.hidden {
  display: none;
}

/* 倒计时进度条（不带文字） */
.choice-countdown-bar {
  height: 6px;
  border-radius: 999px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-light);
  overflow: hidden;
  margin-top: 6px;
}
.choice-countdown-fill {
  height: 100%;
  width: 100%;
  background: color-mix(in srgb, var(--accent-color) 65%, var(--bg-tertiary));
  transition: width 0.2s linear;
}

/* 设置：选项呈现二选一 */
/* 通用 n选1 互斥分段（设置 / tester / variable 横竖切换等共用）。
   永远单行 N 等分。字号由 utils-seg-fit.js 实测动态算，
   能放下用正常字号、窄时缩字但不切；不用 cqi（cqi 下限卡导致溢出被切）。 */
.settings-choice-mode {
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 0;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  overflow: hidden;
  flex: 1 1 0;
  min-width: 0;
  max-width: 320px;
}
.settings-choice-mode button {
  flex: 1 1 0;
  min-width: 0;
  margin: 0;
  padding: 6px 10px;
  font-size: calc(var(--font-size) * 0.9375);
  line-height: 1.3;
  text-align: center;
  border: none;
  border-radius: 0;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
}
.settings-choice-mode button + button {
  border-left: 1px solid var(--border-color);
}
.settings-choice-mode button.is-active {
  background: color-mix(in srgb, var(--accent-color) 28%, var(--bg-primary));
  color: var(--text-primary);
  font-weight: 600;
}
/* utils-seg-fit.js 兜底：字号缩到下限仍塞不下时整段 wrap，按钮独占整行。 */
.settings-choice-mode.seg-fit-wrapped {
  flex-wrap: wrap;
}
.settings-choice-mode.seg-fit-wrapped > button {
  flex: 1 1 100%;
  min-width: 100%;
}
.settings-choice-mode.seg-fit-wrapped > button + button {
  border-left: none;
  border-top: 1px solid var(--border-color);
}

/* 正文内选项链接（与底部按钮二选一） */
.choice-links-block {
  margin-top: 1em;
  padding-top: 0.75em;
  border-top: 1px solid var(--border-light);
  font-size: inherit;
  line-height: 1.65;
}
.choice-countdown-text + .choice-links-block {
  /* 文字选项模式：倒计时块已带分割线，避免重复两条线 */
  border-top: none;
  padding-top: 0;
  margin-top: 0.6em;
}
.choice-inline-row {
  display: block;
  margin: 0.4em 0;
  word-break: break-word;
  white-space: normal;
}
a.choice-inline-link {
  color: var(--accent-color);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  word-break: break-word;
  white-space: pre-wrap;
}
a.choice-inline-link.choice-inline-link--dim {
  opacity: 0.45;
  pointer-events: none;
  cursor: default;
  text-decoration: line-through;
  text-decoration-color: var(--text-muted);
}

/* 点击继续提示 */
.tap-continue {
  text-align: center;
  box-sizing: border-box;
  min-height: var(--game-bottom-tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(4px, 1cqb, 12px) clamp(6px, 1.6cqmin, 14px);
  padding-bottom: calc(clamp(4px, 1cqb, 12px) + var(--safe-bottom));
  color: var(--text-muted);
  font-size: var(--font-size);
  cursor: pointer;
  background: var(--bg-secondary);
  border-top: 1px solid var(--border-light);
  flex-shrink: 0;
}
.tap-continue.hidden {
  display: none;
}

/* END画面 */
.game-end {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 6;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(10px, 5cqmin, 24px) clamp(10px, 4.5cqmin, 22px) calc(clamp(10px, 5cqmin, 24px) + var(--safe-bottom, 0px));
  text-align: center;
  background-size: cover;
  background-position: center;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  gap: clamp(6px, 3cqmin, 14px);
}
.game-end.active {
  display: flex;
}
.end-copy-wrap {
  display: flex;
  flex-direction: column;
  gap: clamp(6px, 2.5cqmin, 12px);
  width: min(92%, 560px);
}
.end-title {
  font-size: calc(var(--font-size) * 1.75);
  line-height: 1.35;
  text-align: center;
}
.end-text {
  font-size: calc(var(--font-size) * 1.125);
  color: var(--text-secondary);
  line-height: 1.7;
  white-space: pre-wrap;
  text-align: center;
}
.end-image {
  display: block;
  width: min(80%, 320px);
  max-width: 100%;
  max-height: 46%;
  object-fit: contain;
  border-radius: var(--radius-sm);
  margin: 0 auto;
}
.end-copy-wrap.end-title-framed .end-title,
.end-copy-wrap.end-text-framed .end-text,
.end-image.end-image-framed,
#btn-replay.end-restart-framed {
  border: 1.5px solid var(--accent-color);
  background: color-mix(in srgb, var(--bg-secondary) 88%, transparent);
  border-radius: var(--radius);
  padding: clamp(6px, 2.5cqmin, 12px) clamp(8px, 3.5cqmin, 16px);
}
#btn-replay {
  width: fit-content;
  max-width: min(280px, 88%);
  min-width: 7.5em;
  font-size: calc(var(--font-size) * 1.125);
  margin: clamp(4px, 2cqmin, 10px) auto 0 !important;
}

/*
 * 媒体模式自定义布局：layout.enabled=true 时 JS 把对话框 / 名字框 / 历史按钮 移到
 * .game-media-layer 直接子节点；位置交给 inline 接管（用户改过的用用户值，未改的用默认值）。
 * 状态栏 / 状态栏按钮单独判断"用户是否改过状态栏组"，未改时保留 dir-left/right 默认行为。
 *
 * z-index 自高到低：历史按钮 > 状态栏折叠按钮 > 状态栏 > 名字框 > 对话框（文本框）
 */
.game-media-layer > .game-text-mode {
  position: absolute !important;
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
  pointer-events: auto;
  z-index: 10 !important;
}
.game-media-layer > .game-media-name {
  position: absolute !important;
  align-self: auto !important;
  z-index: 20 !important;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--custom-layout {
  right: auto !important;
  bottom: auto !important;
  max-width: none !important;
  min-width: 0 !important;
  max-height: none !important;
  min-height: 0 !important;
  z-index: 30 !important;
}
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--custom-layout.status-bar--dir-left,
.game-media-layer > :is(#status-bar, #tester-status-bar).status-bar.status-bar--custom-layout.status-bar--dir-right {
  flex-direction: row;
  align-items: center;
  left: auto;
  right: auto;
}
.game-media-layer > .status-bar-toggle.status-bar-toggle--custom-layout,
.game-media-layer > #status-bar-toggle.status-bar-toggle--custom-layout,
.game-media-layer > #tester-status-bar-toggle.status-bar-toggle--custom-layout {
  position: absolute !important;
  right: auto !important;
  bottom: auto !important;
  z-index: 40 !important;
}
.game-media-layer > .game-history-btn--in-layout {
  right: auto !important;
  bottom: auto !important;
  z-index: 50 !important;
}
