/* ============================================================
   小红书样机套图工具 · 手机版样式
   设计基调：极浅冷白底 + 超大圆角卡片 + 低饱和马卡龙 + 细字重
   ============================================================ */

/* ---------- 英文字体（Rascal，仅用于英文标题 / 装饰字，中文自动回退苹方） ---------- */
@font-face {
  font-family: 'Rascal';
  src: url('../fonts/Rascal.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* 底色：干净极浅冷白 */
  --bg: #F6F7FB;
  --bg-soft: #FBFBFE;
  --card: #FFFFFF;

  /* 文字：细字重、低对比 */
  --ink: #2F3138;
  --ink-2: #5F6474;
  --ink-3: #9CA2B4;
  --line: #EEF0F7;

  /* 低饱和马卡龙 */
  --pink: #F7DCE4;
  --pink-d: #E2A2B7;
  --pink-s: #FDF1F5;
  --mint: #D9EDE3;
  --mint-d: #96C9B2;
  --mint-s: #F0F8F4;
  --lav: #E3DEF5;
  --lav-d: #A79AD6;
  --lav-s: #F3F0FB;
  --blue: #D8E8F4;
  --blue-d: #90B9D6;
  --blue-s: #F0F7FB;
  --butter: #F8EDDA;
  --butter-d: #D9BC8B;
  --butter-s: #FDF8EE;

  /* 圆角 */
  --r-xl: 30px;
  --r-lg: 24px;
  --r-md: 18px;
  --r-sm: 14px;
  --r-pill: 999px;

  /* 投影：极淡、轻微浮起，不做厚重新拟态 */
  --sh-card: 0 8px 24px rgba(142, 150, 182, .10), 0 1px 3px rgba(142, 150, 182, .05);
  --sh-soft: 0 4px 14px rgba(142, 150, 182, .08);
  --sh-float: 0 14px 32px rgba(142, 150, 182, .16);
  --sh-press: 0 2px 8px rgba(142, 150, 182, .10);

  --font-cn: "PingFang SC", "HarmonyOS Sans SC", "Noto Sans SC", "Source Han Sans SC", "Microsoft YaHei", system-ui, sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* 可点控件统一关掉双击缩放/滚动延迟：部分安卓 WebView 里缺这条时，
   第一次点按可能被当成「待双击确认」吞掉，表现为按钮要点两下或偶发没反应。
   canvas 由 JS 单独设 touch-action:none（要接管拖动手势），不在此列。 */
button, .btn, .tpl-item, .swap-item, .seg-btn, .dropzone,
.check-line, .area-chip, input[type="range"] { touch-action: manipulation; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-cn);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  letter-spacing: .2px;
  overflow-x: hidden;
}

/* 顶部两团极淡的马卡龙光晕，制造呼吸感 */
body::before {
  content: '';
  position: fixed;
  inset: -20% -10% auto -10%;
  height: 420px;
  background:
    radial-gradient(280px 200px at 18% 8%, rgba(247, 220, 228, .55), transparent 70%),
    radial-gradient(260px 190px at 82% 4%, rgba(227, 222, 245, .55), transparent 70%),
    radial-gradient(220px 170px at 60% 26%, rgba(216, 232, 244, .40), transparent 72%);
  pointer-events: none;
  z-index: 0;
  /* 独立合成层：安卓 WebView 滚动页面时，fixed 的多层径向渐变若不提升，
     会跟着整屏逐帧重绘，是低端机滚动掉帧的常见隐性来源。 */
  transform: translateZ(0);
}

.app {
  position: relative;
  z-index: 1;
  max-width: 430px;
  margin: 0 auto;
  min-height: 100vh;
  /* svh = 小视口高：手机滚动时地址栏收缩会让 vh 逐帧变化，导致整页高度
     跟着每帧重排；svh 在地址栏展开/收起两种状态下恒定，不支持的旧浏览器
     退回上面的 vh */
  min-height: 100svh;
  padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px));
}

.en { font-family: 'Rascal', var(--font-cn); font-weight: 400; letter-spacing: .5px; }

/* ============================ 屏幕切换 ============================ */
.screen { display: none; }
.screen.on { display: block; animation: fadeUp .22s ease both; }
/* 起始不透到 0：旧版整屏从全透明淡入，低端机上像「白闪一下」；
   从 .55 起只保留轻微的浮现感，不再有闪屏观感 */
@keyframes fadeUp {
  from { opacity: .55; transform: translateY(5px); }
  to { opacity: 1; transform: none; }
}

/* ============================ 顶部条 ============================ */
.appbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(14px + env(safe-area-inset-top, 0px)) 18px 12px;
  /* 防频闪：backdrop-filter 会在低端安卓 WebView 上逐帧重模糊底层画布，导致闪屏卡顿，一律改实色 */
  background: #F6F7FB;
}
.appbar .back,
.appbar .act {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill);
  background: #fff;
  border: 0;
  box-shadow: var(--sh-soft);
  color: var(--ink-2);
  cursor: pointer;
}
.appbar .act { margin-left: auto; width: auto; padding: 0 16px; font-size: 13px; color: var(--pink-d); font-weight: 500; }
.appbar-title { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.appbar-title b { font-size: 16px; font-weight: 500; letter-spacing: .6px; }
.appbar-title span { font-size: 11px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ============================ 首页头部 ============================ */
.hero { padding: 6px 18px 4px; }
.hero .brand {
  display: flex; align-items: baseline; gap: 8px;
}
.hero .brand .logo {
  font-family: 'Rascal', var(--font-cn);
  font-size: 30px;
  color: var(--ink);
  letter-spacing: .5px;
  line-height: 1.15;
}
.hero .brand .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--pink-d); margin-bottom: 6px; }
.hero h1 {
  margin: 2px 0 6px;
  font-size: 22px;
  font-weight: 500;
  letter-spacing: .8px;
}
.hero p { margin: 0; font-size: 12.5px; color: var(--ink-3); font-weight: 300; }

