/* 产品界面外壳样式。纸张本身的样式在 paper.css，两者不要混。
 *
 * ── 视觉系统（2026-08-27 重建）────────────────────────────────
 * 这个产品的产物是纸。界面的职责是当一张安静、精确的工作台面：
 * 纸（A4 预览）是唯一的主角，其余一切退后。由此推出整套语言——
 *
 *   色彩：无彩度的灰阶层级 + 唯一的品牌蓝。界面本身不使用第二种彩色，
 *         绿/红只作语义状态（已发布/危险），且降饱和。
 *   层级：靠字号/字重/灰度三个轴分层，不靠加框加底色。
 *   空间：区块之间优先用距离和对齐分隔；发丝线只出现在
 *         「确实需要一条物理边界」的地方（导航、面板、纸的边缘）。
 *   形状：按钮 8px 方角（2026-08-28 用户裁定弃胶囊，向现代组件库对齐：
 *         次按钮白底描边、主按钮实色，参照 shadcn/ui 的克制感）；
 *         输入类控件 8px；卡片 12px；纸接近直角（2px）——纸就是纸。
 *   投影：三档且各有含义——lift（卡片浮起）、paper（纸浮在台面上）、
 *         float（浮层）。不出现第四种。
 *   动效：只有 120~160ms 的颜色/阴影过渡和焦点环。不做入场动画。
 */

:root {
  /* 灰阶（无色相：冷静、理性，不与纸的白抢戏） */
  --bg: #f4f4f5;            /* 页面台面 */
  --bg-deep: #ececee;       /* 画布井 / 缩略图台面：比台面再深半档，纸才浮得起来 */
  --surface: #ffffff;
  --surface-2: #f4f4f5;     /* 悬停底、静默填充 */
  --border: rgba(17, 17, 20, .08);         /* 发丝线 */
  --border-strong: rgba(17, 17, 20, .16);  /* 输入框描边 */
  --text: #1a1a1e;
  --text-dim: #5d5d66;
  --text-faint: #8f8f99;

  /* 唯一的彩色。绿/红只作语义，不参与品牌表达 */
  --accent: #0a6cf5;
  --accent-deep: #0557d1;
  --accent-soft: #eef4fe;
  --danger: #d0453e;
  --danger-soft: #fdf1f0;
  --ok: #17854a;
  --ok-soft: #e9f6ee;

  --nav-h: 52px;

  --r-ctl: 8px;             /* 输入框、面板内小件 */
  --r-card: 14px;           /* 卡片 */
  --r-pill: 980px;          /* 按钮、分段选择 */
  --radius: var(--r-ctl);   /* 旧名，个别组件还在引用 */

  --shadow-lift: 0 1px 2px rgba(17, 17, 20, .04), 0 6px 20px rgba(17, 17, 20, .06);
  --shadow-paper: 0 1px 3px rgba(17, 17, 20, .08), 0 10px 26px rgba(17, 17, 20, .07);
  --shadow-float: 0 2px 8px rgba(17, 17, 20, .08), 0 14px 36px rgba(17, 17, 20, .16);
  --shadow: var(--shadow-lift);   /* 旧名 */

  --font-ui: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans',
             'Segoe UI', Roboto, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.55 var(--font-ui);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--accent-soft); }

/* 键盘焦点统一一种环。鼠标点击不出环（:focus-visible 自会区分） */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── 导航条 ─────────────────────────────────────────────────── */
.pb-nav {
  height: var(--nav-h);
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 0 20px;
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  position: relative;
  z-index: 20;
}

.pb-nav-brand {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -.01em;
  color: var(--text);
  text-decoration: none;
}

.pb-nav-links { display: flex; gap: 2px; }

/* 当前页 = 墨色 + 加重；其余退成灰。不给当前页上底色——
   层级靠灰度差就够了，加一块彩色底反而让导航比内容响 */
.pb-nav-link {
  padding: 6px 12px;
  border-radius: 8px;
  color: var(--text-dim);
  text-decoration: none;
  font-size: 13px;
  transition: color .12s, background-color .12s;
}