/* ============================ 卡片 ============================ */
.card {
  background: var(--card);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-card);
  padding: 18px;
  margin: 14px 14px 0;
}
.card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: .5px;
  color: var(--ink);
}
.card-title .step {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: var(--pink-s);
  color: var(--pink-d);
  font-size: 12px;
  font-weight: 500;
}
.card-title small { margin-left: auto; font-size: 11px; color: var(--ink-3); font-weight: 300; letter-spacing: 0; }

/* ============================ 上传区 ============================ */
.dropzone {
  border: 1.6px dashed var(--lav);
  background: linear-gradient(160deg, var(--lav-s), var(--pink-s) 90%);
  border-radius: var(--r-lg);
  padding: 26px 18px;
  text-align: center;
  cursor: pointer;
  transition: .22s;
}
.dropzone.dragover { border-color: var(--pink-d); background: var(--pink-s); transform: scale(.99); }
.dropzone-inner { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.drop-icon {
  width: 54px; height: 54px;
  border-radius: 20px;
  background: #fff;
  box-shadow: var(--sh-soft);
  color: var(--pink-d);
  font-size: 26px;
  line-height: 54px;
  font-weight: 300;
}
.drop-main { margin: 4px 0 0; font-size: 14.5px; color: var(--ink); font-weight: 400; }
.drop-sub { margin: 0; font-size: 11.5px; color: var(--ink-3); font-weight: 300; }
.link { color: var(--lav-d); }

.thumb-list {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding: 4px 2px 2px;
  margin-top: 12px;
  scrollbar-width: none;
}
.thumb-list::-webkit-scrollbar { display: none; }
.thumb-item {
  position: relative;
  flex: 0 0 auto;
  width: 66px; height: 66px;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--bg-soft);
  border: 2px solid #fff;
  box-shadow: var(--sh-soft);
  transition: .2s;
}
.thumb-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.thumb-item.active { border-color: var(--pink-d); box-shadow: 0 0 0 3px var(--pink-s); }
.thumb-del {
  position: absolute; right: 3px; top: 3px;
  width: 18px; height: 18px; line-height: 17px; text-align: center;
  border-radius: 50%;
  background: rgba(47, 49, 56, .45);
  color: #fff; font-size: 12px;
}

.hint { margin: 10px 0 0; font-size: 11.5px; color: var(--ink-3); font-weight: 300; line-height: 1.7; }
.hint.mini { font-size: 11px; }
.hint b { color: var(--ink-2); font-weight: 500; }
.flat-tip {
  background: var(--butter-s);
  border-radius: var(--r-sm);
  padding: 10px 12px;
  color: #A8875B;
}