.pb-nav-link:hover { background: var(--surface-2); color: var(--text); }

.pb-nav-active,
.pb-nav-active:hover { background: transparent; color: var(--text); font-weight: 650; }

.pb-nav-slot { flex: 1; display: flex; align-items: center; gap: 10px; min-width: 0; }

.pb-nav-lang-label { color: var(--text-faint); font-size: 12px; }

.pb-nav-lang {
  background: transparent;
  border: none;
  border-radius: var(--r-ctl);
  padding: 4px 6px;
  font-size: 12.5px;
  color: var(--text-dim);
  cursor: pointer;
}
.pb-nav-lang:hover { color: var(--text); background: var(--surface-2); }

/* ── 通用控件 ───────────────────────────────────────────────── */
/* 按钮：现代组件库式样（用户点名要这一路）——次按钮白底 + 发丝描边 + 一线投影，
   主按钮实色无边。8px 方角，36px 高。 */
.pb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;   /* 链接元素长成按钮时不要下划线 */
  box-shadow: 0 1px 2px rgba(17, 17, 20, .05);
  transition: background-color .12s, color .12s, border-color .12s, box-shadow .15s;
}

.pb-btn:hover:not(:disabled) { background: #f7f7f8; }
.pb-btn:active:not(:disabled) { background: #f0f0f2; }
.pb-btn:disabled { opacity: .4; cursor: default; }

.pb-btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.pb-btn-primary:hover:not(:disabled) { background: var(--accent-deep); border-color: var(--accent-deep); }
.pb-btn-primary:active:not(:disabled) { background: var(--accent-deep); }

.pb-btn-ghost {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--text-dim);
  font-weight: 450;
}
.pb-btn-ghost:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }

.pb-btn-danger { background: transparent; border-color: transparent; box-shadow: none; color: var(--danger); }
.pb-btn-danger:hover:not(:disabled) { background: var(--danger-soft); }

.pb-input, .pb-select, .pb-textarea {
  width: 100%;
  padding: 6px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-ctl);
  background: var(--surface);
  font-size: 13px;
  transition: border-color .12s, box-shadow .12s;
}

.pb-input:focus, .pb-select:focus, .pb-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(10, 108, 245, .13);
}

.pb-textarea { resize: vertical; min-height: 66px; line-height: 1.5; }

.pb-range { width: 100%; accent-color: var(--accent); }

.pb-color {
  width: 34px;
  height: 26px;
  padding: 2px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--surface);
  cursor: pointer;
}

.pb-check { display: flex; align-items: center; gap: 7px; font-size: 13px; cursor: pointer; }
.pb-check input { accent-color: var(--accent); }

/* ── Studio 三栏布局 ────────────────────────────────────────── */
.pb-shell {
  display: flex;
  height: calc(100vh - var(--nav-h));
  min-height: 0;
}

.pb-sidebar,
.pb-inspector {
  width: 268px;
  flex: 0 0 268px;
  background: var(--surface);
  /* 用逻辑属性而不是 left/right：设了 dir="rtl"（阿拉伯语等五种）版面会自己镜像 */
  border-inline-end: 1px solid var(--border);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.pb-inspector {
  border-inline-end: none;
  border-inline-start: 1px solid var(--border);
  width: 300px;
  flex-basis: 300px;
}

.pb-main { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }

/* 工具栏永远一行：换行会把「打印」挤到第二层，工具栏就不再像一件工具。
   空间不够时标题输入框先收缩（它带 flex:0 1 基准），再不够整条横滑——
   与移动端同一个模型，桌面只是极少走到滑动那一步 */
.pb-toolbar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.pb-toolbar::-webkit-scrollbar { display: none; }
.pb-toolbar > * { flex: 0 0 auto; }

.pb-toolbar-sep { width: 1px; height: 18px; background: var(--border-strong); margin: 0 2px; }
.pb-toolbar-spacer { flex: 1 1 4px; }

/* 工具栏里的按钮走紧凑档：一行要装下撤销/重做、标题、缩放和三个动作 */
.pb-toolbar .pb-btn { height: 32px; padding: 0 11px; }

/* 画布井比台面再深半档：纸浮在上面，视线自然落到纸上 */
.pb-canvas-wrap {
  flex: 1;
  overflow: auto;
  padding: 32px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  background: var(--bg-deep);
}

.pb-canvas {
  display: flex;
  flex-direction: column;
  gap: 24px;
  /* 宽度由纸张决定（而不是被容器拉伸），缩放原点固定在左上角：
     这样「缩放后占多大位置」是一道能算准的算术题，居中交给外层容器做。 */
  width: max-content;
  transform-origin: top left;
}

/* ── 侧栏分区 ───────────────────────────────────────────────── */
.pb-section { border-bottom: 1px solid var(--border); padding: 14px 16px; }
.pb-section:last-child { border-bottom: none; }

.pb-section-title {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 0 0 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.pb-field { margin-bottom: 12px; }
.pb-field:last-child { margin-bottom: 0; }

.pb-label {
  display: block;
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 4px;
}

.pb-row { display: flex; gap: 8px; align-items: center; }
.pb-row > * { min-width: 0; }
.pb-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.pb-row-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }

.pb-value {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--text-faint);
  min-width: 40px;
  text-align: end;
}

/* ── 文档列表 ───────────────────────────────────────────────── */
.pb-doclist { display: flex; flex-direction: column; gap: 1px; }

.pb-docitem {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: var(--r-ctl);
  cursor: pointer;
  transition: background-color .12s;
}

.pb-docitem:hover { background: var(--surface-2); }

/* 选中项是界面里少数允许用品牌蓝的地方：它是「正在编辑的对象」 */
.pb-docitem-active,
.pb-docitem-active:hover { background: var(--accent-soft); }
.pb-docitem-active .pb-docitem-name { color: var(--accent); font-weight: 600; }

.pb-docitem-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
}

.pb-dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; }
.pb-dot-published { background: var(--ok); }
.pb-dot-draft { background: var(--border-strong); }

/* ── 模板选择 ───────────────────────────────────────────────── */
.pb-templates { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

.pb-tpl {
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  padding: 8px;
  cursor: pointer;
  background: var(--surface);
  text-align: start;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color .12s, background-color .12s;
}

.pb-tpl:hover { border-color: var(--border-strong); }
.pb-tpl-active,
.pb-tpl-active:hover { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }

.pb-tpl-name { font-size: 12.5px; font-weight: 550; line-height: 1.3; }
.pb-tpl-thumb { height: 46px; border-radius: 4px; background: var(--surface-2); overflow: hidden; }
.pb-tpl-thumb svg { display: block; width: 100%; height: 100%; }

/* ── 板块列表 ───────────────────────────────────────────────── */
.pb-blocklist { display: flex; flex-direction: column; gap: 3px; }

.pb-blockitem {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 9px;
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  cursor: pointer;
  font-size: 12.5px;
  background: var(--surface);
  transition: border-color .12s, background-color .12s;
}

.pb-blockitem:hover { background: var(--surface-2); }
.pb-blockitem-active,
.pb-blockitem-active:hover { border-color: var(--accent); background: var(--accent-soft); }
.pb-blockitem-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-blockitem-meta { color: var(--text-faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }

.pb-iconbtn {
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text-faint);
  padding: 2px 6px;
  border-radius: 6px;
  font-size: 13px;
  line-height: 1;
  transition: background-color .12s, color .12s;
}
.pb-iconbtn:hover { background: var(--surface-2); color: var(--text); }
.pb-iconbtn:disabled { opacity: .3; cursor: default; }

/* ── 字体选择 ───────────────────────────────────────────────── */
.pb-fontopt-missing { color: var(--text-faint); }

.pb-hint {
  font-size: 12px;
  color: var(--text-faint);
  line-height: 1.5;
  margin-top: 5px;
}

.pb-warn { color: var(--danger); }

.pb-empty {
  padding: 20px 6px;
  text-align: center;
  color: var(--text-faint);
  font-size: 12.5px;
  line-height: 1.6;
}

.pb-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 550;
  background: var(--surface-2);
  color: var(--text-dim);
  border: none;
}