/* ============================ 分类卡片 ============================ */
.cat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.cat-card {
  border: 0;
  border-radius: var(--r-lg);
  padding: 14px;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-cn);
  transition: .22s;
  box-shadow: var(--sh-soft);
  position: relative;
  overflow: hidden;
}
.cat-card:active { transform: scale(.975); }
.cat-card .ic { width: 34px; height: 34px; margin-bottom: 10px; display: block; }
.cat-card .nm { font-size: 14px; font-weight: 500; color: var(--ink); display: block; }
.cat-card .ct { font-size: 11px; color: var(--ink-3); font-weight: 300; display: block; margin-top: 1px; }
.cat-card .en { position: absolute; right: 10px; bottom: 6px; font-size: 15px; opacity: .5; }
.cat-pink { background: linear-gradient(150deg, #FDF1F5, #F7DCE4); }
.cat-mint { background: linear-gradient(150deg, #F0F8F4, #D9EDE3); }
.cat-lav { background: linear-gradient(150deg, #F3F0FB, #E3DEF5); }
.cat-blue { background: linear-gradient(150deg, #F0F7FB, #D8E8F4); }
.cat-butter { background: linear-gradient(150deg, #FDF8EE, #F8EDDA); }
.cat-gray { background: linear-gradient(150deg, #F7F8FC, #EBEEF6); }
.cat-card.active { outline: 2px solid var(--pink-d); outline-offset: -2px; }

/* ============================ 热门样机 ============================ */
.hot-row {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding: 2px 14px 6px;
  margin: 0 -14px;
  scrollbar-width: none;
}
.hot-row::-webkit-scrollbar { display: none; }
.hot-card {
  flex: 0 0 auto;
  width: 118px;
  background: #fff;
  border-radius: var(--r-lg);
  box-shadow: var(--sh-soft);
  padding: 8px 8px 10px;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-cn);
  transition: .2s;
}
.hot-card:active { transform: scale(.97); }
.hot-card .pic {
  height: 96px;
  border-radius: var(--r-md);
  background: linear-gradient(160deg, var(--bg-soft), var(--lav-s));
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  margin-bottom: 7px;
}
.hot-card .pic img { max-width: 96%; max-height: 92%; display: block; }
.hot-card .nm { font-size: 12.5px; font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hot-card .tag { font-size: 10px; color: var(--mint-d); font-weight: 300; }

/* ============================ 预览区（编辑页） ============================ */
.preview-card {
  margin: 4px 6px 0;
  background: var(--card);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-card);
  padding: 6px;              /* 收紧内边距，样机在编辑区里能显示得更大 */
  position: relative;
  /* 注意：卡片本身不做 translateZ 提升。它是 sticky + 圆角 + overflow:hidden，
     再和内部已提升的 <canvas> 形成嵌套合成层，是部分安卓 GPU 滚动时
     整层闪白的触发组合；只提升画布一层即可 */
}
.canvas-wrap {
  position: relative;
  border-radius: var(--r-lg);
  background:
    linear-gradient(160deg, #FAFBFE, #F2F4FA);
  min-height: 210px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 0;
}
#canvas {
  display: block;
  max-width: 100%;
  /* 画布自身也提升为独立层：切换样机（位图重建）和滚动时
     避免与圆角裁剪、卡片阴影同层重绘造成的闪白 */
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  /* 编辑区里样机尽量占满，看得清才好调；
     但画布不能只按 64vh 撑高 —— 预览卡是 sticky 吸附在顶栏下的，
     卡片底部（擦除按钮 / 换样机横条 / 挑大图·换图按钮）还要落在
     「视口高 - 顶栏 - 固定底栏」的可见区内，否则在矮屏机型上
     这些按钮会被 fixed 底栏永久盖住、怎么滚都点不到。
     300px = 卡片内画布以外的控件预算（校准提示条+擦除行+横条+两按钮+内边距）。 */
  max-height: min(64vh, calc(100vh - var(--appbar-h, 64px) - 300px));
  /* 必须用 svh 覆盖：手机滚动时地址栏逐帧收缩，vh 跟着逐帧变 → sticky 画布
     每帧被重算尺寸、GPU 重栅格化，肉眼就是整屏闪；svh 恒定，滚动期间尺寸不动 */
  max-height: min(64svh, calc(100svh - var(--appbar-h, 64px) - 300px));
  width: auto;
  height: auto;
  border-radius: var(--r-md);
}

/* ---- 放大编辑：画布按倍数放大，容器变成可滚动的视口 ---- */
.canvas-wrap.zoomed {
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  align-items: flex-start;
  justify-content: flex-start;
  padding: 0;
  overscroll-behavior: contain;
}
.canvas-wrap.zoomed #canvas {
  max-width: none;
  max-height: none;
  width: calc(100% * var(--zoom, 1));
  height: auto;
  flex: none;
  border-radius: 0;
}

/* ---- 缩放条：独立于画布展示区之外的一行（舞台下、编辑坞上），不遮挡画面 ---- */
.zoom-row {
  flex: 0 0 auto;
  display: flex;
  justify-content: center;
  padding: 2px 10px 3px;
  background: transparent;
}
.zoom-bar {
  display: flex;
  gap: 4px;
  padding: 3px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 4px 14px rgba(142, 150, 182, .18);
}
.zoom-bar .zb {
  appearance: none;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 11px;
  font-weight: 400;
  color: var(--ink-2);
  padding: 4px 12px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .18s, color .18s;
}
.zoom-bar .zb.active {
  background: var(--pink-d);
  color: #fff;
}
.zoom-bar .zb-erase.active {
  background: var(--laven-d);
}

/* ---- 画布下方：橡皮擦按钮 ----
   从「悬浮在画布右侧」改成「画布下面右对齐的一行」，
   完全脱离画面区域，任何样机比例下都不会遮挡展示面。 */
.stage { position: relative; }
.under-stage-row {
  display: flex;
  justify-content: flex-end;
  padding: 6px 4px 2px;
}
.erase-dock {
  position: static;
  transform: none;
  z-index: auto;
  width: auto;
  height: 34px;
  padding: 0 14px;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 4px 14px rgba(142, 150, 182, .20);
  color: var(--ink-2);
  font: inherit;
  font-size: 10.5px;
  font-weight: 300;
  letter-spacing: .2px;
  cursor: pointer;
  transition: background .18s, color .18s, box-shadow .18s;
}
.erase-dock svg { display: block; }
.erase-dock:active { transform: scale(.96); }
.erase-dock.active {
  background: var(--laven-d);
  color: #fff;
  box-shadow: 0 6px 18px rgba(167, 154, 214, .40);
}
.empty-tip { text-align: center; padding: 30px 10px; }
.empty-main { margin: 0; font-size: 14px; color: var(--ink-2); font-weight: 400; }
.empty-sub { margin: 4px 0 0; font-size: 11.5px; color: var(--ink-3); font-weight: 300; }
.loading-tip {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  background: rgba(255, 255, 255, .92);
  border-radius: var(--r-pill);
  padding: 8px 18px;
  font-size: 12.5px;
  color: var(--ink-2);
  box-shadow: var(--sh-soft);
}
.stage-name { display: none; }

/* ============================ 样机模板条 ============================ */
.tpl-strip { margin: 14px 14px 0; }
.tpl-head { display: flex; align-items: center; gap: 10px; padding: 0 4px 10px; }
.tpl-head .tt { font-size: 15px; font-weight: 500; letter-spacing: .5px; }
.tpl-head .en { font-size: 15px; color: var(--ink-3); }
.tpl-head .srch {
  margin-left: auto;
  border: 0;
  background: #fff;
  border-radius: var(--r-pill);
  box-shadow: var(--sh-soft);
  color: var(--ink-2);
  font-size: 12px;
  padding: 7px 14px;
  font-family: var(--font-cn);
  cursor: pointer;
}
.search {
  width: 100%;
  border: 0;
  background: #fff;
  border-radius: var(--r-pill);
  box-shadow: var(--sh-soft);
  padding: 11px 16px;
  font-size: 13px;
  color: var(--ink);
  font-family: var(--font-cn);
  margin-bottom: 12px;
  outline: none;
}
.search::placeholder { color: var(--ink-3); font-weight: 300; }

.tpl-grid {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding: 2px 2px 8px;
  scrollbar-width: none;
}
.tpl-grid::-webkit-scrollbar { display: none; }
.tpl-item {
  flex: 0 0 auto;
  width: 82px;
  background: #fff;
  border-radius: var(--r-md);
  box-shadow: var(--sh-soft);
  padding: 6px 6px 7px;
  cursor: pointer;
  border: 1.6px solid transparent;
  transition: .2s;
  text-align: center;
}
.tpl-item img { width: 100%; height: 62px; object-fit: contain; display: block; border-radius: 12px; background: var(--bg-soft); }
.tpl-item .tpl-name {
  font-size: 10.5px;
  color: var(--ink-2);
  margin-top: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-weight: 300;
}
.tpl-item.active { border-color: var(--pink-d); box-shadow: 0 0 0 3px var(--pink-s); }
.tpl-item.active .tpl-name { color: var(--pink-d); font-weight: 500; }

/* ---------- 选样机页（打开的第一个页面）：三列大网格 ---------- */
.pick-bar {
  padding: 10px 14px 0;
}
.pick-bar .search { margin-bottom: 0; }
.pick-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 14px;
  overflow: visible;          /* 覆盖 .tpl-grid 的横向滚动 */
}
.pick-grid .tpl-item {
  flex: initial;              /* 覆盖 .tpl-item 的 flex: 0 0 auto */
  width: auto;
  padding: 8px 8px 9px;
  border-radius: var(--r-md);
}
.pick-grid .tpl-item img { height: 78px; border-radius: 12px; }
.pick-grid .tpl-item .tpl-name { font-size: 11px; margin-top: 6px; }
.pick-grid .tpl-empty { grid-column: 1 / -1; }
.foot-note #tplCount { color: var(--pink-d); font-weight: 500; }
.foot-note #tplCatLabel { color: var(--ink-2); }

/* ---------- 选样机页：商品分类横滑条 ---------- */
.cat-bar {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 12px 14px 2px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.cat-bar::-webkit-scrollbar { display: none; }
.cat-chip {
  flex: 0 0 auto;
  border: 0;
  background: #fff;
  border-radius: var(--r-pill);
  box-shadow: var(--sh-soft);
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 400;
  font-family: var(--font-cn);
  padding: 8px 15px;
  cursor: pointer;
  white-space: nowrap;
  transition: .18s;
}
.cat-chip.on {
  background: var(--pink-d);
  color: #fff;
  box-shadow: 0 6px 14px rgba(226, 162, 183, .35);
  font-weight: 500;
}

/* ---------- 编辑页：画布正下方的「换样机」横条 ---------- */
.swap-strip {
  display: flex;
  gap: 9px;
  margin: 10px -12px 0;          /* 负边距：让横条能滚到卡片边缘 */
  padding: 2px 12px 4px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.swap-strip::-webkit-scrollbar { display: none; }
.swap-item {
  flex: 0 0 auto;
  width: 76px;
  background: var(--bg-soft);
  border-radius: var(--r-md);
  padding: 5px 5px 6px;
  border: 1.6px solid transparent;
  cursor: pointer;
  text-align: center;
  transition: .2s;
  -webkit-tap-highlight-color: transparent;
}
.swap-item img {
  width: 100%;
  height: 54px;
  object-fit: contain;
  display: block;
  border-radius: 11px;
  background: #fff;
}
.swap-item .swap-name {
  font-size: 10px;
  color: var(--ink-2);
  margin-top: 4px;
  font-weight: 300;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.swap-item.active { border-color: var(--pink-d); background: var(--pink-s); }
.swap-item.active .swap-name { color: var(--pink-d); font-weight: 500; }
.swap-head {
  display: flex; align-items: center; gap: 6px;
  margin: 12px 0 0;
  font-size: 12px; color: var(--ink-3); font-weight: 300;
}

/* ---------- 预览画面左右边缘：横滑 / 点箭头切换样机 ----------
   只占左右各 30px 的窄条：手指从屏幕边缘在画面上横滑 = 换样机，
   画面中间的单指拖动仍然是调图片；条内竖滑让给页面滚动。
   z-index:2 压过画布(0)、低于右上倍率栏(3)，不挡放大按钮。 */
.swap-edge {
  position: absolute;
  top: 0; bottom: 0;
  width: 30px;
  z-index: 2;
  display: flex;
  align-items: center;
  touch-action: pan-y;                 /* 竖向手势让给页面，横向由 JS 接管 */
  -webkit-tap-highlight-color: transparent;
}
#swapEdgeL {
  left: 0; justify-content: flex-start;
  background: linear-gradient(90deg, rgba(91,74,99,.10), rgba(91,74,99,0));
}
#swapEdgeR {
  right: 0; justify-content: flex-end;
  background: linear-gradient(270deg, rgba(91,74,99,.10), rgba(91,74,99,0));
}
.swap-arrow {
  width: 26px; height: 26px;
  margin: 0 2px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(255,255,255,.85);
  box-shadow: 0 2px 8px rgba(91,74,99,.22);
  color: #5B4A63;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background .15s, transform .15s;
}
.swap-arrow:hover { background: #fff; transform: scale(1.10); }
.swap-arrow:active { transform: scale(.92); }
/* 放大精调时边缘让给视野拖动，避免拖画面看别处被误判成换样机 */
.canvas-wrap.zoomed .swap-edge { display: none; }
@media (max-width: 360px) {
  .swap-edge { width: 24px; }
  .swap-arrow { width: 22px; height: 22px; }
}

/* 两个按钮并排 */
.ctrl-row.two { margin-top: 10px; }
.ctrl-row.two .btn { flex: 1; }

/* 橡皮擦模式下给个十字光标，提示「这是笔不是手」 */
canvas.erasing { cursor: crosshair; }

/* ============================ 分段控件 ============================ */
.seg {
  display: flex;
  gap: 4px;
  background: #F2F3F9;
  border-radius: var(--r-pill);
  padding: 4px;
  margin-bottom: 4px;
}
.seg-3 { }
.seg-btn {
  flex: 1;
  border: 0;
  background: transparent;
  border-radius: var(--r-pill);
  padding: 9px 6px;
  font-size: 12.5px;
  font-family: var(--font-cn);
  color: var(--ink-2);
  font-weight: 400;
  cursor: pointer;
  transition: .2s;
  white-space: nowrap;
}
.seg-btn.active {
  background: #fff;
  color: var(--pink-d);
  font-weight: 500;
  box-shadow: var(--sh-soft);
}
.seg.wrap { flex-wrap: wrap; background: transparent; padding: 0; gap: 8px; }
.seg.wrap .seg-btn {
  flex: 0 0 auto;
  background: #fff;
  box-shadow: var(--sh-soft);
  padding: 8px 14px;
  font-size: 12px;
}
.seg.wrap .seg-btn.active { background: var(--lav-s); color: var(--lav-d); box-shadow: 0 0 0 1.6px var(--lav); }

/* ============================ 控件 ============================ */
.ctrl { margin-top: 14px; }
.ctrl-label {
  display: flex;
  align-items: center;
  font-size: 12.5px;
  color: var(--ink-2);
  margin-bottom: 9px;
  font-weight: 400;
}
.ctrl-val { margin-left: auto; font-size: 12px; color: var(--pink-d); font-weight: 500; }
.ctrl-row { display: flex; gap: 10px; margin-top: 14px; }

input[type=range] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 26px;
  background: transparent;
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  height: 8px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--lav-s), #EFF1F8);
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 24px; height: 24px;
  margin-top: -8px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid var(--lav-d);
  box-shadow: var(--sh-soft);
}
input[type=range]::-moz-range-track { height: 8px; border-radius: 999px; background: #EFF1F8; }
input[type=range]::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; background: #fff; border: 3px solid var(--lav-d); }

.btn {
  border: 0;
  border-radius: var(--r-pill);
  padding: 13px 20px;
  font-size: 13.5px;
  font-family: var(--font-cn);
  font-weight: 500;
  cursor: pointer;
  transition: .2s;
  letter-spacing: .4px;
}
.btn:active { transform: scale(.98); }
.btn-ghost {
  flex: 1;
  background: #fff;
  color: var(--ink-2);
  box-shadow: var(--sh-soft);
  font-weight: 400;
}
.btn-primary {
  width: 100%;
  background: linear-gradient(120deg, #F2C6D3, #D8CBF0 55%, #C6DDF0);
  color: #5B4A63;
  box-shadow: 0 10px 22px rgba(214, 190, 220, .45);
}
.btn-block { width: 100%; }
.btn-block2 { width: 100%; }
.btn-soft {
  background: var(--pink-s);
  color: var(--pink-d);
}

/* 开关行 */
.check-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  font-size: 12.5px;
  color: var(--ink-2);
  font-weight: 400;
  cursor: pointer;
}
.check-line input[type=checkbox] {
  -webkit-appearance: none;
  appearance: none;
  width: 42px; height: 24px;
  border-radius: 999px;
  background: #E7EAF3;
  position: relative;
  transition: .22s;
  flex: 0 0 auto;
  cursor: pointer;
}
.check-line input[type=checkbox]::after {
  content: '';
  position: absolute;
  left: 3px; top: 3px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--sh-soft);
  transition: .22s;
}
.check-line input[type=checkbox]:checked { background: var(--mint); }
.check-line input[type=checkbox]:checked::after { left: 21px; }

/* 区域 chips */
.area-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.area-chip {
  border: 0;
  background: #fff;
  border-radius: var(--r-pill);
  box-shadow: var(--sh-soft);
  padding: 8px 14px;
  font-size: 12px;
  color: var(--ink-2);
  font-family: var(--font-cn);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  transition: .2s;
}
.area-chip.active { background: var(--mint-s); color: var(--mint-d); box-shadow: 0 0 0 1.6px var(--mint); font-weight: 500; }
.chip-del { color: var(--ink-3); font-size: 13px; }
.chip-add { color: var(--lav-d); }

/* 折叠面板 */
.fold {
  background: var(--card);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-card);
  margin: 14px 14px 0;
  overflow: hidden;
}
.fold > summary {
  list-style: none;
  padding: 17px 18px;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: .5px;
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after {
  content: '';
  margin-left: auto;
  width: 9px; height: 9px;
  border-right: 1.8px solid var(--ink-3);
  border-bottom: 1.8px solid var(--ink-3);
  border-radius: 2px;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: .24s;
}
.fold[open] > summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.fold .fold-body { padding: 0 18px 18px; }
.fold > summary .step {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: var(--mint-s);
  color: var(--mint-d);
  font-size: 12px;
}

/* ============================ 导出页 ============================ */
.export-shot {
  border-radius: var(--r-lg);
  background: linear-gradient(160deg, #FAFBFE, #F1F3F9);
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  overflow: hidden;
}
.export-shot img {
  display: block;
  max-width: 100%;
  max-height: 46vh;
  border-radius: var(--r-md);
}
.export-shot .ph { font-size: 12.5px; color: var(--ink-3); font-weight: 300; text-align: center; line-height: 1.8; }
.ex-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  font-size: 11.5px;
  color: var(--ink-3);
  font-weight: 300;
}
.ex-meta .pill { background: var(--blue-s); color: var(--blue-d); border-radius: 999px; padding: 3px 10px; }

/* ============================ 底部导航 ============================ */
.tabbar {
  position: fixed;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 100%;
  max-width: 430px;
  z-index: 40;
  display: flex;
  gap: 4px;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
  background: #fff;
  border-radius: 26px 26px 0 0;
  box-shadow: 0 -8px 26px rgba(142, 150, 182, .10);
}
.tab {
  flex: 1;
  border: 0;
  background: transparent;
  border-radius: var(--r-md);
  padding: 8px 4px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  font-size: 10.5px;
  color: var(--ink-3);
  font-family: var(--font-cn);
  cursor: pointer;
  transition: .2s;
}
.tab .ti { width: 22px; height: 22px; }
.tab.on { color: var(--pink-d); background: var(--pink-s); font-weight: 500; }

/* ============================ 其它 ============================ */
.file-warn {
  margin: 12px 14px 0;
  background: var(--butter-s);
  border-radius: var(--r-md);
  padding: 12px 14px;
  font-size: 12px;
  color: #A8875B;
  line-height: 1.7;
}
.file-warn code { background: rgba(255, 255, 255, .7); border-radius: 6px; padding: 1px 6px; }

.foot-note {
  text-align: center;
  font-size: 11px;
  color: var(--ink-3);
  font-weight: 300;
  padding: 22px 30px 8px;
  line-height: 1.9;
}
.foot-note .en { font-size: 14px; color: var(--ink-3); display: block; margin-bottom: 2px; }

#toast {
  position: fixed;
  left: 50%;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  background: rgba(47, 49, 56, .88);
  color: #fff;
  padding: 10px 20px;
  border-radius: 999px;
  font-size: 12.5px;
  z-index: 99;
  opacity: 0;
  transition: .25s;
  pointer-events: none;
  max-width: 76%;
  text-align: center;
}

.spacer { height: 8px; }


/* ---------- 成品保存浮层（容器内不支持下载，改为展示 + 截屏） ---------- */
.xhs-mask {
  position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: 999;
  display: none; flex-direction: column; align-items: center; justify-content: center;
  padding: 18px 14px calc(18px + env(safe-area-inset-bottom, 0px));
  /* 实色底：blur 在安卓 WebView 又卡又费电，实色还衬得成品图更干净 */
  background: #262230;
}
.xhs-mask.on { display: flex; }
.xhs-mask img {
  max-width: 100%; max-height: 74vh; border-radius: 20px; background: #fff;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .32);
}
/* 点图进入「纯净全屏」：藏掉提示和按钮，成品铺满整屏，截屏分辨率最大化；再点还原 */
.xhs-mask.clean { padding: 0; }
.xhs-mask.clean img {
  max-height: none; width: 100%; height: 100%; object-fit: contain;
  border-radius: 0; box-shadow: none; background: #262230;
}
.xhs-mask.clean .xhs-tip, .xhs-mask.clean .xhs-close { display: none; }
.xhs-text {
  width: 100%; max-height: 52vh; border: 0; border-radius: 18px; padding: 16px;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.5;
  color: var(--ink); background: #fff; -webkit-user-select: text; user-select: text;
}
.xhs-tip { margin-top: 18px; text-align: center; color: #fff; font-size: 13.5px; font-weight: 300; }
.xhs-close {
  margin-top: 20px; padding: 11px 34px; border-radius: 999px; color: #5B4A63; font-size: 14px;
  background: linear-gradient(120deg, #F2C6D3, #D8CBF0 55%, #C6DDF0); box-shadow: 0 6px 18px rgba(0,0,0,.2);
}


/* ============================ 悬浮预览（自动追加 ============================
   下滚时样机展示区吸附在顶栏下面；.floating 由 app.js 的
   bindFloatPreview() 按滚动距离加/去（迟滞 160/60px）。
   --appbar-h 由脚本按顶栏实际高度（含安全区）写入。 */
.preview-card {
  position: sticky;
  top: var(--appbar-h, 64px);
  z-index: 12;               /* 顶栏是 30，卡在它下面、压住滚动上来的参数面板 */
}
.preview-card.floating {
  box-shadow: var(--sh-float);
  border-radius: 0 0 var(--r-xl) var(--r-xl);
}
/* 只收起「换样机横条」：换样机可走底部「样机」tab；
   但 .ctrl-row.two（挑大图·换张图片）必须保留 —— 收起后「换张图片」
   在整个应用里没有别的入口，藏掉会导致用户无法更换作品图。 */
.preview-card.floating .swap-head,
.preview-card.floating .swap-strip { display: none; }
/* 画布收窄；放大（.zoomed）时不动画布自身，改收外框。
   收起态卡片内非画布元素：校准提示条(约59) + 擦除行(约42)
   + 挑大图·换图按钮行(约56) + 卡片内边距(12) ≈ 169，
   再给固定底栏和安全余量留约 80px —— 极矮机型（横屏/小屏）下用 calc 兜底，
   确保「擦除」「换图」按钮永远不会落进底栏后面。 */
.preview-card.floating .canvas-wrap:not(.zoomed) #canvas {
  max-height: min(34vh, calc(100vh - var(--appbar-h, 64px) - 250px));
  /* 同上，svh 防止滚动时画布随地址栏逐帧缩放闪屏（旧浏览器用上一行 vh） */
  max-height: min(34svh, calc(100svh - var(--appbar-h, 64px) - 250px));
}
.preview-card.floating .canvas-wrap.zoomed { max-height: 46vh; max-height: 46svh; }
#canvas { transition: max-height .22s ease; }
/* 滚动 / 地址栏收缩 / 转屏期间：视口高逐帧变，过渡必须关掉，
   否则动画不停重启、画布尺寸一直追赶 → 边缘抖动闪（app.js 打 .view-moving） */
html.view-moving #canvas { transition: none; }


/* ============================ 多图对应（自动追加 ============================
   多图上传：缩略图左下角的序号（图 N）跟区域 chip 上的「区域N · 图M」对得上；
   「⇄ 按顺序铺图」一键把 图1→区域1、图2→区域2…… */
.thumb-no {
  position: absolute; left: 3px; bottom: 3px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px;
  background: rgba(47, 49, 56, .58); color: #fff;
  font-size: 10px; line-height: 16px; text-align: center;
  pointer-events: none;
}
.chip-spread { color: var(--mint-d); background: var(--mint-s); font-weight: 500; }

/* ============================ 编辑页 · 醒图风工作台（20260926） ============================
   布局：顶栏（返回/标题/导出）→ 顶部换样机横条 → 居中超大画布 → 底部编辑坞
   （上：当前工具的参数面板；下：可横滑的图标工具条）。整屏不滚动，
   旧的「滚动吸顶预览卡 + 折叠面板」机制在编辑页停用（其他页面不受影响）。 */
/* fixed 脱离文档流：高度直接等于可视区（inset:0），不受 .app 的 min-height:100svh、
   页面地址栏动态伸缩、vh/svh 差异影响，整屏固定不滚动；宽屏居中限宽 430 */
body.edit-on #scrEdit.screen.on {
  position: fixed;
  inset: 0;
  z-index: 100;
  width: 100%;
  max-width: 430px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: none;
}
body.edit-on .tabbar { display: none; }
/* 双保险：fixed 工作台已脱离文档流，再锁掉文档/body 自身滚动，杜绝橡皮筋式整页滑动。
   浏览器的滚动根可能是 documentElement 也可能是 body，两边都锁；离开编辑页类被移除即恢复 */
html.edit-on { overflow: hidden; }
body.edit-on { overflow: hidden; }
/* .app 默认给固定底栏留了 84px 内边距，编辑页没有底栏，去掉，否则画布下空一条 */
body.edit-on .app { padding-bottom: 0; }
body.edit-on #scrEdit > .spacer { display: none; }
#scrEdit .appbar { flex: 0 0 auto; }

/* ---------- 顶部：换样机横条 + 两个入口 ---------- */
.edit-top {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 10px 4px 4px;
  background: var(--card);
  border-radius: 0 0 18px 18px;
  box-shadow: 0 6px 16px rgba(142, 150, 182, .07);
  position: relative;
  z-index: 5;
}
.edit-strip {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  padding: 1px 4px 1px 8px;
  gap: 7px;
}
.edit-strip .swap-item { width: 54px; padding: 3px 4px 4px; }
.edit-strip .swap-item img { height: 39px; border-radius: 9px; }
.edit-strip .swap-item .swap-name { font-size: 9.5px; margin-top: 2px; }
.top-ico {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 12px;
  background: #fff;
  box-shadow: var(--sh-soft);
  color: var(--ink-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: .15s;
}
.top-ico:active { transform: scale(.92); }

/* ---------- 中间：大画布舞台 ---------- */
.edit-stage {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px 10px;
  overflow: hidden;
}
.edit-stage .canvas-wrap {
  width: 100%;
  height: 100%;
  min-height: 0;
  border-radius: var(--r-lg);
}
.edit-stage #canvas {
  max-width: 100%;
  max-height: 100%;
  /* 旧布局的 max-height 过渡是为滚动吸顶服务的；本布局画布尺寸由 flex 舞台决定，不要它 */
  transition: none;
}
.edit-stage .canvas-wrap.zoomed #canvas {
  max-width: none;
  max-height: none;
}

/* ---------- 底部：编辑坞（参数面板 + 工具条） ---------- */
.edit-dock {
  flex: 0 0 auto;
  background: #fff;
  border-radius: 22px 22px 0 0;
  box-shadow: 0 -8px 26px rgba(142, 150, 182, .12);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  position: relative;
  z-index: 6;
}

/* 跨工具共享：贴图区域 chips + 调整操作提示（提示只在 调图片/贴图区/透视 三个工具下出现） */
.dock-shared { padding: 5px 14px 0; }
/* 区域名和 chips 挤同一行，chips 单行横滑，尽量少占垂直空间 */
.dock-area {
  display: flex;
  align-items: center;
  gap: 10px;
}
.dock-area-label {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--ink-2);
  margin: 0;
  white-space: nowrap;
}
.dock-area-label .ctrl-val { font-style: normal; }
.dock-area .area-chips {
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: nowrap;
  gap: 7px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.dock-area .area-chips::-webkit-scrollbar { display: none; }
.dock-area .area-chip { padding: 4px 10px; font-size: 11.5px; white-space: nowrap; }
.dock-tip {
  margin: 3px 0 0;
  font-size: 11px;
  color: var(--ink-3);
  font-weight: 300;
  line-height: 1.4;
}
#adjustTipWrap {
  height: 15px;
  margin: 2px 0 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 非调整工具下只隐身不删占位：切工具时舞台/画布高度纹丝不动 */
.edit-dock:not([data-tool="image"]):not([data-tool="region"]):not([data-tool="persp"]) #adjustTipWrap {
  visibility: hidden;
}

/* 参数面板：固定高度（紧凑：两行滑块/一排分段即可），切工具画布不跳；
   内容更多（橡皮擦/更多）时面板内部滚动，不挤占画布 */
.tool-panels {
  height: 94px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 2px 14px 5px;
  scrollbar-width: thin;
}
.tool-panel { display: none; }
.tool-panel.on { display: block; animation: dockIn .2s ease both; }
@keyframes dockIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.tool-panel .ctrl-label { margin-bottom: 4px; }
/* 调色面板：标题行（含还原）+ 5 个滑块「名称在左滑杆在右」单列紧凑排，一屏放下不滚动 */
.color-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0;
  line-height: 1.2;
}
.color-title { font-size: 10.5px; color: var(--ink-3); }
.color-reset {
  border: 0;
  background: var(--pink-s);
  color: var(--pink-d);
  font-family: var(--font-cn);
  font-size: 10.5px;
  line-height: 1.2;
  padding: 2px 12px;
  border-radius: 999px;
  cursor: pointer;
}
.color-reset:active { transform: scale(.94); }
#colorCtrls .grid2 { display: block; }
#colorCtrls .ctrl {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 0;
}
#colorCtrls .ctrl-label {
  flex: 0 0 50px;
  margin: 0;
  font-size: 10.5px;
  line-height: 1.1;
  white-space: nowrap;
}
#colorCtrls input[type=range] { flex: 1 1 auto; width: auto; height: 12px; margin: 0; }
/* 其他工具面板默认两列网格（调色面板在上方用更高优先级改为单列紧凑行） */
.tool-panel .grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}
.tool-panel .ctrl { margin-top: 6px; }
.tool-panel .ctrl:first-child { margin-top: 2px; }
.tool-panel input[type=range] { height: 20px; }
.tool-panel .ctrl-row { margin-top: 6px; }
.tool-panel .seg.wrap { margin-bottom: 2px; }
.tool-panel .flat-tip { padding: 6px 11px; margin-top: 6px; }

/* 工具条：图标 + 文字，横向滑动 */
.tool-rail {
  display: flex;
  gap: 2px;
  overflow-x: auto;
  padding: 3px 8px 4px;
  border-top: 1px solid #F1F2F8;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.tool-rail::-webkit-scrollbar { display: none; }
.tool-btn {
  flex: 0 0 auto;
  width: 56px;   /* 7 个工具在 430 宽内刚好放满，不用滚动 */
  border: 0;
  background: transparent;
  border-radius: 14px;
  padding: 4px 0 3px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  color: var(--ink-3);
  font-family: var(--font-cn);
  font-size: 10px;
  line-height: 1.1;
  cursor: pointer;
  transition: .18s;
  -webkit-tap-highlight-color: transparent;
}
.tool-btn svg { width: 20px; height: 20px; }
.tool-btn.on {
  color: var(--pink-d);
  background: var(--pink-s);
  font-weight: 500;
}

/* 矮屏机型（横屏 / 小窗 / 小屏手机）：进一步压缩面板和顶部缩略条，把高度让给画布 */
@media (max-height: 740px) {
  .tool-panels { height: 82px; padding: 1px 14px 2px; }
  .edit-strip .swap-item { width: 48px; }
  .edit-strip .swap-item img { height: 34px; }
  .edit-strip .swap-item .swap-name { display: none; }
  .dock-shared { padding-top: 4px; }
  #adjustTipWrap { display: none !important; }
  /* 缩放独立行在矮屏下再收一档 */
  .zoom-row { padding: 1px 10px 2px; }
  .zoom-bar .zb { padding: 3px 11px; font-size: 10.5px; }
  /* 调色行基础样式已足够紧凑，矮屏下只再收一点，保证 5 个滑块一屏可见 */
  #colorCtrls .ctrl { gap: 8px; }
  #colorCtrls input[type=range] { height: 11px; }
  .color-reset { padding: 1px 11px; }
}