.pb-badge-published { background: var(--ok-soft); color: var(--ok); }
.pb-badge-dirty { background: #fbf3e2; color: #96731d; }

/* ── 打印提示条 ─────────────────────────────────────────────── */
.pb-hintbar {
  background: #fcf8ee;
  border-bottom: 1px solid #efe6cc;
  padding: 9px 16px;
  font-size: 12.5px;
  color: #7d6425;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.pb-hintbar ul { margin: 4px 0 0; padding-inline-start: 17px; }
.pb-hintbar li { margin: 1px 0; }
.pb-hintbar-body { flex: 1; }
.pb-hintbar strong { font-weight: 600; }

/* ── 展示馆 ─────────────────────────────────────────────────── */
.pb-gallery {
  max-width: 1180px;
  margin: 0 auto;
  padding: 44px 28px 72px;
}

.pb-gallery-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 28px; flex-wrap: wrap; }
.pb-gallery-head h1 { margin: 0; font-size: 27px; font-weight: 700; letter-spacing: -.02em; }
.pb-gallery-head p { margin: 6px 0 0; color: var(--text-dim); font-size: 14px; }
.pb-gallery-tools { margin-inline-start: auto; display: flex; gap: 10px; align-items: center; }
.pb-gallery-search { width: 220px; }

.pb-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(226px, 1fr));
  gap: 22px;
}

/* 卡片无边框：白面 + 浮起投影就够了。边框是第三种「说同一件事」的方式 */
.pb-card {
  background: var(--surface);
  border: none;
  border-radius: var(--r-card);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
  display: flex;
  flex-direction: column;
  transition: box-shadow .18s;
}
.pb-card:hover { box-shadow: var(--shadow-paper); }

.pb-card-thumb {
  height: 262px;
  background: var(--bg-deep);
  overflow: hidden;
  position: relative;
}

/* 缩略图里的画布不参与 flex 布局：纸张按原尺寸渲染，只在最外层缩放，
   这样缩略图和打印出来的是同一次排版结果。left 由脚本按缩放后宽度算出来。 */
.pb-card-thumb .pb-canvas {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  gap: 0;
  transform-origin: top left;
}

.pb-card-body { padding: 13px 15px 15px; display: flex; flex-direction: column; gap: 8px; }
.pb-card-name { font-size: 14.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-card-meta { font-size: 11.5px; color: var(--text-faint); display: flex; gap: 9px; flex-wrap: wrap; font-variant-numeric: tabular-nums; }
/* 按钮必须能换行：英文的 Duplicate 放得下，德语的 Duplizieren、
   皮钦语的 Make copy、泰米尔语的长词都放不下，不换行就被挤出卡片外。
   三十种语言里，"英文刚好放得下" 是最不可靠的假设。 */
.pb-card-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }

.pb-stat { color: var(--text-faint); font-size: 12.5px; font-variant-numeric: tabular-nums; }

/* ── 提示条 ─────────────────────────────────────────────────── */
.pb-toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translate(-50%, 14px);
  background: #1a1a1e;
  color: #fff;
  padding: 10px 20px;
  border-radius: var(--r-pill);
  font-size: 13px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s, transform .16s;
  z-index: 60;
  box-shadow: var(--shadow-float);
  max-width: 78vw;
}

.pb-toast-show { opacity: 1; transform: translate(-50%, 0); }
.pb-toast[data-kind='error'] { background: var(--danger); }
.pb-toast[data-kind='ok'] { background: var(--ok); }

/* ── 打印预览页（隐藏外壳，只留纸） ─────────────────────────── */
.pb-printonly { display: none; }

/* ── 动物园画廊：挑一张直接打印 ──────────────────────────────
   这一页刻意做成「一屏能看懂」：一个体型选择 + 两个风格标签 + 一排成品。
   手机上就是从上往下滚，不需要任何面板或抽屉。
   版式居中：这是产品的门面页，海报店的气质，不是工作台。 */

.pb-page-scroll {
  height: calc(100vh - var(--nav-h));
  height: calc(100dvh - var(--nav-h));
  overflow-y: auto;
}

.zoo-shop { max-width: 1220px; margin: 0 auto; padding: 52px 24px 72px; }

.zoo-shop-head { text-align: center; }
.zoo-shop-head h1 { margin: 0; font-size: 34px; font-weight: 700; letter-spacing: -.02em; }
.zoo-shop-head p { margin: 8px 0 0; color: var(--text-dim); font-size: 15px; }

/* 一行固定 3 列（用户裁定），间距收紧——图与图之间不要大片空白 */
.zoo-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

/* 动物卡片：纸是主角。发丝边 + 一线投影的组件库式卡面 */
.zoo-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(17, 17, 20, .04);
  display: flex;
  flex-direction: column;
  transition: box-shadow .18s, border-color .18s;
}
.zoo-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-lift); }

/* 缩略图区：深半档的台面上摆一张 A4 纸。
   白底满铺的图看不出「这是一张纸」，也就看不出动物在 A4 上占多大、留多少白。 */
.zoo-card-thumb {
  background: var(--bg-deep);
  border-bottom: none;
  padding: 8px;
  display: flex;
  justify-content: center;
}

.zoo-card-sheet {
  position: relative;
  width: 100%;
  /* A4 的比例写死在这儿：画布不管多少像素，框始终是 210:297 */
  aspect-ratio: 210 / 297;
  background: #fff;
  border: none;
  border-radius: 2px;
  box-shadow: 0 1px 2px rgba(17, 17, 20, .10), 0 4px 14px rgba(17, 17, 20, .10);
  line-height: 0;
}

.zoo-card-sheet img {
  width: 100%;
  height: 100%;
  object-fit: contain;   /* 原图略窄于 A4，contain 摆放，两侧留一线白 */
  display: block;
}

.zoo-card-a4 {
  position: absolute;
  top: 6px;
  inset-inline-end: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(26, 26, 30, .5);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: .04em;
}

.zoo-card-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 8px; }
.zoo-card-name { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }

/* 摄影师署名。压得很轻，但必须在——用的是别人的照片 */
.zoo-card-credit {
  font-size: 11px;
  color: var(--text-faint);
  text-decoration: none;
  margin-top: -5px;
}
.zoo-card-credit:hover { text-decoration: underline; }
.zoo-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.zoo-card-actions .pb-btn-primary { flex: 1 1 auto; }

/* 「自己调」是第三入口，不跟前两个按钮抢注意力，做成安静的文字链 */
.zoo-card-link {
  margin-inline-start: 3px;
  font-size: 13px;
  color: var(--text-dim);
  text-decoration: none;
  white-space: nowrap;
  transition: color .12s;
}
.zoo-card-link:hover { color: var(--accent); }

.zoo-bulk {
  margin-top: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* ══ 手机与小平板 ══════════════════════════════════════════════
   桌面是三栏。手机上三栏并排必然失败：393px 塞不下两个 300px 的侧栏。
   之前的做法是把左栏 display:none —— 那不是适配，那是砍掉一半功能
   （手机上连动物都选不了）。现在改成：画布占主位，左右栏变成
   从底部滑出的面板，由底部标签栏切换。页面 HTML 一个字都不用改。 */

/* 桌面上这三样不存在 */
.pb-sheet-head,
.pb-tabbar,
.pb-dock-trigger,
.pb-scrim { display: none; }

@media (max-width: 900px) {
  :root {
    --nav-h: 48px;
    --tabbar-h: 56px;
  }

  /* dvh 让地址栏收起/展开时高度跟着变，100vh 在手机浏览器上会算多一截 */
  .pb-shell {
    flex-direction: column;
    height: calc(100vh - var(--nav-h));
    height: calc(100dvh - var(--nav-h));
  }

  .pb-main {
    flex: 1;
    min-height: 0;
    padding-bottom: var(--tabbar-h);
  }

  /* ── 侧栏 → 底部面板 ───────────────────────────────── */
  /* 挂在 .pb-sheet 上而不是点名某两栏：mobile.js 给每块面板都加这个类，
     加页面时只传一组面板声明，样式一行都不用动 */
  .pb-sheet {
    position: fixed;
    inset-inline: 0;
    /* 面板落在底部导航之上。标签栏是固定高度，dock 的高度由文案长短决定，
       所以用 --dock-h（由 JS 实测后写入），没有 dock 的页面退回标签栏高度 */
    bottom: var(--dock-h, var(--tabbar-h));
    width: auto;
    flex-basis: auto;
    max-height: 62vh;
    max-height: 62dvh;
    border: none;
    border-top: 1px solid var(--border);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -10px 32px rgba(17, 17, 20, .16);
    transform: translateY(110%);
    visibility: hidden;
    transition: transform .22s ease, visibility .22s;
    z-index: 40;
  }

  .pb-sheet-open {
    transform: translateY(0);
    visibility: visible;
  }

  .pb-sheet-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px 10px;
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    background: var(--surface);
    z-index: 1;
  }

  .pb-sheet-grip {
    position: absolute;
    top: 5px;
    inset-inline: 0;
    margin: 0 auto;
    width: 34px;
    height: 4px;
    border-radius: 2px;
    background: var(--border-strong);
  }

  .pb-sheet-title { font-weight: 650; font-size: 14px; flex: 1; }
  .pb-sheet-close { padding: 4px 12px; }

  /* 点画布区域收起面板 */
  .pb-scrim {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(17, 17, 20, .22);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
    z-index: 30;
  }
  body[data-sheet] .pb-scrim { opacity: 1; pointer-events: auto; }


  /* ── 底部常驻导航（画廊）────────────────────────────
     形状：一行说明 +（设置按钮 | 可横滑的切换条）。
     和上面那套标签栏的分工：标签栏是「一个标签 = 一块设置面板」，
     dock 是「切一下，上面的内容立刻就换」——画廊的主动作是后者。 */
  .pb-dock {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 50;
    background: rgba(255, 255, 255, .92);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 20px rgba(17, 17, 20, .08);
    padding-bottom: env(safe-area-inset-bottom);
  }

  .pb-dock-hint {
    margin: 0;
    padding: 8px 14px 0;
    font-size: 12px;
    line-height: 1.35;
    color: var(--text-faint);
    /* 说明最多两行：再长就把切换条挤下去了 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .pb-dock-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px 10px;
  }

  .pb-dock-trigger {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    flex: 0 1 auto;
    min-width: 0;
    /* 长文案语言里这颗按钮会很宽，得给切换条留下大半条 */
    max-width: 46%;
  }
  .pb-dock-trigger-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .pb-dock-trigger-val { flex: 0 0 auto; font-variant-numeric: tabular-nums; }

  /* 要横滑就滑这一条——它里面装的是真内容。
     原先是五个标签平铺 flex:1，窄屏或长文案语言下会把整个页面撑宽，
     于是页面能左右滑，滑出来的却是一片空白。 */
  .pb-dock-strip {
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .pb-dock-strip::-webkit-scrollbar { display: none; }
  .pb-dock-strip > * { flex: 0 0 auto; }

  /* 右缘淡出：告诉人这条还能往右滑。没有它，被切掉半个的标签
     看起来更像布局坏了，而不是「后面还有」 */
  .pb-dock-row { position: relative; }
  .pb-dock-row::after {
    content: '';
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    width: 26px;
    pointer-events: none;
    background: linear-gradient(to left, rgba(255, 255, 255, .95), transparent);
  }

  /* 最后一排卡片不能被 dock 压住 */
  .pb-has-dock .pb-page-scroll { padding-bottom: calc(var(--dock-h, 96px) + 14px); }

  /* ── 底部标签栏 ────────────────────────────────────── */
  .pb-tabbar {
    display: flex;
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    height: var(--tabbar-h);
    background: rgba(255, 255, 255, .92);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-top: 1px solid var(--border);
    z-index: 50;
    /* iPhone 底部横条不要压住按钮 */
    padding-bottom: env(safe-area-inset-bottom);
    box-sizing: content-box;
  }

  .pb-tab {
    flex: 1;
    border: none;
    background: transparent;
    color: var(--text-dim);
    font-size: 13px;
    font-weight: 550;
    cursor: pointer;
    padding: 0 6px;
    /* 触摸目标要够大：这里整块都是 56px 高 */
    min-height: var(--tabbar-h);
    transition: color .12s;
  }

  .pb-tab-active { color: var(--text); font-weight: 650; background: transparent; }

  /* ── 导航条压缩到一行 ──────────────────────────────── */
  .pb-nav { gap: 8px; padding: 0 12px; }
  .pb-nav-brand { font-size: 14px; }
  .pb-nav-link { padding: 5px 9px; font-size: 13px; }
  .pb-nav-lang-label { display: none; }
  .pb-nav-lang { max-width: 108px; }

  /* ── 工具条：一行横滑，不换行吃掉画布高度 ──────────── */
  .pb-toolbar {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 7px 12px;
  }
  /* 横滑的前提是里面的东西不许被压扁：不写这条，
     「头洞 12.0 × 10.8 厘米」会被挤成一根竖着排的窄条 */
  .pb-toolbar > * { flex: 0 0 auto; }
  .pb-toolbar .pb-badge,
  .pb-toolbar .pb-btn { white-space: nowrap; }
  .pb-toolbar::-webkit-scrollbar { display: none; }
  .pb-toolbar-spacer { flex: 0 0 4px; }

  .pb-hintbar { padding: 7px 12px; font-size: 12px; }
  .pb-hintbar ul { padding-inline-start: 15px; }

  .pb-canvas-wrap { padding: 12px; }

  /* ── 展示馆 ────────────────────────────────────────── */
  .pb-gallery { padding: 24px 14px 44px; }
  .pb-gallery-head { gap: 10px; margin-bottom: 18px; }
  .pb-gallery-head h1 { font-size: 22px; }
  .pb-gallery-tools { margin-inline-start: 0; width: 100%; }
  .pb-gallery-search { flex: 1; width: auto; }
  .pb-cards { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
  .pb-card-thumb { height: 190px; }

  /* ── 动物园画廊 ────────────────────────────────────── */
  .zoo-shop { padding: 26px 14px 48px; }
  .zoo-shop-head h1 { font-size: 24px; }
  .zoo-cards { grid-template-columns: 1fr 1fr; gap: 14px; }
  .zoo-card-thumb { padding: 10px 10px 8px; }
  .zoo-card-name { font-size: 13.5px; }
  /* basis 保持 auto：basis 0 会让折行判定认为「都装得下」，
     按钮被压到最小宽后从卡片右侧溢出（overflow:hidden 再把它吃掉半个） */
  .zoo-card-actions .pb-btn { flex: 1 1 auto; justify-content: center; padding: 7px 12px; }
  .zoo-bulk { margin-top: 26px; }

}

/* 很窄的屏（iPhone SE 一类）再省一点 */
@media (max-width: 400px) {
  .pb-nav-brand { display: none; }
  .pb-cards { grid-template-columns: 1fr 1fr; }
}

/* 打印容器里的纸不要屏幕上的阴影 */
#zoo-print-root .pb-page { box-shadow: none; }

/* ── 从右往左的语言（阿拉伯语 / 埃及阿拉伯语 / 乌尔都语 / 西旁遮普语 / 波斯语） ──
   界面用逻辑属性写，设了 dir 就会自己镜像；下面几处是不该跟着翻的例外。 */

/* 纸张是物理排版：A4 的左边永远是左边，不随界面语言镜像。
   打印出来的东西跟界面书写方向无关。 */
[dir="rtl"] .pb-page,
[dir="rtl"] .pb-canvas,
[dir="rtl"] .pb-card-thumb {
  direction: ltr;
}

/* 纯数字读数（100% / 0° / 1.90）在 RTL 里仍按从左到右读。
   只作用于 .pb-value——徽章里有整句译文，强制 LTR 会把阿拉伯语的词序打乱。 */
[dir="rtl"] .pb-value {
  direction: ltr;
  text-align: start;
}

/* 滑块在 RTL 下应从右侧起算，否则拖动方向和视觉相反 */
[dir="rtl"] .pb-range {
  direction: rtl;
}
