/* ==========================================================================
   慢慢抠图 · GIF 工具箱 共享样式
   排版布局 1:1 复刻 gif-master.com/zh/tools，配色替换为本站品牌色。
   品牌色（来自 style.css / App.tsx）：
     --brand-1 #0062ff   主蓝
     --brand-2 #2f7bff   亮蓝（gif-master 的 --brand-2 角色）
     --brand-3 #38bdf8   天蓝
   ========================================================================== */

/* ---------- 0. 设计令牌（HSL 以适配 gif-master 的 hsl(var(--x))/alpha 写法） ---------- */
:root {
  /* 本站品牌色（色相/饱和/亮度） */
  --brand-1: 217 100% 50%;   /* #0062ff */
  --brand-2: 218 100% 59%;   /* #2f7bff */
  --brand-3: 199 89% 60%;    /* #38bdf8 */

  /* gif-master 的基础令牌（浅色主题） */
  --background: 0 0% 100%;
  --foreground: 0 0% 3.9%;
  --card: 0 0% 100%;
  --card-foreground: 0 0% 3.9%;
  --popover: 0 0% 100%;
  --popover-foreground: 0 0% 3.9%;
  --primary: 217 100% 50%;
  --primary-foreground: 0 0% 100%;
  --secondary: 214 32% 96%;
  --secondary-foreground: 217 100% 40%;
  --muted: 210 40% 96.1%;
  --muted-foreground: 215 16% 45%;
  --accent: 213 100% 97%;
  --accent-foreground: 217 100% 42%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 0 0% 98%;
  --border: 214 25% 89.8%;
  --input: 214 25% 89.8%;
  --ring: 217 100% 50%;
  --radius: 0.5rem;

  /* 速度曲线与阴影 */
  --shadow-card: 0 20px 60px rgba(15, 23, 42, 0.08);
  --shadow-panel: 0 12px 32px rgba(15, 23, 42, 0.06);
  --shadow-pop: 0 20px 60px rgba(15, 23, 42, 0.18);
  --shadow-soft: 0 14px 34px rgba(15, 23, 42, 0.10);
}

/* ---------- 1. Reset / 基础 ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
    Roboto, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  min-height: 100vh;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
/* ★ 关键：清除浏览器默认按钮边框。
   Chromium/Edge 对 <button> 的 UA 样式是 `border: 2px outset ButtonBorder`，
   在浅色主题下渲染成 2px 实心黑/深灰边。本站所有按钮的观感（胶囊/渐变/幽灵）
   都由类自己定义，因此这里统一归零 —— 否则 .btn-primary / .btn-grad 这类
   「只写背景不写边框」的蓝色按钮会顶着一圈黑边，与设计稿不符。
   （输入框等非 button 元素不受影响；需要边框的按钮类自行声明即可。）
   ★ 不用 `border: none` 而用 `border: 0` + 显式 outline 归零，避免某些引擎
   把 outset 关键字残留在 border-style 上。 */
button {
  font-family: inherit;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}
button:focus-visible { outline: 2px solid hsl(var(--brand-1)); outline-offset: 2px; }
img, svg, video, canvas { display: block; max-width: 100%; }
table { border-collapse: collapse; }

::selection { background: hsl(var(--brand-2) / 0.18); }

/* 滚动条（对齐 gif-master） */
* { scrollbar-color: hsl(0 0% 45.1%) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: hsl(0 0% 45.1%); border-radius: 999px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: hsl(0 0% 25%); background-clip: content-box; }

.text-mobile-safe { overflow-wrap: anywhere; word-break: break-word; }
/* ★ 第 22 轮：视觉隐藏但保留给读屏软件（搜索框放大镜的 label 文案需要它） */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* ---------- 2. 顶部导航 → 已抽成全站共享组件 ---------- */
/* ★ 第 7 轮重构：原先这里维护的 .site-header / .site-nav / .nav-drop / .mobile-menu
   已全部废弃，改为加载 /global-header.js（window.MMHeader）——全站唯一导航数据源。
   Header 样式由该组件自带（.mmh / .mmh-* 前缀），本文件不再重复定义。
   变更：废弃「工具」下拉 → 4 个主入口铺平；Logo 去「· GIF工具箱」后缀；
   右侧移除「隐私安全 · 本地处理」，只保留全局额度。 */

/* ---------- 2.1 GIF 工具页二级工具条（SubToolbar）---------- */
/* Header 只放 4 个主入口后，18 个 GIF 工具的入口在此横向铺开，避免工具页孤立。 */
.gif-sub {
  position: sticky; top: 60px; z-index: 90;
  border-bottom: 1px solid hsl(var(--border) / 0.7);
  background: hsl(var(--background) / 0.9);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
}
.gif-sub-inner {
  margin: 0 auto; max-width: 80rem; padding: 0.625rem 1rem;
  display: flex; align-items: center; gap: 0.625rem; min-width: 0;
}
@media (min-width: 640px) { .gif-sub-inner { padding: 0.625rem 1.5rem; } }
.gif-sub-label {
  flex-shrink: 0; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: hsl(var(--muted-foreground));
}
.gif-sub-links {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 0.25rem;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -ms-overflow-style: none;
}
.gif-sub-links::-webkit-scrollbar { display: none; }
.gif-sub-link {
  flex-shrink: 0; border-radius: 999px; padding: 0.3125rem 0.6875rem;
  font-size: 0.8125rem; font-weight: 500; white-space: nowrap;
  color: hsl(var(--muted-foreground));
  transition: color .15s, background-color .15s;
}
.gif-sub-link:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.gif-sub-link.is-on {
  background: hsl(var(--brand-2) / 0.12); color: hsl(var(--brand-1)); font-weight: 600;
}
.gif-sub-all {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 0.25rem;
  border-radius: 999px; padding: 0.3125rem 0.75rem;
  font-size: 0.8125rem; font-weight: 600; color: hsl(var(--brand-2));
  border: 1px solid hsl(var(--brand-2) / 0.35);
  transition: background-color .15s, border-color .15s;
}
.gif-sub-all:hover { background: hsl(var(--brand-2) / 0.1); border-color: hsl(var(--brand-2) / 0.6); }
.gif-sub-all svg { height: 0.875rem; width: 0.875rem; }
@media (max-width: 640px) { .gif-sub-label { display: none; } .gif-sub { top: 60px; } }

.wrap { margin: 0 auto; max-width: 80rem; padding-left: 1rem; padding-right: 1rem; }
@media (min-width: 640px) { .wrap { padding-left: 1.5rem; padding-right: 1.5rem; } }

.eyebrow {
  font-size: 0.875rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.24em;
  color: hsl(var(--brand-2));
}
.h1 { font-size: 1.5rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.2; text-wrap: balance; }
@media (min-width: 640px) { .h1 { font-size: 2.25rem; } }
.h2 { font-size: 1.5rem; font-weight: 600; letter-spacing: -0.01em; }
@media (min-width: 640px) { .h2 { font-size: 1.875rem; } }
.h3 { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.01em; }
.lead { font-size: 1rem; line-height: 1.75rem; color: hsl(var(--muted-foreground)); }
@media (min-width: 640px) { .lead { font-size: 1.125rem; line-height: 2rem; } }
.muted { color: hsl(var(--muted-foreground)); }
.small { font-size: 0.875rem; line-height: 1.75rem; }

/* ---------- 4. 按钮体系 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  white-space: nowrap; font-size: 0.875rem; font-weight: 500;
  border: 0; border-radius: 0.375rem; cursor: pointer;
  transition: background-color .15s, color .15s, border-color .15s, opacity .15s;
}
.btn:disabled, .btn.disabled { opacity: 0.5; pointer-events: none; }
.btn svg { height: 1rem; width: 1rem; }
/* ★ 变体类可单独使用（结果卡下载按钮曾只有 .btn-primary → display:block + 可换行 + 可收缩，
   内容挤到第二行溢出固定高度胶囊外 →「下载」两字掉到按钮下面）。统一给全部变体兜底： */
.btn, .btn-primary, .btn-ghost, .btn-quiet, .btn-danger, .btn-grad, .btn-stop, .btn-icon {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem;
  white-space: nowrap; flex-shrink: 0;
}
.btn svg, .btn-primary svg, .btn-ghost svg, .btn-quiet svg, .btn-danger svg, .btn-grad svg, .btn-stop svg, .btn-icon svg {
  height: 1rem; width: 1rem; flex-shrink: 0;
}

/* ★ 蓝色实心 / 渐变蓝按钮：显式声明不带边框。
   即使某个页面漏了上面的 button 重置，也不会再出现浏览器默认黑边。 */
.btn-primary { height: 2.25rem; padding: 0.5rem 1.5rem; border: 0; border-radius: 999px; background: hsl(var(--brand-1)); color: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.05); }
.btn-primary:hover { background: hsl(var(--brand-1) / 0.9); }
.btn-ghost { height: 2.25rem; padding: 0.5rem 1.25rem; border-radius: 999px; border: 1px solid hsl(var(--border) / 0.7); background: hsl(var(--background) / 0.85); color: hsl(var(--brand-2)); }
.btn-ghost:hover { border-color: hsl(var(--brand-2) / 0.4); }
.btn-quiet { height: 2.25rem; padding: 0.5rem 1rem; border-radius: 999px; background: transparent; color: hsl(var(--muted-foreground)); }
.btn-quiet:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.btn-danger { height: 2.25rem; padding: 0.5rem 1.25rem; border: 0; border-radius: 999px; background: hsl(var(--destructive)); color: #fff; }
.btn-danger:hover { opacity: .9; }
.btn-sm { height: 1.9rem; padding: 0.25rem 0.9rem; font-size: 0.8125rem; border-radius: 999px; }
.btn-icon { height: 2.25rem; width: 2.25rem; padding: 0; border: 0; border-radius: 0.375rem; background: transparent; color: hsl(var(--muted-foreground)); }
.btn-icon:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
.btn-grad {
  height: 2.5rem; padding: 0.6rem 1.6rem; border: 0; border-radius: 999px; color: #fff; font-weight: 600;
  background: linear-gradient(135deg, #0062ff 0%, #2f7bff 45%, #38bdf8 100%);
  box-shadow: 0 10px 26px -10px rgba(0, 98, 255, 0.7);
}
.btn-grad:hover { filter: brightness(1.06); }

/* ---------- 5. 首页：hero ---------- */
.page-main { padding-top: 3rem; padding-bottom: 3rem; }
@media (min-width: 640px) { .page-main { padding-top: 6rem; padding-bottom: 6rem; } }
.hero-block { max-width: 48rem; display: flex; flex-direction: column; gap: 1rem; }

/* ---------- 6. 首页：工具搜索 + 分类过滤 Tab（原 pill 云已下线） ---------- */
/* 6.1 过滤工具条：★ 左「分类 Tabs」右「搜索框」（SaaS 标准布局，搜索贴最右）。
   窄屏纵向堆叠（Tabs 在上），≥768px 两端对齐一行。
   间距节奏：与上方 lead、下方「共 N 个工具」计数行各留 ~1.75rem。 */
.tool-toolbar {
  display: flex; flex-direction: column; gap: 1rem;
  margin-top: 1.75rem;
  margin-bottom: 2rem;
}
@media (min-width: 768px) {
  .tool-toolbar { flex-direction: row; align-items: center; justify-content: space-between; gap: 1.25rem; }
}

/* 搜索框 —— ★ 第 22 轮重构：单层边框（消除双层框/重影）。
   设计契约（严格遵循「外层统管 + 内层剥离」）：
     · .tool-search       外层容器「独占」全部可见样式：
                         物理边框 1px、圆角 999px、背景、hover 描边、focus-within 描边 + 光圈。
                         全局表单族 `input[type="search"]` 的 border/radius/bg 绝不作用于它（它是 div）。
     · .ts-input          内层原生 input「绝对干净」：border/outline/box-shadow/background 全部归零，
                         **且必须显式覆盖 :focus 态** —— 否则全局
                         `input[type="search"]:focus { border-color; box-shadow: 0 0 0 3px }`
                         （特异性 0,2,1）会压过旧版 `.tool-search input`（0,1,1），
                         与外层 .tool-search:focus-within 的 4px 光圈叠加成"重影"。
     · .ts-icon           放大镜：label 只做无障碍关联，视觉是纯 flex 子项，无边框无背景。
   ★ 内层选择器一律写成 `.ts-input` / `input.ts-input` / `input.ts-input:focus(:focus-visible)`，
     特异性 ≥ (0,2,0)，全程 ≥ 全局表单族，杜绝任何顺序依赖。 */
.tool-search {
  display: flex; align-items: center;
  width: 100%;
  padding: 0 1rem;
  border: 1px solid hsl(var(--border) / 0.8);
  border-radius: 999px;
  background: hsl(var(--background) / 0.9);
  transition: border-color .18s, box-shadow .18s, background-color .18s;
}
@media (min-width: 768px) { .tool-search { width: 24rem; max-width: 24rem; margin-left: auto; flex-shrink: 0; } }
.tool-search:hover { border-color: hsl(var(--border)); }
.tool-search:focus-within {
  border-color: hsl(var(--brand-2) / 0.6);
  box-shadow: 0 0 0 4px hsl(var(--brand-2) / 0.12);
}

/* 放大镜：label 只做关联，不承载视觉 */
.tool-search > .ts-icon {
  display: flex; align-items: center; flex-shrink: 0;
  color: hsl(var(--muted-foreground));
  cursor: text;
}
.tool-search > .ts-icon > svg { height: 1.125rem; width: 1.125rem; }

/* ★ 内层输入框：彻底剥离 —— 含 :focus / :focus-visible / placeholder 全态归零 */
input.ts-input,
.tool-search input.ts-input {
  flex: 1 1 auto;
  width: auto; min-width: 0;
  border: 0 none transparent;
  border-radius: 0;
  outline: 0 none;
  box-shadow: none;
  background: transparent;
  -webkit-appearance: none; appearance: none;
  padding: 0.75rem 0 0.75rem 0.625rem;
  font-size: 0.9375rem; font-family: inherit; line-height: 1.5;
  color: hsl(var(--foreground));
}
input.ts-input:focus,
input.ts-input:focus-visible,
.tool-search input.ts-input:focus,
.tool-search input.ts-input:focus-visible {
  border: 0 none transparent;
  outline: 0 none;
  box-shadow: none;
  background: transparent;
}
input.ts-input::placeholder { color: hsl(var(--muted-foreground)); opacity: 1; }
/* 隐藏原生 search 清除钮（避免与自定义 .ts-clear 出现两个 ×） */
input.ts-input::-webkit-search-cancel-button,
input.ts-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }

/* 清除按钮：有内容时才显示（由 JS 切 .is-on） */
.tool-search .ts-clear {
  display: none; flex-shrink: 0;
  height: 1.5rem; width: 1.5rem; align-items: center; justify-content: center;
  border: 0; border-radius: 999px; background: hsl(var(--muted) / 0.7);
  color: hsl(var(--muted-foreground)); cursor: pointer;
  transition: background-color .15s, color .15s;
}
.tool-search .ts-clear.is-on { display: inline-flex; }
.tool-search .ts-clear:hover { background: hsl(var(--brand-2) / 0.15); color: hsl(var(--brand-2)); }
.tool-search .ts-clear svg { height: 0.875rem; width: 0.875rem; }

/* 分类 Tab：胶囊组，选中态用主题渐变实心 */
.tool-tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.tool-tab {
  display: inline-flex; align-items: center; gap: 0.375rem;
  border: 1px solid hsl(var(--border) / 0.8);
  border-radius: 999px;
  background: hsl(var(--background) / 0.9);
  padding: 0.5rem 1.125rem;
  font-size: 0.875rem; font-weight: 500; line-height: 1.25rem;
  color: hsl(var(--muted-foreground));
  cursor: pointer;
  transition: color .18s, border-color .18s, background-color .18s, box-shadow .18s, transform .18s;
}
.tool-tab:hover { border-color: hsl(var(--brand-2) / 0.45); color: hsl(var(--brand-2)); }
.tool-tab.is-on {
  border-color: transparent;
  background: linear-gradient(135deg, hsl(var(--brand-1)) 0%, hsl(var(--brand-2)) 55%, hsl(var(--brand-3)) 100%);
  color: #fff; font-weight: 600;
  box-shadow: 0 8px 20px -10px hsl(var(--brand-1) / 0.85);
}
.tool-tab .tt-n {
  font-size: 0.75rem; font-weight: 600; line-height: 1;
  padding: 0.1875rem 0.375rem; border-radius: 999px;
  background: hsl(var(--foreground) / 0.06); color: inherit;
}
.tool-tab.is-on .tt-n { background: rgba(255, 255, 255, 0.22); }

/* 过滤结果计数 + 空状态 */
.tool-meta {
  margin: -0.75rem 0 1.5rem;
  font-size: 0.8125rem; line-height: 1.5rem;
  color: hsl(var(--muted-foreground));
}
.tool-empty {
  padding: 3.5rem 1.5rem; text-align: center;
  border: 1px dashed hsl(var(--border));
  border-radius: 1.5rem;
  background: hsl(var(--muted) / 0.35);
  color: hsl(var(--muted-foreground));
  font-size: 0.9375rem; line-height: 1.75rem;
}
.tool-empty strong { display: block; margin-bottom: 0.375rem; font-size: 1.0625rem; color: hsl(var(--foreground)); }

/* ---------- 7. 首页：工具卡片网格（极简版） ---------- */
.tool-grid { display: grid; gap: 1rem; }
@media (min-width: 640px) { .tool-grid { gap: 1.25rem; } }
@media (min-width: 768px) { .tool-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .tool-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* 卡片：三层 Flexbox 结构（★ 严禁绝对定位，文字区与按钮区物理隔离）
   ① .tool-card  垂直弹性盒 + height:100%，在网格中撑满整行高度；
                 min-height 兜底：无论描述 1 行还是 2 行，初始高度完全一致。
   ② .tc-body    flex:1 内容区，自动吃掉所有剩余空间，把按钮"顶"到最底部
   ③ .tc-foot    margin-top:auto 底部按钮区，处于内容区之外（下方），
                 ★ 永久保留物理高度，显隐只用 opacity/pointer-events 控制
                 （第 18c 轮用户规范：禁止 hover 撑高——那会拉伸整排卡片）。
   hover 另有 Y 轴上浮 + 阴影加深 + 标题变主题色 + 按钮浮现。 */
.tool-card {
  position: relative; display: flex; flex-direction: column;
  height: 100%;
  min-height: 15rem; /* ★ 物理占位兜底：初始态所有卡片等高（实测自然高≈236px） */
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.25rem;
  background: hsl(var(--card));
  padding: 1.5rem;
  color: inherit; text-decoration: none; overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: transform .28s cubic-bezier(.2, .7, .3, 1), box-shadow .28s, border-color .28s, background-color .28s;
}
@media (min-width: 640px) { .tool-card { border-radius: 1.5rem; padding: 1.75rem; } }
.tool-card::after { /* hover 时从左上角透出的极淡主题光晕，降噪但不寡淡 */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 90% at 0% 0%, hsl(var(--brand-2) / 0.10), transparent 60%);
  opacity: 0; transition: opacity .28s;
}

/* ② 内容区：图标 + 标题 + 描述。flex:1 让它占满所有剩余空间（关键！） */
.tc-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex; flex-direction: column;
}
.tool-card:hover, .tool-card:focus-visible {
  transform: translateY(-4px);
  border-color: hsl(var(--brand-2) / 0.4);
  /* ★ 必须在「模糊半径」和「不透明度」两个维度同时超过基础 token（0 20px 60px /.08），
     否则 hover 反而显得更平——升力由 双层投影 + 更大 blur + 更高 alpha 共同表达。 */
  box-shadow:
    0 28px 68px -16px rgba(15, 23, 42, 0.22),
    0 10px 24px -10px rgba(15, 23, 42, 0.12);
}
.tool-card:hover::after, .tool-card:focus-visible::after { opacity: 1; }
.tool-card:focus-visible { outline: 2px solid hsl(var(--brand-2) / 0.55); outline-offset: 2px; }
.tool-card:active { transform: translateY(-1px); }

/* 主题色图标块：每个工具一个品牌色渐变底，图标为白色描边 SVG */
.tc-ico {
  display: inline-flex; align-items: center; justify-content: center;
  height: 3rem; width: 3rem;
  border-radius: 1rem;
  color: #fff;
  background: linear-gradient(135deg, hsl(var(--brand-1)) 0%, hsl(var(--brand-2)) 60%, hsl(var(--brand-3)) 100%);
  box-shadow: 0 10px 22px -12px hsl(var(--brand-1) / 0.9);
  transition: transform .28s cubic-bezier(.2, .7, .3, 1), box-shadow .28s;
}
.tc-ico svg { height: 1.5rem; width: 1.5rem; }
.tool-card:hover .tc-ico, .tool-card:focus-visible .tc-ico {
  transform: scale(1.06) rotate(-3deg);
  box-shadow: 0 14px 28px -12px hsl(var(--brand-1) / 1);
}
/* 图标色相微调：不同工具用不同主题色阶，避免整页同色（-a 主蓝 / -b 青 / -c 深蓝） */
.tc-ico.tc-c-b { background: linear-gradient(135deg, hsl(var(--brand-2)) 0%, hsl(var(--brand-3)) 100%); box-shadow: 0 10px 22px -12px hsl(var(--brand-2) / 0.9); }
.tc-ico.tc-c-c { background: linear-gradient(135deg, #0b3fd6 0%, hsl(var(--brand-1)) 55%, hsl(var(--brand-2)) 100%); box-shadow: 0 10px 22px -12px #0b3fd6; }

.tc-title {
  margin-top: 1.125rem;
  font-size: 1.0625rem; font-weight: 700; letter-spacing: -0.01em;
  color: hsl(var(--foreground));
  transition: color .2s;
}
@media (min-width: 640px) { .tc-title { font-size: 1.125rem; } }
.tool-card:hover .tc-title, .tool-card:focus-visible .tc-title { color: hsl(var(--brand-2)); }

/* 描述：最多两行，超出省略（line-clamp 防过长，卡片高度由网格行高统一） */
.tc-desc {
  margin-top: 0.5rem;
  font-size: 0.875rem; line-height: 1.5rem;
  color: hsl(var(--muted-foreground));
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ③ 底部专属按钮区：位于 flex-1 内容区之外（下方）
   ★ mt-auto 把它恒定压到卡片最底部；★ 无 position，纯 Flexbox 排布。
   ★★ 第 18c 轮规范（用户指令）：本区域【永久占据物理高度】——
      严禁 hidden / display:none / grid-rows / padding / height 任何会改变占位的显隐手段；
      只允许 opacity + pointer-events 翻转（默认透明不可点，hover 变实可点），
      因此按钮区高度恒定 = padding-top 1rem + 按钮行，任何卡片 hover 时整排纹丝不动。 */
.tc-foot {
  margin-top: auto;
  display: flex; justify-content: flex-end; /* 按钮贴右下角（原 grid+justify-self 随 0fr 方案一并废弃） */
  padding-top: 1rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease;
}
.tool-card:hover .tc-foot,
.tool-card:focus-visible .tc-foot {
  opacity: 1;
  pointer-events: auto;
}

/* 「立即使用 →」：稳态占据 flex 行内空间，绝无 absolute */
.tc-go {
  display: inline-flex; align-items: center; gap: 0.375rem;
  justify-self: end;
  font-size: 0.8125rem; font-weight: 600; line-height: 1;
  color: hsl(var(--brand-2)); white-space: nowrap;
  transform: translateY(4px);
  transition: transform .26s cubic-bezier(.2, .7, .3, 1);
  pointer-events: none;
}
.tc-go svg { height: 0.9375rem; width: 0.9375rem; transition: transform .26s; }
.tool-card:hover .tc-go, .tool-card:focus-visible .tc-go { transform: translateY(0); }
.tool-card:hover .tc-go svg { transform: translateX(3px); }
/* 触屏设备没有 hover：直接常显按钮区（物理高度本就保留，只翻 opacity），避免功能不可见 */
@media (hover: none) {
  .tc-foot { opacity: 1; pointer-events: auto; }
  .tc-go { transform: none; }
  .tool-card::after { opacity: .6; }
}

/* ---------- 8. 首页：步骤 / FAQ ---------- */
.steps-panel {
  margin-top: 3rem;
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.5rem;
  background: hsl(var(--muted) / 0.45);
  padding: 1.5rem; box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
@media (min-width: 640px) { .steps-panel { border-radius: 2rem; padding: 2rem; } }
.steps { margin-top: 1.5rem; display: grid; gap: 1rem; list-style: none; }
@media (min-width: 768px) { .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.steps li {
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.5rem; background: hsl(var(--background) / 0.8);
  padding: 1.25rem; font-size: 0.875rem; line-height: 1.75rem;
  color: hsl(var(--muted-foreground));
}
.step-no {
  margin-bottom: 0.75rem;
  display: inline-flex; height: 2rem; width: 2rem;
  align-items: center; justify-content: center; border-radius: 999px;
  background: hsl(var(--brand-2) / 0.10);
  font-size: 0.875rem; font-weight: 600; color: hsl(var(--brand-2));
}

.faq-sec { margin-top: 3rem; }
.faq-head { max-width: 48rem; margin: 0 auto; text-align: center; display: flex; flex-direction: column; gap: 1rem; }
.faq-list { margin: 2.5rem 0 0; max-width: 100%; display: grid; gap: 1.25rem; }
/* 双列：把原本被压在 56rem 里的窄条 FAQ 铺满内容区（与工作台同宽） */
@media (min-width: 900px) { .faq-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem 1.5rem; } }
.faq-list > .h2 { grid-column: 1 / -1; }
.faq-list details {
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.75rem; background: hsl(var(--card) / 0.8);
  padding: 1.5rem; box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
.faq-list summary {
  cursor: pointer; list-style: none; font-size: 1.125rem;
  font-weight: 600; letter-spacing: -0.01em;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary .chev { height: 1rem; width: 1rem; flex-shrink: 0; transition: transform .2s; }
.faq-list details[open] summary .chev { transform: rotate(180deg); }
.faq-list p { margin-top: 1rem; font-size: 0.875rem; line-height: 1.75rem; color: hsl(var(--muted-foreground)); }

/* ---- 9. 页脚 ----
   ★ 第 25 轮重构（对齐用户 Tailwind 规范）：
     外层 = max-w-[1440px] mx-auto px-6 md:px-10 grid grid-cols-1 md:grid-cols-4 lg:grid-cols-5 gap-8
     品牌区 = col-span-1 md:col-span-2，内部 flex flex-col gap-3 垂直均匀间距。
   原布局 1.4fr + 4×1fr → 品牌列仅占 ~26% 宽，描述/邮箱/署名全部被挤压换行。
   ★ .footer-bottom 与主网格共用 1440px 定宽 + 同款左右 gutter，保证上下两段边缘对齐。 */
.site-footer {
  border-top: 1px solid hsl(var(--border) / 0.7);
  background-image:
    radial-gradient(circle at top left, rgba(0, 98, 255, 0.10), transparent 38%),
    radial-gradient(circle at bottom right, rgba(56, 189, 248, 0.10), transparent 38%);
}
.site-footer-grid {
  margin: 0 auto; max-width: 1440px;
  display: grid; gap: 2rem;
  padding: 3.5rem 1.5rem;
}
@media (min-width: 768px) {
  .site-footer-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    padding-left: 2.5rem; padding-right: 2.5rem;
  }
  .footer-brand { grid-column: span 2; }
}
@media (min-width: 1024px) {
  .site-footer-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
.footer-brand { display: flex; flex-direction: column; gap: 0.75rem; }
.footer-brand-head { display: inline-flex; align-items: center; gap: 0.75rem; font-size: 1.25rem; font-weight: 600; letter-spacing: -0.01em; }
.footer-brand-head .brand-logo { height: 2.5rem; width: 2.5rem; }
.footer-lines { display: flex; flex-direction: column; gap: 0.5rem; font-size: 0.875rem; line-height: 1.75rem; color: hsl(var(--muted-foreground)); }
/* 品牌区内部统一 0.75rem（gap-3）垂直节奏，彻底消除挤压感 */
.footer-brand .footer-lines { gap: 0.75rem; }
.footer-lines a { font-weight: 500; color: hsl(var(--foreground)); transition: color .15s; }
.footer-lines a:hover { color: hsl(var(--brand-2)); }
.footer-col-title {
  font-size: 0.75rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.18em;
  color: hsl(var(--muted-foreground));
  margin-bottom: 0.9rem;
}
.footer-col { display: flex; flex-direction: column; gap: 0.6rem; }
.footer-col a { font-size: 0.875rem; color: hsl(var(--muted-foreground)); transition: color .15s; }
.footer-col a:hover { color: hsl(var(--brand-2)); }
.footer-bottom {
  margin: 0 auto; max-width: 1440px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 0.75rem 1.5rem;
  padding: 1.25rem 1.5rem; font-size: 0.875rem;
  border-top: 1px solid hsl(var(--border) / 0.7);
  color: hsl(var(--muted-foreground));
}
@media (min-width: 768px) {
  .footer-bottom { padding-left: 2.5rem; padding-right: 2.5rem; }
}
.footer-bottom a { display: inline-flex; align-items: center; gap: 0.3rem; }
.footer-bottom a:hover { color: hsl(var(--brand-2)); }

/* ==========================================================================
   10. 工具工作台通用组件（工具页复用）
   ========================================================================== */
.work-wrap { margin: 0 auto; max-width: 80rem; padding: 1.5rem 1rem 4rem; }
@media (min-width: 640px) { .work-wrap { padding: 2.5rem 1.5rem 5rem; } }

.back-link {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: 0.875rem; font-weight: 500; color: hsl(var(--muted-foreground));
  transition: color .15s;
}
.back-link:hover { color: hsl(var(--foreground)); }
.back-link svg { height: 1rem; width: 1rem; }

/* ---- 返回面包屑（.crumb）
   ★ 曾经完全没有样式：箭头只有 14px 且与文字基线错位、整块贴到最左且无点击热区。
   现在做成「胶囊按钮 + 斜杠 + 当前页」，图标用 flex 居中并给固定盒，字号与主站一致。 */
.crumb {
  margin-top: 1.25rem;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem; line-height: 1.25rem;
}
.crumb-back {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.4rem 0.85rem 0.4rem 0.55rem;
  border: 1px solid hsl(var(--border) / 0.9);
  border-radius: 999px;
  background: hsl(var(--background) / 0.85);
  font-size: 0.875rem; font-weight: 600;
  color: hsl(var(--foreground) / 0.85);
  transition: border-color .15s, background-color .15s, color .15s, transform .15s;
}
.crumb-back:hover {
  border-color: hsl(var(--brand-2) / 0.55);
  background: hsl(var(--brand-2) / 0.08);
  color: hsl(var(--brand-1));
  transform: translateX(-2px);
}
/* 图标固定正方形盒 + flex 居中：彻底消除「箭头太小 / 错位」 */
.crumb-ico {
  display: inline-flex; align-items: center; justify-content: center;
  height: 1.5rem; width: 1.5rem; flex-shrink: 0;
  border-radius: 999px;
  background: hsl(var(--brand-2) / 0.12);
  color: hsl(var(--brand-1));
}
.crumb-ico svg { display: block; height: 1rem; width: 1rem; }
.crumb-back:hover .crumb-ico { background: hsl(var(--brand-1)); color: #fff; }
.crumb-sep { color: hsl(var(--muted-foreground) / 0.6); }
.crumb-now {
  font-weight: 600; color: hsl(var(--foreground));
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- 工具页标题区
   ★ 之前 h1 用 2.25rem + max-width:48rem，而下方工作台是全宽（80rem），
   导致「顶部文字框比工作台窄一大截」的视觉断层。现在收紧节奏：
   标题区与工作台同一左边界，行宽用 46rem 约束（阅读舒适），但外层容器全宽。 */
.tool-head { margin-top: 1.25rem; max-width: 100%; }
.tool-head .eyebrow {
  display: inline-flex; align-items: center;
  font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: hsl(var(--brand-2));
}
.tool-head h1, .tool-head .h1 {
  margin-top: 0.6rem;
  font-size: 1.65rem; font-weight: 600; line-height: 1.22; letter-spacing: -0.01em;
  max-width: 46rem;
}
@media (min-width: 640px) { .tool-head h1, .tool-head .h1 { font-size: 2rem; } }
.tool-head .lead {
  margin-top: 0.6rem;
  max-width: 46rem;
  font-size: 0.9375rem; line-height: 1.7rem;
  color: hsl(var(--muted-foreground));
}
@media (min-width: 640px) { .tool-head .lead { font-size: 1rem; line-height: 1.8rem; } }
/* 兼容旧类名（部分页面/工具沿用 head-desc）*/
.tool-head .head-desc { margin-top: 0.6rem; max-width: 46rem; font-size: 0.9375rem; line-height: 1.7rem; color: hsl(var(--muted-foreground)); }
@media (min-width: 640px) { .tool-head .head-desc { font-size: 1rem; line-height: 1.8rem; } }
.privacy-note { margin-top: 1rem; display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: hsl(var(--muted-foreground)); }
.privacy-note svg { height: 1rem; width: 1rem; color: hsl(var(--brand-2)); flex-shrink: 0; }

.cross-cta {
  margin-top: 2rem;
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.5rem;
  background-image: linear-gradient(135deg, rgba(240, 249, 255, 0.9), rgba(255, 255, 255, 0.96));
  padding: 1.25rem; box-shadow: var(--shadow-panel);
}
@media (min-width: 640px) { .cross-cta { padding: 1.5rem; } }
.cross-cta-inner { display: flex; flex-direction: column; gap: 1rem; }
@media (min-width: 768px) { .cross-cta-inner { flex-direction: row; align-items: center; justify-content: space-between; } }
.cross-cta h2 { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.01em; }
.cross-cta p { margin-top: 0.5rem; font-size: 0.875rem; line-height: 1.5rem; color: hsl(var(--muted-foreground)); }
.cross-cta .btn-primary { width: 100%; }
@media (min-width: 768px) { .cross-cta .btn-primary { width: auto; flex-shrink: 0; } }

/* ---- 10.1 工作面板 ---- */
/* ★ align-items 必须是 stretch：center 会把参数表单/舞台缩成内容宽度（窄列 bug） */
.work-panel {
  margin-top: 1.5rem; display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start;
  min-height: 20rem;
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.5rem;
  background: hsl(var(--background) / 0.9);
  padding: 1.5rem; box-shadow: var(--shadow-panel);
}
.work-panel > * { width: 100%; }
@media (min-width: 640px) { .work-panel { min-height: 0; } }
.work-panel.wide { align-items: stretch; justify-content: flex-start; }

/* ---- 10.2 拖拽上传区（第 17 轮升级为全站统一「上传 Hero 组件」）----
   ★ 两段式状态机：upload 态下 JS 给 #gif-work 加 data-step="upload"，
     面板/文件列表/结果区全部隐藏，只有本 Hero 全宽居中。 */
.dropzone {
  display: flex; width: 100%; flex-direction: column; align-items: center; gap: 1rem;
  border: 2px dashed hsl(var(--border));
  border-radius: 1.25rem;
  padding: 2.5rem 1.5rem;
  text-align: center; cursor: pointer;
  transition: border-color .15s, background-color .15s;
}
.dropzone:hover, .dropzone.over { border-color: hsl(var(--brand-2)); background: hsl(var(--brand-2) / 0.04); }
.dropzone-icon {
  display: flex; height: 3.5rem; width: 3.5rem; align-items: center; justify-content: center;
  border-radius: 1rem; background: hsl(var(--brand-2) / 0.10); color: hsl(var(--brand-2));
}
.dropzone-icon svg { height: 1.75rem; width: 1.75rem; }
.dropzone-title { font-size: 1rem; font-weight: 600; }
.dropzone-hint { font-size: 0.8125rem; color: hsl(var(--muted-foreground)); }

/* ---- 10.2b 统一上传 Hero（.dz-hero-upload）----
   浅蓝渐变底 + 大号渐变图标 + tags 胶囊 + 全宽居中 + 统一按钮文案。 */
.dz-hero-upload {
  gap: 1.15rem;
  min-height: 21rem;
  justify-content: center;
  padding: 3.25rem 1.75rem;
  border: 2px dashed hsl(var(--brand-2) / 0.34);
  border-radius: 1.5rem;
  background:
    radial-gradient(120% 90% at 50% 0%, hsl(var(--brand-3) / 0.10), transparent 62%),
    hsl(var(--muted) / 0.45);
  transition: border-color .2s ease, background-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.dz-hero-upload:hover, .dz-hero-upload.over {
  border-color: hsl(var(--brand-2));
  background:
    radial-gradient(120% 90% at 50% 0%, hsl(var(--brand-3) / 0.18), transparent 62%),
    hsl(var(--accent) / 0.55);
  box-shadow: var(--v2g-soft-lg);
}
.dz-hero-upload:active { transform: scale(.995); }
.dzu-ico {
  display: flex; align-items: center; justify-content: center;
  width: 5rem; height: 5rem;
  border-radius: 1.6rem;
  color: #fff;
  background: linear-gradient(135deg, hsl(var(--brand-1)), hsl(var(--brand-3)));
  box-shadow: 0 10px 28px hsl(var(--brand-1) / 0.28);
}
.dzu-ico svg { width: 2.1rem; height: 2.1rem; }
.dzu-main { display: flex; flex-direction: column; gap: 0.45rem; max-width: 34rem; }
.dzu-main b { font-size: 1.2rem; font-weight: 700; letter-spacing: -0.01em; }
.dzu-main span { font-size: 0.875rem; color: hsl(var(--muted-foreground)); }
.dzu-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; }
.dzu-tags i {
  font-style: normal; font-size: 0.6875rem; font-weight: 600;
  padding: 0.2rem 0.6rem; border-radius: 999px;
  background: hsl(var(--background) / 0.85); color: hsl(var(--muted-foreground));
  border: 1px solid hsl(var(--border) / 0.8);
}
.dzu-btn { padding: 0.6rem 1.5rem; border-radius: 999px; font-weight: 700; }
/* file input 恒隐藏（hidden 属性已被 [hidden]{display:none!important} 兜住，再钉一层防御） */
.dz-hero-upload input[type="file"] { display: none !important; }

/* ---- 10.2c 两段式状态机（setStep）----
   #gif-work[data-step="upload"]  → 只留上传 Hero，其余全隐
   #gif-work[data-step="editor"]  → 隐藏上传 Hero，露出操作面板
   用 !important 压过各工具内联 style.display 的既有写法。 */
#gif-work[data-step="upload"] .list-wrap,
#gif-work[data-step="upload"] .panel,
#gif-work[data-step="upload"] .tool-actions { display: none !important; }
#gif-work[data-step="upload"] { justify-content: center; align-items: stretch; }
#gif-work[data-step="editor"] .dz-hero-upload { display: none !important; }
/* 结果区归属：upload 态必须隐藏（shell.result 不在 #gif-work 内，由 JS 同步控制） */
.result-wrap[data-step="upload"] { display: none !important; }

/* ---- 10.2d 可选背景图选择条（第 17 轮 · 例外 3）----
   用于「上传不是入口」的工具（countdown / recorder）：上传 Hero 不进状态机，
   仅在编辑器面板内提供一个可选按钮，不选也能正常出图（走纯色兜底）。
   见 gif-tool.js 的 optionalBgPicker()。 */
.opt-bg {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem;
  margin: 0.25rem 0 1.1rem;
  padding: 0.7rem 0.85rem;
  border: 1px dashed hsl(var(--border));
  border-radius: 0.85rem;
  background: hsl(var(--muted) / 0.35);
}
.opt-bg-btn {
  flex-shrink: 0;
  height: 2rem; padding: 0 0.85rem;
  border: 1px solid hsl(var(--brand-2) / 0.35);
  border-radius: 999px;
  background: hsl(var(--background) / 0.9);
  color: hsl(var(--brand-1));
  font-size: 0.8125rem; font-weight: 600;
  cursor: pointer;
  transition: border-color .15s, background-color .15s;
}
.opt-bg-btn:hover { border-color: hsl(var(--brand-2) / 0.65); background: hsl(var(--brand-2) / 0.08); }
.opt-bg-name {
  flex: 1 1 10rem; min-width: 0;
  font-size: 0.75rem; color: hsl(var(--muted-foreground));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.opt-bg-clear {
  flex-shrink: 0;
  height: 1.85rem; width: 1.85rem; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
/* 可选类工具不显示上传 Hero（JS 已置 hidden，这里再兜一层，防内联样式被覆盖） */
.dropzone.is-optional { display: none !important; }

/* ---- 10.2.1 倒计时生成按钮（第 25 轮）----
   规范：按钮必须放在白底表单容器（.panel）最底部、padding 内部的常规文档流中，
   严禁 position:absolute / bottom-* / right-* 定位。
   全宽大按钮（对应 Tailwind 意图 w-full py-3 text-lg font-medium rounded-lg）：
   · .cd-actions  块级包裹层 = mt-8，强制在 inline-block 预览画布之后另起一行；
   · .btn-grad    覆盖胶囊外观 → rounded-lg + py-3 + text-lg，宽度 100%。
   hover 沿用 .btn-grad:hover 的亮度变化（≈ hover:bg-blue-700 transition-colors）。 */
.cd-actions { margin-top: 2rem; display: flex; flex-direction: column; gap: 0.6rem; }
.cd-actions .btn-grad {
  width: 100%;
  height: auto;
  padding: 0.75rem 1.5rem;
  border-radius: 0.5rem;
  font-size: 1.125rem;
  font-weight: 500;
}

/* ---- 10.2.2 多图合成 GIF 工作台（第 27 轮 · 由第 26 轮骨架样式合入 gif.css）----
   png-to-gif 专用：左控制面板（21rem）+ 右分镜板（浅灰底、响应式网格、原生拖拽排序）。
   ★ 与 .cd-actions 同一规范：底部主按钮是**常规文档流最后一格**的全宽大按钮，
     严禁 position:absolute / bottom-* / 负边距。
   ★ 状态机：upload 态整体隐藏 .p2g-ws（editor 态才露出工作台），与 10.2c 同口径。 */
#gif-work[data-step="upload"] .p2g-ws { display: none !important; }

.p2g-ws { margin-top: 1.25rem; display: grid; gap: 1.25rem; align-items: start; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1024px) { .p2g-ws { grid-template-columns: minmax(0, 21rem) minmax(0, 1fr); } }

.p2g-side { display: flex; flex-direction: column; gap: 1.5rem; min-width: 0; }
.p2g-sec { display: flex; flex-direction: column; gap: 0.55rem; }
.p2g-sec + .p2g-sec { padding-top: 1.25rem; border-top: 1px solid #f1f5f9; }
.p2g-h { margin: 0; display: flex; align-items: center; gap: 0.35rem; font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.02em; }
.p2g-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; }
.p2g-row2 .field { margin-bottom: 0; }

/* (i) 悬浮说明徽标（取代占空间的说明段落） */
.p2g-info {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 0.95rem; height: 0.95rem; border-radius: 999px; flex-shrink: 0;
  background: hsl(var(--muted)); color: hsl(var(--muted-foreground));
  font-size: 0.6rem; font-weight: 700; font-style: normal; line-height: 1; cursor: help;
}
.p2g-tip {
  position: absolute; left: 50%; bottom: calc(100% + 0.45rem); z-index: 8;
  width: max-content; max-width: 15rem; padding: 0.45rem 0.6rem; border-radius: 0.5rem;
  background: #0f172a; color: #fff; font-size: 0.6875rem; font-weight: 500; line-height: 1.55; letter-spacing: 0;
  opacity: 0; visibility: hidden; transform: translateX(-50%) translateY(4px);
  transition: opacity .15s, transform .15s, visibility .15s;
  box-shadow: 0 10px 24px -10px rgba(15, 23, 42, .55); pointer-events: none;
}
.p2g-info:hover .p2g-tip, .p2g-info:focus .p2g-tip { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }

/* 画布比例分段控制器（Segmented Control）：淡灰底槽 + 选中白底轻阴影 */
.p2g-seg { display: flex; gap: 2px; padding: 3px; border-radius: 0.6rem; background: hsl(var(--muted)); border: 0; }
.p2g-seg-btn {
  flex: 1 1 0; min-width: 0; height: 1.85rem; padding: 0 0.25rem;
  border: 0; border-radius: 0.45rem; background: transparent;
  color: hsl(var(--muted-foreground)); font-size: 0.75rem; font-weight: 600; letter-spacing: 0;
  white-space: nowrap; cursor: pointer;
  transition: background-color .15s, color .15s, box-shadow .15s;
}
.p2g-seg-btn:hover { color: hsl(var(--foreground)); }
.p2g-seg-btn.is-on {
  background: #fff; color: hsl(var(--foreground));
  box-shadow: 0 1px 2px rgba(15, 23, 42, .12), 0 1px 1px rgba(15, 23, 42, .05);
}

/* ---- 第 29 轮：动画双模式 + 预估总时长 + 比例冲突预警 ---- */
/* 面板内一切 [hidden] 强制生效（.p2g-seg/.p2g-slider 的 display:flex 会盖过 UA 的 [hidden]） */
.p2g-side [hidden], .p2g-alert[hidden] { display: none !important; }
/* 极简/高级 文字 Toggle（模块标题右侧） */
.p2g-mode-toggle {
  margin-left: auto; padding: 0.15rem 0.45rem; border: 0; border-radius: 0.4rem;
  background: transparent; color: hsl(var(--brand-1)); font-size: 0.6875rem; font-weight: 600;
  white-space: nowrap; cursor: pointer; flex-shrink: 0;
  transition: background-color .15s, color .15s;
}
.p2g-mode-toggle:hover { background: hsl(var(--brand-1) / 0.09); color: hsl(var(--brand-1)); }
/* 常驻预估总时长 */
.p2g-dur { margin: 0; font-size: 0.75rem; line-height: 1.5; color: hsl(var(--muted-foreground)); }
.p2g-dur b { color: hsl(var(--foreground)); font-weight: 700; }
/* 比例冲突预警横幅（第 31 轮重塑：amber-50 克制底 + amber-200 细边，去高饱和黄） */
.p2g-alert {
  display: flex; flex-direction: column; gap: 0.55rem;
  padding: 0.75rem; border-radius: 0.5rem;
  background: #fffbeb; border: 1px solid #fde68a;
}
.p2g-alert-title { margin: 0; display: flex; align-items: flex-start; gap: 0.4rem; font-size: 0.8125rem; line-height: 1.6; color: #92400e; }
.p2g-alert-title svg { width: 1rem; height: 1rem; flex-shrink: 0; margin-top: 0.14rem; color: #d97706; }
/* 处理方式 = 2×2 操作卡片（Pricing-Plan 式：hover 变底、选中蓝边加粗），原生 radio 隐藏 */
.p2g-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem; }
.p2g-opt { display: block; position: relative; margin: 0; }
.p2g-opt input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; margin: 0; }
.p2g-opt-body {
  display: flex; flex-direction: column; gap: 0.05rem;
  padding: 0.45rem 0.55rem; border: 1px solid #e5e7eb; border-radius: 0.5rem;
  background: #fff; cursor: pointer;
  font-size: 0.75rem; line-height: 1.35; color: hsl(var(--foreground));
  transition: border-color .15s, background-color .15s, box-shadow .15s;
}
.p2g-opt-body b { font-weight: 600; }
.p2g-opt-body i { font-style: normal; font-size: 0.6875rem; color: hsl(var(--muted-foreground)); }
.p2g-opt:hover .p2g-opt-body { background: #f8fafc; border-color: #cbd5e1; }
.p2g-opt input:checked + .p2g-opt-body {
  border-color: hsl(var(--brand-1)); box-shadow: inset 0 0 0 1px hsl(var(--brand-1));
  background: hsl(var(--brand-1) / 0.04);
}
.p2g-opt input:checked + .p2g-opt-body b { color: hsl(var(--brand-1)); }
.p2g-opt input:focus-visible + .p2g-opt-body { outline: 2px solid hsl(var(--brand-1)); outline-offset: 2px; }
@media (max-width: 480px) { .p2g-opts { grid-template-columns: 1fr; } }

/* ---- 第 31 轮：高级扩展设置（折叠面板）+ 追加卡片 + 全局拖入高亮 ---- */
.p2g-adv-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.55rem 0.7rem; border: 1px solid hsl(var(--border) / 0.8); border-radius: 0.5rem;
  background: hsl(var(--muted) / 0.4); color: hsl(var(--foreground));
  font-size: 0.8125rem; font-weight: 600; cursor: pointer;
  transition: background-color .15s, border-color .15s;
}
.p2g-adv-head:hover { background: hsl(var(--muted)); }
.p2g-adv-head svg { width: 0.9rem; height: 0.9rem; flex-shrink: 0; color: hsl(var(--muted-foreground)); transition: transform .18s; }
.p2g-adv-head.is-open svg { transform: rotate(180deg); }
.p2g-adv-body {
  display: flex; flex-direction: column; gap: 0.55rem;
  padding: 0.7rem 0.7rem 0.75rem; border: 1px solid hsl(var(--border) / 0.8); border-radius: 0.5rem;
}
.p2g-flbl { margin: 0.1rem 0 0; font-size: 0.75rem; font-weight: 600; color: hsl(var(--muted-foreground)); }
.p2g-wm { display: flex; align-items: stretch; gap: 0.5rem; }
.p2g-wm .p2g-wm-txt {
  flex: 1 1 auto; min-width: 0; margin-bottom: 0; resize: vertical; min-height: 3.4rem;
  font-family: inherit; line-height: 1.4;
}
.p2g-wm input[type="color"] { flex: 0 0 2.6rem; width: 2.6rem; height: 2.25rem; padding: 3px; margin-bottom: 0; }
/* 网格末尾的「+ 添加图片」虚线卡片（非 .p2g-card，不参与拖拽） */
.p2g-addcard {
  aspect-ratio: 4 / 5; border: 2px dashed #cbd5e1; border-radius: 0.5rem; background: transparent;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.3rem;
  color: hsl(var(--muted-foreground)); font-size: 0.8125rem; font-weight: 600; cursor: pointer;
  transition: border-color .15s, color .15s, background-color .15s;
}
.p2g-addcard svg { width: 1.1rem; height: 1.1rem; }
.p2g-addcard:hover { border-color: hsl(var(--brand-1)); color: hsl(var(--brand-1)); background: #fff; }
/* 全局拖入时分镜板高亮 */
.p2g-board.is-drop {
  border-color: hsl(var(--brand-1));
  box-shadow: 0 0 0 3px hsl(var(--brand-1) / 0.15), inset 0 1px 3px rgba(15, 23, 42, .05);
}

/* W × H 行（单位内嵌右侧） */
.p2g-dims { display: flex; align-items: center; gap: 0.5rem; }
.p2g-dim { position: relative; flex: 1 1 0; min-width: 0; display: flex; align-items: center; }
.p2g-dim input { padding-right: 1.9rem; }
.p2g-dim > i { position: absolute; right: 0.6rem; font-style: normal; font-size: 0.7rem; color: hsl(var(--muted-foreground)); pointer-events: none; }
.p2g-x { flex-shrink: 0; color: hsl(var(--muted-foreground)); font-weight: 600; }

/* 滑块 + 数值同行 */
.p2g-slider { display: flex; align-items: center; gap: 0.6rem; }
.p2g-slider input[type="range"] { flex: 1 1 auto; min-width: 0; }
.p2g-slider .p2g-num { flex: 0 0 4.8rem; width: 4.8rem; }

/* ★ 底部主操作：全宽大按钮（常规流最后一格；等效 mt-8 w-full py-3 rounded-lg text-lg font-medium） */
.p2g-actions { margin-top: 2rem; display: flex; flex-direction: column; gap: 0.6rem; }
.p2g-actions .btn-grad {
  width: 100%; height: auto;
  padding: 0.75rem 1.5rem; border-radius: 0.5rem;
  font-size: 1.125rem; font-weight: 500;
}
.p2g-est { margin: 0; text-align: center; font-size: 0.75rem; color: hsl(var(--muted-foreground)); }
.p2g-est b { color: hsl(var(--foreground)); }

/* ---- 右：分镜板（bg-gray-50 浅灰工作台 + 内嵌阴影） ---- */
.p2g-board {
  min-width: 0; border: 1px solid hsl(var(--border) / 0.85); border-radius: 1rem; padding: 1.1rem;
  background: #f8fafc; box-shadow: inset 0 1px 3px rgba(15, 23, 42, .05);
}
.p2g-board-head { display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 0.9rem; }
.p2g-board-title { display: inline-flex; align-items: center; gap: 0.45rem; font-size: 0.9375rem; font-weight: 600; }
.p2g-board-title svg { width: 17px; height: 17px; flex-shrink: 0; }
.p2g-count { font-size: 0.75rem; color: hsl(var(--muted-foreground)); }
.p2g-hint { margin-left: auto; font-size: 0.75rem; color: hsl(var(--muted-foreground)); }
@media (max-width: 1023px) { .p2g-hint { margin-left: 0; } }
.p2g-grid { display: grid; gap: 0.85rem; align-items: start; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); min-height: 8rem; }
.p2g-empty { grid-column: 1 / -1; border: 1px dashed hsl(var(--border)); border-radius: 0.9rem; padding: 2rem 1rem; text-align: center; font-size: 0.8125rem; color: hsl(var(--muted-foreground)); }

/* ---- 第 30 轮：SortableJS 拖拽排序（iOS 式丝滑交换） ---- */
/* 选中态微抬（注意：ghost 与 chosen 同挂占位元素，ghost 规则必须在后以覆盖阴影） */
.p2g-card.p2g-chosen { box-shadow: 0 10px 24px -12px rgba(15, 23, 42, .35); }
/* 原位占位符（落点暗示）：半透明 + 灰底 + 2px 虚线灰边 */
.p2g-card.p2g-ghost {
  opacity: 0.4; background: #f3f4f6;
  border: 2px dashed #d1d5db; box-shadow: none;
}
/* 跟随鼠标的浮影（forceFallback 克隆，挂 body，由 Sortable 内联定位尺寸） */
.p2g-fallback {
  opacity: 0.92; cursor: grabbing; pointer-events: none; list-style: none;
  border-radius: 0.5rem;
  box-shadow: 0 18px 40px -14px rgba(15, 23, 42, .5);
  transform: rotate(2deg) scale(1.03);
}
.p2g-fallback .p2g-del { display: none; }
/* 拖拽中全局 grabbing 光标 */
body.p2g-dragging, body.p2g-dragging * { cursor: grabbing !important; }

/* ---- 单帧卡片：白底细边阴影 + 常驻红色删除 + 无缝底部延迟栏 ---- */
.p2g-card {
  position: relative; display: flex; flex-direction: column;
  background: #fff; border: 1px solid #e5e7eb; border-radius: 0.5rem; overflow: hidden;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05); cursor: grab;
  transition: box-shadow .15s, border-color .15s;
}
.p2g-card:hover { border-color: hsl(var(--brand-2) / 0.5); box-shadow: 0 12px 26px -14px rgba(15, 23, 42, .4); }
.p2g-card:active { cursor: grabbing; }
.p2g-card.is-drag { opacity: 0.42; cursor: grabbing; }
.p2g-card.is-over-b::before,
.p2g-card.is-over-a::after {
  content: ""; position: absolute; top: 0.35rem; bottom: 0.35rem; width: 3px; border-radius: 999px;
  background: hsl(var(--brand-1)); box-shadow: 0 0 0 2px hsl(var(--brand-1) / 0.18);
}
.p2g-card.is-over-b::before { left: -0.45rem; }
.p2g-card.is-over-a::after { right: -0.45rem; }
.p2g-card:focus-visible { outline: 2px solid hsl(var(--brand-1)); outline-offset: 2px; }
/* 画面：4:5 盒 + object-fit:contain（棋盘格底，透明 PNG 也看得见） */
.p2g-shot {
  position: relative;
  aspect-ratio: 4 / 5; display: flex; align-items: center; justify-content: center; padding: 0.35rem;
  background-image:
    linear-gradient(45deg, #f1f5f9 25%, transparent 25%, transparent 75%, #f1f5f9 75%),
    linear-gradient(45deg, #f1f5f9 25%, #fff 25%, #fff 75%, #f1f5f9 75%);
  background-size: 14px 14px; background-position: 0 0, 7px 7px;
}
.p2g-shot img { width: 100%; height: 100%; object-fit: contain; border-radius: 0.35rem; }
/* 水印「所见即所得」预览层（第 33 轮）：只盖 object-contain 内容矩形，
   字号/内边距/对齐由 JS 按「输出画布物理比例」换算注入，data-pos 控九宫格对齐 */
.p2g-wm-prev {
  position: absolute; z-index: 2; pointer-events: none; overflow: hidden;
  display: flex; flex-direction: column;
  font-weight: 600; line-height: 1.3; white-space: nowrap;
  text-shadow: 0 0 0.18em rgba(15, 23, 42, .5);
}
.p2g-wm-prev[data-pos$="l"] { align-items: flex-start; text-align: left; }
.p2g-wm-prev[data-pos$="c"] { align-items: center; text-align: center; }
.p2g-wm-prev[data-pos$="r"] { align-items: flex-end; text-align: right; }
.p2g-wm-prev[data-pos^="t"] { justify-content: flex-start; }
.p2g-wm-prev[data-pos^="b"] { justify-content: flex-end; }
/* 序号角标（拖拽后自动重排，纯展示，绝非输入框） */
.p2g-no {
  position: absolute; left: 0.4rem; top: 0.4rem; z-index: 2;
  min-width: 1.35rem; height: 1.35rem; padding: 0 0.3rem; border-radius: 0.45rem;
  background: rgba(15, 23, 42, .72); color: #fff; font-size: 0.6875rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
/* 删除：常驻右上角红色圆形（Trash），背景色 ≠ 页面底色 → 显式 border:0 */
.p2g-del {
  position: absolute; right: 0.35rem; top: 0.35rem; z-index: 3;
  height: 1.5rem; width: 1.5rem; padding: 0; border: 0; border-radius: 999px;
  background: rgba(239, 68, 68, .92); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 1; cursor: pointer;
  box-shadow: 0 1px 3px rgba(15, 23, 42, .2);
  transition: background-color .15s, transform .12s;
}
.p2g-del:hover { background: #dc2626; transform: scale(1.06); }
.p2g-del:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }
.p2g-del svg { width: 0.9rem; height: 0.9rem; }
/* 单帧延迟：无缝底部栏（border-t + 居中沉浸式输入） */
.p2g-foot {
  display: flex; align-items: center; justify-content: center; gap: 0.3rem;
  padding: 0.5rem 0.75rem; border-top: 1px solid #f3f4f6; background: #fff;
  color: hsl(var(--muted-foreground));
}
.p2g-foot svg { width: 0.85rem; height: 0.85rem; flex-shrink: 0; }
.p2g-foot .p2g-ms {
  width: 3rem; height: 1.55rem; padding: 0 0.3rem; text-align: center;
  border: 0; border-radius: 0.375rem; background: #f9fafb; color: hsl(var(--foreground));
  font-size: 0.8125rem; font-weight: 600; line-height: 1;
  transition: background-color .15s, box-shadow .15s;
}
.p2g-foot .p2g-ms:hover { background: #f3f4f6; }
.p2g-foot .p2g-ms:focus { outline: none; border: 0; background: #fff; box-shadow: 0 0 0 1px hsl(var(--brand-1)); }
.p2g-ms::-webkit-outer-spin-button, .p2g-ms::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.p2g-unit { font-size: 0.6875rem; color: hsl(var(--muted-foreground)); }

/* ---- 预览弹窗（Figma 式导出体验） ---- */
.p2g-modal {
  position: fixed; inset: 0; z-index: 90; padding: 1.25rem;
  display: flex; align-items: center; justify-content: center;
  background: rgba(15, 23, 42, .55); backdrop-filter: blur(3px);
}
.p2g-modal[hidden] { display: none !important; }
.p2g-modal-card {
  width: 100%; max-width: 34rem; background: #fff; border-radius: 1.1rem;
  box-shadow: 0 30px 80px -20px rgba(15, 23, 42, .55); overflow: hidden;
  display: flex; flex-direction: column; animation: p2gPop .18s ease-out;
}
@keyframes p2gPop { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
.p2g-modal-head { display: flex; align-items: center; gap: 0.6rem; padding: 0.9rem 1.1rem; border-bottom: 1px solid hsl(var(--border) / 0.8); font-size: 0.9375rem; font-weight: 600; }
.p2g-modal-head svg { width: 17px; height: 17px; flex-shrink: 0; }
.p2g-modal-close {
  margin-left: auto; height: 1.9rem; width: 1.9rem; border: 0; border-radius: 0.5rem;
  background: transparent; color: hsl(var(--muted-foreground)); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.p2g-modal-close:hover { background: hsl(var(--muted)); color: hsl(var(--foreground)); }
.p2g-modal-close svg { width: 1rem; height: 1rem; }
.p2g-modal-body { padding: 1.1rem; display: flex; flex-direction: column; gap: 0.8rem; }
.p2g-modal-stage {
  min-height: 12rem; padding: 0.6rem; border-radius: 0.8rem;
  background: #f8fafc; border: 1px solid hsl(var(--border) / 0.8);
  display: flex; align-items: center; justify-content: center;
}
.p2g-modal-stage img, .p2g-modal-stage canvas { max-width: 100%; max-height: 46vh; border-radius: 0.4rem; }
.p2g-modal-loading { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; color: hsl(var(--muted-foreground)); }
.p2g-modal-loading i {
  height: 1rem; width: 1rem; border-radius: 999px; border: 2px solid hsl(var(--brand-1));
  border-top-color: transparent; animation: p2gSpin .7s linear infinite;
}
@keyframes p2gSpin { to { transform: rotate(360deg); } }
.p2g-modal-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem 0.9rem; font-size: 0.8125rem; color: hsl(var(--muted-foreground)); }
.p2g-modal-meta b { color: hsl(var(--foreground)); }
.p2g-modal-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.7rem; }   /* ★ 第 45 轮：结果快捷操作（参照 v2g 结果卡） */
.p2g-modal-chain { display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.45rem; }
.p2g-modal-body .v2g-rc-divider { margin-top: 0.8rem; }
.p2g-modal-body .v2g-rc-chain-title { margin-top: 0.8rem; }
.p2g-clearall:hover { color: hsl(0 72% 46%); background: hsl(0 84% 60% / 0.08); }   /* ★ 第 45 轮：清除所有图片 hover 危险色 */
.p2g-modal-foot { display: flex; gap: 0.6rem; padding: 0 1.1rem 1.1rem; }
.p2g-modal-foot .btn-grad { flex: 1 1 auto; height: auto; padding: 0.7rem 1.2rem; border-radius: 0.5rem; font-size: 1rem; }
.p2g-modal-foot .btn-ghost { flex: 0 0 auto; }

/* ---- 10.3 工作区两栏 ---- */
.work-grid { margin-top: 1.5rem; display: grid; gap: 1.25rem; }
@media (min-width: 1024px) { .work-grid { grid-template-columns: minmax(0, 1fr) 20rem; align-items: start; } }

.panel {
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.25rem;
  background: hsl(var(--background) / 0.95);
  padding: 1.25rem; box-shadow: var(--shadow-panel);
}
.panel-title { font-size: 0.9375rem; font-weight: 600; margin-bottom: 0.9rem; display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.panel-sub { font-size: 0.8125rem; color: hsl(var(--muted-foreground)); }

/* ---- 10.4 表单控件 ---- */
.field { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 0.9rem; }
.field > label { font-size: 0.8125rem; font-weight: 600; color: hsl(var(--foreground) / 0.85); }
.field-row { display: flex; align-items: center; gap: 0.5rem; }
.field-row > input[type="number"], .field-row > input[type="text"] { min-width: 0; flex: 1; }
.field-hint { font-size: 0.75rem; line-height: 1.25rem; color: hsl(var(--muted-foreground)); }

input[type="text"], input[type="number"], input[type="search"], select, textarea {
  width: 100%; border: 1px solid hsl(var(--border));
  border-radius: 0.6rem; background: #fff; color: hsl(var(--foreground));
  padding: 0.5rem 0.7rem; font-size: 0.875rem; font-family: inherit;
  transition: border-color .15s, box-shadow .15s;
}
input[type="text"]:focus, input[type="number"]:focus, input[type="search"]:focus, select:focus, textarea:focus {
  outline: none; border-color: hsl(var(--brand-2)); box-shadow: 0 0 0 3px hsl(var(--brand-2) / 0.14);
}
input[type="color"] {
  height: 2.1rem; width: 3.2rem; padding: 2px;
  border: 1px solid hsl(var(--border)); border-radius: 0.6rem; background: #fff; cursor: pointer;
}
input[type="range"] { width: 100%; accent-color: hsl(var(--brand-1)); cursor: pointer; }
input[type="checkbox"], input[type="radio"] { accent-color: hsl(var(--brand-1)); width: 1rem; height: 1rem; cursor: pointer; }
.check-row { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; cursor: pointer; margin-bottom: 0.5rem; }

.seg { display: inline-flex; border: 1px solid hsl(var(--border)); border-radius: 999px; background: hsl(var(--muted) / 0.5); padding: 2px; gap: 2px; }
.seg button {
  border: 0; background: transparent; border-radius: 999px;
  padding: 0.32rem 0.85rem; font-size: 0.8125rem; font-weight: 600;
  color: hsl(var(--muted-foreground)); cursor: pointer; transition: background-color .15s, color .15s;
}
.seg button.on { background: #fff; color: hsl(var(--brand-1)); box-shadow: 0 1px 3px rgba(15,23,42,.12); }
.seg.wide { display: flex; width: 100%; }
.seg.wide button { flex: 1; }

/* ---- 10.5 预览舞台 ---- */
.stage {
  position: relative; display: flex; align-items: center; justify-content: center;
  min-height: 18rem; border-radius: 1rem;
  background:
    linear-gradient(45deg, #eef2f7 25%, transparent 25%) 0 0 / 18px 18px,
    linear-gradient(-45deg, #eef2f7 25%, transparent 25%) 0 9px / 18px 18px,
    linear-gradient(45deg, transparent 75%, #eef2f7 75%) 9px -9px / 18px 18px,
    linear-gradient(-45deg, transparent 75%, #eef2f7 75%) -9px 0 / 18px 18px,
    #fff;
  overflow: hidden;
}
.stage img, .stage canvas, .stage video { max-height: 26rem; max-width: 100%; object-fit: contain; border-radius: 0.5rem; }

/* ---- 10.6 文件列表 / 结果表 ---- */
.file-list, .result-list { display: flex; flex-direction: column; gap: 0.65rem; }
.file-row, .result-row {
  display: flex; align-items: center; gap: 0.75rem;
  border: 1px solid hsl(var(--border) / 0.8);
  border-radius: 0.85rem; padding: 0.6rem 0.75rem;
  background: #fff; transition: border-color .15s, background-color .15s;
}
.file-row:hover, .result-row:hover { border-color: hsl(var(--brand-2) / 0.45); background: hsl(var(--accent) / 0.4); }

/* ---- 10.6b ★★ 第 21 轮：文件预览卡「顶部信息栏 + 全宽预览」上下堆叠 ----
   一次性应用到全部 18 个工具（唯一生成点在 gif-shared.js 的 render()）。
   旧横排 .file-row 保留定义（.result-row 等仍在用），不再由 render() 产出。 */
.file-card {
  border: 1px solid hsl(var(--border) / 0.8);
  border-radius: 0.85rem; overflow: hidden; background: #fff;
  transition: border-color .15s, box-shadow .15s;
}
.file-card:hover { border-color: hsl(var(--brand-2) / 0.45); box-shadow: 0 6px 20px -14px hsl(var(--brand-1) / 0.55); }
/* 顶栏：全宽柔和底横条，底边一条分隔线；两端对齐 */
.fc-head {
  width: 100%; box-sizing: border-box;
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 0.7rem 1rem;
  background: hsl(var(--muted) / 0.45);
  border-bottom: 1px solid hsl(var(--border) / 0.75);
}
.fc-info { display: flex; align-items: center; gap: 0.6rem; min-width: 0; flex: 1 1 auto; }
.fc-icon {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  height: 1.75rem; width: 1.75rem; border-radius: 0.5rem;
  background: hsl(var(--brand-2) / 0.12); color: hsl(var(--brand-1));
}
.fc-icon svg { height: 0.9375rem; width: 0.9375rem; }
.fc-meta { min-width: 0; display: flex; flex-direction: column; gap: 0.05rem; }
/* 文件名：单行截断，超长绝不撑破布局 */
.fc-name {
  font-size: 0.875rem; font-weight: 500; color: hsl(var(--foreground) / 0.9);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 12.5rem; /* 200px */
}
@media (min-width: 768px) { .fc-name { max-width: 20rem; } } /* md:max-w-xs */
.fc-size { font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
/* 删除：轻量图标按钮 + 红色 hover，不喧宾夺主 */
.fc-del { flex-shrink: 0; }
.fc-del:hover { border-color: hsl(0 84% 60% / 0.55); color: hsl(0 72% 46%); background: hsl(0 84% 60% / 0.06); }
/* 预览区：全宽、按比例缩放、浅灰底、底部圆角 */
.fc-body {
  width: 100%; background: hsl(var(--muted) / 0.7);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.fc-media { height: auto; width: 100%; border-radius: 0; border: 0; background: transparent; }
.fc-body .fr-thumb { display: flex; align-items: center; justify-content: center; }
/* 真实媒体：占满宽度 + 等比缩放 + 限高（竖屏长图不顶出下方参数区） */
.fc-body img, .fc-body video {
  display: block; width: 100%; height: auto;
  max-height: 31.25rem; /* 500px */
  object-fit: contain; background: hsl(var(--muted) / 0.7);
}
.fc-body.is-empty { padding: 1.6rem 1rem; color: hsl(var(--muted-foreground)); }
.fc-body.is-empty img, .fc-body.is-empty video { display: none; }
@media (max-width: 900px) {
  .fc-body img, .fc-body video { max-height: 22rem; }
  .fc-name { max-width: 9rem; }
}
.list-wrap .file-card + .file-card { margin-top: 0.85rem; }
.file-thumb {
  height: 3rem; width: 3rem; flex-shrink: 0; border-radius: 0.6rem;
  object-fit: contain; background: hsl(var(--muted));
  border: 1px solid hsl(var(--border) / 0.6);
}
.file-meta { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.file-name { font-size: 0.8125rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-info { font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
.result-acts { display: flex; flex-shrink: 0; align-items: center; gap: 0.35rem; }

.badge-ok { display: inline-flex; align-items: center; gap: 0.25rem; border-radius: 999px; background: rgba(16,185,129,.12); color: #059669; padding: 0.1rem 0.5rem; font-size: 0.6875rem; font-weight: 700; }
.badge-warn { display: inline-flex; align-items: center; gap: 0.25rem; border-radius: 999px; background: rgba(245,158,11,.14); color: #b45309; padding: 0.1rem 0.5rem; font-size: 0.6875rem; font-weight: 700; }
.badge-info { display: inline-flex; align-items: center; gap: 0.25rem; border-radius: 999px; background: hsl(var(--brand-2) / 0.12); color: hsl(var(--brand-1)); padding: 0.1rem 0.5rem; font-size: 0.6875rem; font-weight: 700; }

/* ---- 10.7 进度条 / 状态 ---- */
.progress { margin-top: 0.75rem; height: 0.4rem; border-radius: 999px; background: hsl(var(--border)); overflow: hidden; }
.progress > i { display: block; height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, #0062ff, #38bdf8); transition: width .2s; }
.status-line { margin-top: 0.6rem; min-height: 1.1rem; font-size: 0.8125rem; color: hsl(var(--muted-foreground)); }

/* ---- 10.8 帧网格 ---- */
.frame-grid {
  margin-top: 0.75rem; display: grid; gap: 0.6rem;
  grid-template-columns: repeat(auto-fill, minmax(5.25rem, 1fr));
  max-height: 20rem; overflow-y: auto; padding: 2px;
}
.frame-cell {
  position: relative; border: 2px solid hsl(var(--border));
  border-radius: 0.6rem; overflow: hidden; background: #fff; cursor: pointer;
  aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center;
  transition: border-color .15s, box-shadow .15s;
}
.frame-cell img { max-height: 100%; max-width: 100%; object-fit: contain; }
.frame-cell.sel { border-color: hsl(var(--brand-1)); box-shadow: 0 0 0 2px hsl(var(--brand-1) / 0.2); }
.frame-no {
  position: absolute; left: 3px; bottom: 3px;
  border-radius: 0.3rem; background: rgba(15,23,42,.72); color: #fff;
  padding: 0 0.3rem; font-size: 0.625rem; font-weight: 600; line-height: 1rem;
}
.frame-cell.sel .frame-no { background: hsl(var(--brand-1)); }

/* ---- 10.9 空态 / toast / 弹层 ---- */
.empty { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; text-align: center; color: hsl(var(--muted-foreground)); padding: 2rem 1rem; }
.empty svg { height: 2.5rem; width: 2.5rem; color: hsl(var(--border)); }
.empty p { font-size: 0.875rem; }

.toast {
  position: fixed; left: 50%; bottom: 2rem; transform: translate(-50%, 1rem);
  z-index: 200; max-width: 90vw;
  border-radius: 999px; background: rgba(15, 23, 42, 0.94); color: #fff;
  padding: 0.6rem 1.2rem; font-size: 0.8125rem;
  opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s;
  box-shadow: 0 20px 50px -12px rgba(15,23,42,.6);
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---- 10.10 模态 ---- */
.modal { position: fixed; inset: 0; z-index: 180; display: flex; align-items: center; justify-content: center; padding: 1rem; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, 0.45); backdrop-filter: blur(2px); }
.modal-card {
  position: relative; width: 100%; max-width: 24rem;
  border-radius: 1.25rem; background: #fff; padding: 1.5rem;
  box-shadow: 0 30px 80px -20px rgba(15,23,42,.5);
}
.modal-card h3 { font-size: 1.0625rem; font-weight: 600; }
.modal-card p { margin-top: 0.5rem; font-size: 0.875rem; line-height: 1.6; color: hsl(var(--muted-foreground)); }
.modal-actions { margin-top: 1.25rem; display: flex; justify-content: flex-end; gap: 0.6rem; }

/* ---- 10.11 工具页底部三卡（marketing） ---- */
.market-cards { margin-top: 1.5rem; display: grid; gap: 1.5rem; }
@media (min-width: 768px) { .market-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.market-card {
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 1.5rem; background: hsl(var(--card) / 0.85);
  padding: 1.5rem; box-shadow: var(--shadow-card);
}
.market-card-icon {
  display: flex; height: 2.75rem; width: 2.75rem; align-items: center; justify-content: center;
  border-radius: 1rem; background: hsl(var(--brand-2) / 0.10); color: hsl(var(--brand-2));
}
.market-card-icon svg { height: 1.35rem; width: 1.35rem; }
.market-card h2 { margin-top: 1.25rem; font-size: 1.25rem; font-weight: 600; letter-spacing: -0.01em; }
.market-card p { margin-top: 0.75rem; font-size: 0.875rem; line-height: 1.75rem; color: hsl(var(--muted-foreground)); }

/* ---- 10.12 局部裁剪/涂抹画布层（供 crop / blur / video 工具复用） ---- */
.canvas-host { position: relative; display: inline-block; line-height: 0; max-width: 100%; }
.canvas-host > canvas, .canvas-host > img { border-radius: 0.5rem; }
.overlay-layer { position: absolute; inset: 0; z-index: 3; }
.ov-rect {
  position: absolute; border: 2px solid hsl(var(--brand-1));
  background: hsl(var(--brand-1) / 0.10);
  box-shadow: 0 0 0 9999px rgba(15, 23, 42, 0.32);
}
.ov-handle {
  position: absolute; height: 12px; width: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%; background: #fff; border: 2px solid hsl(var(--brand-1));
  cursor: pointer;
}
.ov-handle[data-h="nw"] { cursor: nwse-resize; } .ov-handle[data-h="se"] { cursor: nwse-resize; }
.ov-handle[data-h="ne"] { cursor: nesw-resize; } .ov-handle[data-h="sw"] { cursor: nesw-resize; }
.ov-handle[data-h="n"], .ov-handle[data-h="s"] { cursor: ns-resize; }
.ov-handle[data-h="w"], .ov-handle[data-h="e"] { cursor: ew-resize; }
.region-box {
  position: absolute; border: 2px solid #f59e0b; background: rgba(245, 158, 11, 0.12);
  border-radius: 4px; cursor: move;
}
.region-del {
  position: absolute; right: -9px; top: -9px; height: 18px; width: 18px;
  border-radius: 50%; background: #ef4444; color: #fff; border: 2px solid #fff;
  font-size: 11px; line-height: 1; display: flex; align-items: center; justify-content: center;
  cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,.25);
}
.axis-line { position: absolute; background: hsl(var(--brand-1)); }
.axis-line.is-h { left: 0; right: 0; height: 2px; cursor: ns-resize; }
.axis-line.is-v { top: 0; bottom: 0; width: 2px; cursor: ew-resize; }

/* ---- 10.13 工具内快捷链接条 ---- */
.quick-links { margin-top: 2rem; display: flex; flex-wrap: wrap; gap: 0.6rem; }
.quick-links a {
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: 999px; background: hsl(var(--background) / 0.85);
  padding: 0.4rem 0.9rem; font-size: 0.8125rem; font-weight: 500;
  color: hsl(var(--brand-2)); transition: border-color .15s;
}
.quick-links a:hover { border-color: hsl(var(--brand-2) / 0.4); }

/* ---- 10.14 表格（对比表） ---- */
.cmp-sec { margin-top: 3rem; }
.cmp-scroll { margin-top: 1.25rem; overflow-x: auto; border: 1px solid hsl(var(--border) / 0.7); border-radius: 0.5rem; }
.cmp-scroll table { min-width: 46rem; width: 100%; text-align: left; font-size: 0.875rem; }
.cmp-scroll thead { background: hsl(var(--muted) / 0.4); }
.cmp-scroll th, .cmp-scroll td { padding: 0.75rem 1rem; }
.cmp-scroll thead th { font-weight: 600; }
.cmp-scroll tbody th { font-weight: 500; text-align: left; }
.cmp-scroll tbody tr { border-top: 1px solid hsl(var(--border) / 0.7); }
.cmp-scroll td { color: hsl(var(--muted-foreground)); line-height: 1.5rem; }

/* ---- 10.15 移动端安全 ---- */
@media (max-width: 640px) {
  .tool-card { padding: 1.25rem; border-radius: 1.125rem; }
  .tc-title { font-size: 1rem; }
  .tc-ico { height: 2.75rem; width: 2.75rem; border-radius: 0.875rem; }
  .tool-toolbar { gap: 0.75rem; }
  .tool-search input.ts-input { padding-top: 0.6875rem; padding-bottom: 0.6875rem; }
  .tool-tab { padding: 0.4375rem 0.9375rem; font-size: 0.8125rem; }
  .work-panel { min-height: 16rem; padding: 1rem; }
  .stage { min-height: 13rem; }
  .grid-4 { grid-template-columns: 1fr 1fr; }
}

/* ======================================================================
   11. 工具层样式补齐（★ 生成脚本曾漏掉这批类，导致窄列/错位等 UI bug）
   ====================================================================== */

/* ---- 11.1 通用 ---- */
.list-wrap { margin-top: 1rem; }
.hint { margin: 0.4rem 0 0.9rem; font-size: 0.8125rem; line-height: 1.35rem; color: hsl(var(--muted-foreground)); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 0.9rem; }
@media (max-width: 640px) { .grid-2 { grid-template-columns: 1fr; } }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0 0.75rem; }
.icon-btn {
  height: 1.7rem; min-width: 2rem; padding: 0 0.4rem;
  border: 1px solid hsl(var(--border)); border-radius: 0.45rem;
  background: #fff; color: hsl(var(--muted-foreground));
  font-size: 0.7rem; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-btn:hover { border-color: hsl(var(--brand-2)); color: hsl(var(--brand-1)); }

/* ---- 11.2 视频舞台（video-to-gif / screen-recorder）与标注层 ---- */
.video-stage {
  position: relative; width: 100%; margin-bottom: 1rem;
  display: flex; align-items: center; justify-content: center;
  padding: 0.75rem; border-radius: 1rem;
  background: hsl(var(--muted) / 0.55); overflow: hidden;
}
.video-stage video { max-width: 100%; max-height: 26rem; border-radius: 0.5rem; background: #000; }
.video-inner { position: relative; display: inline-block; line-height: 0; max-width: 100%; }
.ov-layer { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.time-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 0.9rem; }
.annot-bar { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.4rem 0 1rem; }
.annot { position: absolute; z-index: 6; pointer-events: none; display: flex; align-items: center; justify-content: center; }
.annot-text, .annot-emoji { white-space: nowrap; padding: 0.05em 0.35em; border-radius: 0.3em; line-height: 1.3; }

/* ---- 11.3 裁剪选区（crop-gif）----
   ★ 曾经的致命 bug：.ov-rect 初始 0×0，却带着 `box-shadow: 0 0 0 9999px` 的遮罩；
   阴影以 4 边各 9999px 向外扩散，而 .canvas-host 没有 overflow 裁剪，
   于是把整个页面蒙黑、GIF 完全没法用。
   现在：① 遮罩改由 .canvas-host 上的 .crop-mask 承担并随宿主裁剪（overflow:hidden）；
        ② .ov-rect 只负责亮框，不带任何超大阴影；
        ③ 未选出图片前 ov-rect 整体隐藏（is-off）。 */
.canvas-host { overflow: hidden; }              /* 关键：把遮罩阴影关在舞台内 */
.crop-mask {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: rgba(15, 23, 42, 0.42);
  /* 用「四块矩形」挖洞比 box-shadow 稳：不会溢出、不被 border-radius 干扰 */
}
.crop-mask > i { position: absolute; background: transparent; }
.crop-mask .cm-t { left: 0; right: 0; top: 0; }
.crop-mask .cm-b { left: 0; right: 0; bottom: 0; }
.crop-mask .cm-l { top: 0; bottom: 0; left: 0; }
.crop-mask .cm-r { top: 0; bottom: 0; right: 0; }
.ov-rect {
  position: absolute; z-index: 6; cursor: move;
  border: 2px solid hsl(var(--brand-1));
  outline: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: none;
}
.ov-rect.is-off { display: none; }
.ov-rect.is-dragging { pointer-events: none; }
.ov-rect::after {
  content: ""; position: absolute; right: -6px; bottom: -6px;
  height: 13px; width: 13px; border-radius: 3px;
  background: #fff; border: 2px solid hsl(var(--brand-1)); cursor: nwse-resize;
}
/* 网格辅助线：帮助预览裁剪后的构图（三等分） */
.ov-rect .ov-grid { position: absolute; inset: 0; pointer-events: none; }
.ov-rect .ov-grid::before, .ov-rect .ov-grid::after {
  content: ""; position: absolute; background: rgba(255, 255, 255, 0.45);
}
.ov-rect .ov-grid::before { left: 33.33%; right: 33.33%; top: 0; bottom: 0; border-left: 1px dashed rgba(255,255,255,.55); border-right: 1px dashed rgba(255,255,255,.55); background: none; }
.ov-rect .ov-grid::after { top: 33.33%; bottom: 33.33%; left: 0; right: 0; border-top: 1px dashed rgba(255,255,255,.55); border-bottom: 1px dashed rgba(255,255,255,.55); background: none; }
/* 四角/四边手柄（比旧版只有右下角一个更好抓） */
.ov-h { position: absolute; width: 14px; height: 14px; z-index: 7; }
.ov-h-n { top: -7px; left: 50%; margin-left: -7px; cursor: ns-resize; }
.ov-h-s { bottom: -7px; left: 50%; margin-left: -7px; cursor: ns-resize; }
.ov-h-w { left: -7px; top: 50%; margin-top: -7px; cursor: ew-resize; }
.ov-h-e { right: -7px; top: 50%; margin-top: -7px; cursor: ew-resize; }
.ov-rect::after { right: -8px; bottom: -8px; height: 15px; width: 15px; }

/* ===== 11.3b 裁剪工作台：左右分栏（左工作区 70% / 右控制面板 30%）===== */
.crop-ws {
  display: grid; grid-template-columns: minmax(0, 1fr) 20rem;
  gap: 1.25rem; align-items: start; margin-top: .75rem;
}
@media (max-width: 900px) { .crop-ws { grid-template-columns: minmax(0, 1fr); } }

/* 左：可视化工作区（浅灰格纹底 + 画面居中 + 内边距）
   ★ 第 24 轮：必须给舞台一个「硬性高度上限」，否则竖屏比例 + 大图时
     舞台会被内容顶到几千 px 高、整体溢出视口（用户实测 Bug）。
     上限口径 = min(视口 52%，34rem)，且不小于 min-height，避免互相打架。 */
.crop-stage {
  position: relative; display: flex; flex-direction: column;
  min-height: 22rem;
  height: min(52vh, 34rem);
  max-height: min(52vh, 34rem);
  box-sizing: border-box;
  padding: 1.5rem; border-radius: 1.25rem;
  border: 1px solid hsl(var(--border));
  background-color: hsl(var(--muted) / .55);
  background-image:
    linear-gradient(45deg, rgba(148,163,184,.14) 25%, transparent 25%, transparent 75%, rgba(148,163,184,.14) 75%),
    linear-gradient(45deg, rgba(148,163,184,.14) 25%, transparent 25%, transparent 75%, rgba(148,163,184,.14) 75%);
  background-size: 18px 18px; background-position: 0 0, 9px 9px;
}
/* 画布托底区：吃掉剩余高度并把画布真正居中（说明行在它下方，不参与居中）
   ★ 第 24 轮：这里绝不能 overflow:hidden —— 四角/四边手柄（.ov-h）是刻意
     向外探出 7px 的抓取点，裁掉它们等于让用户抓不到边。改为「给手柄留出
     padding 安全区」，画面本体仍被 JS + max-width/height 约束在安全区内。
   安全区 = 10px（手柄 7px + 3px 余量），拖拽时鼠标不会顶到 holder 边缘。 */
.crop-holder {
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center;
  min-height: 0; width: 100%; overflow: visible;
  padding: 10px; box-sizing: border-box;
}
/* 舞台里的画布宿主：带柔和投影，像一张「照片」浮在格纹底上
   ★ 第 24 轮：宿主自身也必须被 flex 压回可用空间，否则它会被 canvas 的
     固有尺寸撑大，配合 overflow:hidden 反而把画面「裁掉」（不是缩放）。 */
.crop-stage .canvas-host {
  border-radius: .6rem; box-shadow: 0 10px 30px -12px rgba(15,23,42,.35);
  max-width: 100%; max-height: 100%; min-width: 0; min-height: 0; flex: 0 1 auto;
}
/* ★ 舞台内的 canvas 就是「画面本身」：强制完整容纳（Fit to Container）。
   1) object-fit:contain 让它在任何比例下都整体可见、绝不裁切；
   2) display:block 干掉 inline 基线间隙（曾导致 host 出现 6px 竖向溢出）。
   注：宿主保留 overflow:hidden 只为「万一 JS 尺寸算错时兜底不戳出画面」，
   手柄探出的 7px 由 holder 的 10px 安全区承接，视觉与交互都不受影响。 */
.crop-stage .canvas-host > canvas {
  display: block;
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
}
.crop-info {
  margin: .75rem .15rem 0; font-size: .8125rem; line-height: 1.4rem;
  color: hsl(var(--muted-foreground));
  flex: 0 0 auto;
}
.crop-info b { color: hsl(var(--foreground)); }

/* ★ 矮视口兜底：视口高度不足时减小舞台上下内边距与最小高度，
   给画面留出尽量多的可用空间（否则小窗口下画面只剩一条缝）。 */
@media (max-height: 720px) {
  .crop-stage { min-height: 17rem; padding: 1rem; }
  .crop-info { margin-top: .5rem; font-size: .75rem; line-height: 1.25rem; }
}
@media (max-height: 560px) {
  .crop-stage { min-height: 13rem; padding: .75rem; }
}

/* 右：白色阴影侧边栏，固定在面板内（滚动跟随） */
.crop-side {
  display: flex; flex-direction: column; gap: 1.1rem;
  background: hsl(var(--card, 0 0% 100%)); background-color: #fff;
  border: 1px solid hsl(var(--border)); border-radius: 1.25rem;
  padding: 1.15rem 1.1rem; box-shadow: 0 12px 32px -18px rgba(15,23,42,.35);
}
@media (min-width: 901px) { .crop-side { position: sticky; top: 5rem; } }
.cs-sec { display: flex; flex-direction: column; gap: .6rem; }
.cs-sec + .cs-sec { padding-top: 1rem; border-top: 1px solid hsl(var(--border) / .7); }
.cs-h { margin: 0; font-size: .8125rem; font-weight: 700; letter-spacing: .02em; color: hsl(var(--foreground)); }
.cs-hint { margin: .1rem 0 0; font-size: .75rem; line-height: 1.15rem; color: hsl(var(--muted-foreground)); }

/* 比例预设：3 列图标网格 */
.ratio-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem; }
.ratio-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .15rem;
  padding: .55rem .25rem .5rem; border: 1px solid hsl(var(--border)); border-radius: .7rem;
  background: #fff; color: hsl(var(--muted-foreground)); cursor: pointer;
  transition: border-color .15s, background-color .15s, color .15s, box-shadow .15s, transform .12s;
}
.ratio-btn:hover { border-color: hsl(var(--brand-1) / .5); color: hsl(var(--brand-1)); background: hsl(var(--brand-1) / .04); }
.ratio-btn .rb-ico { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.ratio-btn .rb-lb { font-size: .75rem; font-weight: 600; line-height: 1.1; }
.ratio-btn .rb-nt { font-size: .625rem; line-height: 1; opacity: .7; }
.ratio-btn.is-on {
  border-color: hsl(var(--brand-1)); color: hsl(var(--brand-1));
  background: hsl(var(--brand-1) / .09);
  box-shadow: 0 0 0 1px hsl(var(--brand-1) / .35) inset, 0 6px 16px -10px hsl(var(--brand-1) / .55);
  transform: translateY(-1px);
}

/* 尺寸表单：W/H 同行（中间锁），X/Y 下一行 */
.cs-row { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0 .5rem; align-items: end; }
.cs-row .field { margin-bottom: .35rem; }
.cs-row + .cs-row { margin-top: .15rem; }
.ratio-lock {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2.3rem; width: 2.3rem; margin-bottom: .38rem;
  border: 1px solid hsl(var(--border)); border-radius: .6rem;
  background: #fff; color: hsl(var(--brand-1)); cursor: pointer;
  transition: background-color .15s, border-color .15s, transform .12s, color .15s;
}
.ratio-lock svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.ratio-lock:hover { border-color: hsl(var(--brand-1) / .55); background: hsl(var(--brand-1) / .05); }
/* is-off = 未锁定：锁口张开、颜色转灰 */
.ratio-lock.is-off { color: hsl(var(--muted-foreground)); }
.ratio-lock.is-off .lk-sh { transform: translateX(2.4px) rotate(-22deg); transform-origin: 6.4px 9px; }
.ratio-lock.is-off svg rect { fill: none; }
.ratio-lock:not(.is-off) svg rect { fill: hsl(var(--brand-1) / .12); }

/* 底部主操作：100% 宽 block 按钮 */
.cs-act { display: flex; flex-direction: column; gap: .5rem; margin-top: .15rem; }
.cs-act .btn-grad, .cs-act .btn-primary { width: 100%; display: flex; justify-content: center; }

/* 侧边栏内输入框：极简浅灰边框 */
.crop-side .field > label { font-size: .75rem; color: hsl(var(--muted-foreground)); }
.crop-side .field input {
  border: 1px solid hsl(var(--border)); background: #fff; border-radius: .5rem;
  padding: .42rem .55rem; font-size: .8125rem; width: 100%;
}
.crop-side .field input:focus { border-color: hsl(var(--brand-1)); box-shadow: 0 0 0 3px hsl(var(--brand-1) / .12); outline: none; }

/* ---- 11.4 帧选择网格（gif-to-png 自定义帧）---- */
.frame-pick {
  margin-top: 0.9rem; display: grid; gap: 0.5rem; padding: 2px;
  grid-template-columns: repeat(auto-fill, minmax(4.75rem, 1fr));
  max-height: 20rem; overflow-y: auto;
}
.fp-cell {
  position: relative; border: 2px solid hsl(var(--border)); border-radius: 0.6rem;
  background: #fff; padding: 2px; cursor: pointer; line-height: 0;
}
.fp-cell.is-on { border-color: hsl(var(--brand-1)); box-shadow: 0 0 0 2px hsl(var(--brand-1) / 0.18); }
.fp-cell span {
  position: absolute; left: 3px; bottom: 3px; border-radius: 0.3rem;
  background: rgba(15, 23, 42, 0.72); color: #fff;
  padding: 0 0.3rem; font-size: 0.625rem; font-weight: 600; line-height: 1rem;
}

/* ---- 11.5 帧顺序网格（png-to-gif）---- */
.order-box { margin-top: 0.9rem; }
.order-box > label { display: block; margin-bottom: 0.5rem; font-size: 0.8125rem; font-weight: 600; color: hsl(var(--foreground) / 0.85); }
.order-grid {
  display: grid; gap: 0.55rem; padding: 2px;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  max-height: 18rem; overflow-y: auto;
}
.oc-cell {
  position: relative; border: 1px solid hsl(var(--border) / 0.8);
  border-radius: 0.6rem; background: #fff; padding: 0.3rem;
}
.oc-cell img { width: 100%; height: 4rem; object-fit: contain; background: hsl(var(--muted)); border-radius: 0.4rem; }
.oc-cell b {
  position: absolute; left: 0.45rem; top: 0.45rem; z-index: 2;
  min-width: 1.15rem; height: 1.15rem; border-radius: 0.35rem;
  background: rgba(15, 23, 42, 0.72); color: #fff;
  font-size: 0.65rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.oc-act { display: flex; gap: 0.3rem; margin-top: 0.35rem; }
.oc-act .icon-btn { flex: 1; }

/* ---- 11.6 录屏（screen-recorder）---- */
.rec-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.9rem 0; }
/* 录屏实时画面：居中显示，别贴左 */
.canvas-host video { display: block; margin: 0 auto; }

/* 录制状态灯：待机=灰 / 请求权限=蓝闪 / 录制中=红呼吸 + 计时 */
.rec-state {
  display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap;
  margin-top: 1rem; padding: 0.6rem 0.9rem;
  border: 1px solid hsl(var(--border) / 0.8); border-radius: 0.7rem;
  background: hsl(var(--muted) / 0.35);
  font-size: 0.8125rem; color: hsl(var(--muted-foreground));
  transition: background 0.2s ease, border-color 0.2s ease;
}
.rec-state-txt { font-size: 0.875rem; color: hsl(var(--foreground)); }
.rec-dot {
  width: 0.6rem; height: 0.6rem; border-radius: 999px; flex-shrink: 0;
  background: hsl(var(--muted-foreground) / 0.5);
}
.rec-timer {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 0.9375rem;
  color: hsl(var(--foreground)); margin-left: 0.15rem;
}
.rec-state.is-idle .rec-timer { opacity: 0.45; font-weight: 600; }
.rec-size { font-size: 0.75rem; color: hsl(var(--muted-foreground)); }
.rec-state.is-asking {
  border-color: #38bdf8; background: rgba(56, 189, 248, 0.1);
}
.rec-state.is-asking .rec-dot { background: #38bdf8; animation: recPulse 1s ease-in-out infinite; }
.rec-state.is-recording {
  border-color: #ef4444; background: rgba(239, 68, 68, 0.08);
}
.rec-state.is-recording .rec-state-txt { color: #dc2626; font-weight: 700; }
.rec-state.is-recording .rec-dot { background: #ef4444; animation: recPulse 1.1s ease-in-out infinite; }
.rec-state.is-recording .rec-timer { color: #dc2626; }
@keyframes recPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.32; transform: scale(0.78); }
}
/* 红色停止按钮，和「开始」形成强对比 */
.btn-stop {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem;
  border-radius: 0.6rem; padding: 0.6rem 1.1rem; font-size: 0.875rem; font-weight: 600;
  background: #ef4444; color: #fff; border: 1px solid #ef4444; cursor: pointer;
  transition: background 0.16s ease, transform 0.16s ease;
}
.btn-stop:hover:not(:disabled) { background: #dc2626; transform: translateY(-1px); }
.btn-stop:disabled { opacity: 0.45; cursor: not-allowed; background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); border-color: hsl(var(--border)); }

.rec-hist-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-top: 1.6rem; }
.rec-hist-head .h3 { margin: 0; }
.rec-history { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.6rem; }
.rec-item {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap;
  border: 1px solid hsl(var(--border) / 0.7); border-radius: 0.6rem;
  background: #fff; padding: 0.5rem 0.7rem; font-size: 0.8125rem;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.rec-item.is-playing { border-color: #0062ff; box-shadow: 0 0 0 3px rgba(0, 98, 255, 0.1); }
.rec-main { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; flex: 1 1 12rem; }
.rec-main b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rec-main span { color: hsl(var(--muted-foreground)); font-size: 0.75rem; }
.rec-acts { display: flex; align-items: center; gap: 0.35rem; flex-shrink: 0; }
.rec-acts .btn-sm.is-on { background: rgba(0, 98, 255, 0.1); border-color: #0062ff; color: #0062ff; }
.rec-del { color: hsl(var(--muted-foreground)); }
.rec-del:hover { color: #ef4444; border-color: #ef4444; }
/* 行内快捷预览：条目下方直接播放，不用先下载 */
.rec-full { display: none; width: 100%; }
.rec-full.is-on { display: block; margin-top: 0.35rem; }
.rec-full video {
  width: 100%; max-height: 22rem; border-radius: 0.55rem; background: #000; display: block;
}

/* ---- 11.7 Lottie 预览 ---- */
.lottie-prev {
  display: flex; align-items: center; justify-content: center;
  padding: 0.4rem; border-radius: 0.5rem; background: hsl(var(--muted) / 0.5);
}

/* ---- 11.8 实时预览窗（video-to-gif / crop-gif / 变速 / 压缩 共用）----
   统一结构：.live-box > .live-canvas(舞台) + .live-bar(状态/数字)
   全部用 canvas 逐帧重绘，改参数即时看到结果，不需要先导出。 */
.live-box {
  margin-top: 0.9rem;
  border: 1px solid hsl(var(--border) / 0.8);
  border-radius: 1rem;
  background: hsl(var(--muted) / 0.35);
  padding: 0.75rem;
}
.live-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.5rem; margin-bottom: 0.6rem;
}
.live-title { font-size: 0.8125rem; font-weight: 600; color: hsl(var(--foreground) / 0.85); }
.live-badge {
  display: inline-flex; align-items: center; gap: 0.3rem;
  border-radius: 999px; background: hsl(var(--brand-2) / 0.14); color: hsl(var(--brand-1));
  padding: 0.15rem 0.6rem; font-size: 0.6875rem; font-weight: 700;
}
.live-stage-wrap {
  display: flex; align-items: center; justify-content: center;
  border-radius: 0.75rem; overflow: hidden;
  background:
    linear-gradient(45deg, #eef2f7 25%, transparent 25%) 0 0 / 16px 16px,
    linear-gradient(-45deg, #eef2f7 25%, transparent 25%) 0 8px / 16px 16px,
    linear-gradient(45deg, transparent 75%, #eef2f7 75%) 8px -8px / 16px 16px,
    linear-gradient(-45deg, transparent 75%, #eef2f7 75%) -8px 0 / 16px 16px,
    #fff;
}
.live-stage { max-width: 100%; max-height: 24rem; display: block; }
.live-stage-wrap { position: relative; }
/* 首帧前的覆盖加载层（livePreview 内置：第一帧画出来后淡出） */
.live-loading {
  position: absolute; inset: 0; z-index: 6;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.55rem;
  background: hsl(var(--muted) / 0.72);
  font-size: 0.8125rem; color: hsl(var(--muted-foreground));
  transition: opacity 0.25s ease;
}
.live-loading.is-done { opacity: 0; pointer-events: none; }
.ll-bar, .lp-bar {
  position: relative; overflow: hidden; height: 4px; border-radius: 999px;
  background: hsl(var(--muted));
}
.ll-bar { width: 9rem; }
.lp-bar { flex: 1; min-width: 5rem; margin-left: 0.35rem; }
.ll-bar i, .lp-bar i {
  position: absolute; top: 0; bottom: 0; left: -35%; width: 35%; border-radius: 999px;
  background: linear-gradient(90deg, #0062ff, #38bdf8);
  animation: lpSlide 1.1s ease-in-out infinite;
}
@keyframes lpSlide { to { left: 105%; } }
/* 预览尚未就绪时的占位条（解析文件/读元数据阶段） */
.live-pending {
  display: flex; align-items: center; gap: 0.6rem;
  margin: 0.9rem 0; padding: 0.85rem 1rem;
  border: 1px dashed hsl(var(--border)); border-radius: 0.7rem;
  background: hsl(var(--muted) / 0.35);
  font-size: 0.8125rem; color: hsl(var(--muted-foreground));
}
.lp-spin {
  width: 0.95rem; height: 0.95rem; border-radius: 999px; flex-shrink: 0;
  border: 2px solid hsl(var(--brand-2) / 0.25); border-top-color: hsl(var(--brand-1));
  animation: lpSpin 0.8s linear infinite;
}
@keyframes lpSpin { to { transform: rotate(360deg); } }
.live-stats {
  margin-top: 0.6rem; display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem;
  font-size: 0.75rem; color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}
.live-stats b { color: hsl(var(--foreground)); font-weight: 600; }
.live-stats .est { color: hsl(var(--brand-1)); }

/* ======================================================================
   11.1 导出前体积预估面板（.est-panel —— 批量压缩等「压缩类」工具在导出前
        逐文件给出预计体积/预计档位/节省比例；长文件名必须能换行，禁止撑破侧栏）
   ====================================================================== */
.est-panel {
  margin: 0.9rem 0 0.4rem;
  border: 1px solid hsl(var(--brand-2) / 0.28);
  border-radius: 0.8rem;
  background: hsl(var(--brand-2) / 0.05);
  padding: 0.75rem 0.85rem;
  overflow: hidden;            /* 双保险：任何子元素都不允许横向溢出 */
}
.est-panel .est-title {
  font-size: 0.8125rem; font-weight: 700; color: hsl(var(--brand-1));
  margin-bottom: 0.5rem; display: flex; align-items: center; gap: 0.35rem;
}
.est-panel .est-rows { display: flex; flex-direction: column; gap: 0.45rem; }
.est-panel .est-row {
  display: flex; flex-direction: column; gap: 0.12rem;
  padding: 0.45rem 0.55rem; border-radius: 0.55rem;
  background: hsl(var(--background) / 0.75);
  border: 1px solid hsl(var(--border) / 0.7);
  font-size: 0.75rem; color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
.est-panel .est-row > b {
  color: hsl(var(--foreground)); font-weight: 600; font-size: 0.8125rem;
  /* ★ 长文件名必须截断，否则会把侧栏顶宽 → 整页横向滚动 */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.est-panel .est-row > span { line-height: 1.35; word-break: break-word; }
.est-panel .est-row > span > b { color: hsl(var(--brand-1)); font-weight: 700; }
.est-panel .est { color: hsl(var(--brand-1)); font-weight: 600; }
.est-panel .est.pending { color: hsl(var(--muted-foreground)); }
.est-panel .est.ok { color: #059669; }
.est-panel .est.warn { color: #b45309; }
.est-panel .est-foot {
  margin-top: 0.55rem; padding-top: 0.5rem;
  border-top: 1px dashed hsl(var(--brand-2) / 0.3);
  font-size: 0.75rem; color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums; line-height: 1.4;
}
.est-panel .est-foot b { color: hsl(var(--foreground)); font-weight: 700; }

/* ======================================================================
   11.2 批量压缩双模式面板（.cmp-* —— 第 32 轮：极简三档 / 高级参数 / 智能预警）
   ====================================================================== */
/* 模式切换头：label + 两段 Toggle */
.cmp-mode-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  margin-bottom: 0.85rem;
}
.cmp-mode-label { font-size: 0.8125rem; font-weight: 600; color: hsl(var(--foreground)); }
.cmp-mode-seg {
  display: inline-flex; padding: 3px; gap: 2px;
  background: #f1f5f9; border-radius: 0.55rem;
}
.cmp-mode-btn {
  border: 0; background: none; cursor: pointer;
  font-size: 0.75rem; font-weight: 600; color: #64748b;
  padding: 0.3rem 0.7rem; border-radius: 0.4rem;
  transition: background-color .15s, color .15s, box-shadow .15s;
}
.cmp-mode-btn.is-on { background: #fff; color: #0f172a; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); }

/* 极简：三档压缩强度（横向分段，选中蓝边白底） */
.cmp-tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.45rem; }
.cmp-tier {
  border: 1px solid #e5e7eb; background: #fff; cursor: pointer;
  border-radius: 0.6rem; padding: 0.55rem 0.35rem; text-align: center;
  display: flex; flex-direction: column; gap: 0.1rem; align-items: center;
  transition: border-color .15s, box-shadow .15s, background-color .15s;
}
.cmp-tier b { font-size: 0.8125rem; font-weight: 600; color: #334155; }
.cmp-tier i { font-style: normal; font-size: 0.6875rem; color: #94a3b8; }
.cmp-tier:hover { background: #f8fafc; }
.cmp-tier.is-on {
  border-color: #0062ff; background: hsl(var(--brand-2) / 0.05);
  box-shadow: inset 0 0 0 1px #0062ff;
}
.cmp-tier.is-on b { color: #0062ff; }

/* 高级参数区（默认 hidden，切高级展开） */
.cmp-adv { display: flex; flex-direction: column; gap: 0.15rem; }

/* 预警 ①：色彩断层（琥珀色浅黄 Alert） */
.cmp-warn {
  margin-top: 0.85rem; padding: 0.75rem;
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 0.5rem;
  font-size: 0.8125rem; line-height: 1.55; color: #92400e;
}
.cmp-warn b { font-weight: 600; }
.cmp-warn .cmp-warn-extra { display: block; margin-top: 0.25rem; }   /* ★ 第 44 轮：极限抽帧保色提示独立成行 */
.bgc-page .cmp-warn .cmp-warn-extra { margin-top: 0.2rem; }

/* 预警 ②：压缩比率 < 15%（橙色警告 + 快速修复链） */
.cmp-crit {
  margin-top: 0.85rem; padding: 0.75rem;
  background: #fff7ed; border: 1px solid #fdba74; border-radius: 0.5rem;
  font-size: 0.8125rem; line-height: 1.55; color: #9a3412;
}
.cmp-crit-title { display: block; font-weight: 700; margin-bottom: 0.4rem; }
.cmp-fixes { display: flex; flex-direction: column; gap: 0.3rem; align-items: flex-start; }
.cmp-fix {
  border: 0; background: none; cursor: pointer; padding: 0; text-align: left;
  font-size: 0.78125rem; color: #c2410c;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #fdba74;
}
.cmp-fix:hover { color: #9a3412; text-decoration-color: #c2410c; }

/* ===== 第 36 轮：单文件压缩 · 引流横幅 / 平台预设 / 胶囊参数（Chip Controls） ===== */
.cmp-banner {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem;
  margin-bottom: 1.25rem; padding: 0.65rem 0.9rem;
  border: 1px solid hsl(var(--brand-1) / 0.25); border-radius: 0.6rem;
  background: hsl(var(--brand-1) / 0.06);
  font-size: 0.8125rem; color: hsl(var(--muted-foreground)); line-height: 1.6;
}
.cmp-banner b { color: hsl(var(--brand-1)); font-weight: 700; }
.cmp-banner a { margin-left: auto; color: hsl(var(--brand-1)); font-weight: 600; text-decoration: none; white-space: nowrap; }
.cmp-banner a:hover { text-decoration: underline; }
.cmp-glbl { margin: 0 0 0.35rem; font-size: 0.75rem; font-weight: 600; color: hsl(var(--muted-foreground)); }
.cmp-presets { margin-bottom: 1.25rem; }
/* ★ 37c：平台预设「纯文字极简」化——去平台 Logo / 去规格副文本，
   纯文字药丸胶囊（浅灰底 → hover 加深 → 选中切品牌蓝），flex-wrap 流式折行，
   消除旧图文卡的全部垂直占位。规格详情改由 .cmp-preset-note 回显 + 按钮 title。 */
.cmp-preset-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.cmp-preset {
  border: 0;   /* 铁律双保险：全局 button reset 之外，自带底色的按钮必须显式 border:0 */
  padding: 0.32rem 0.95rem; border-radius: 999px;
  background: #f1f5f9; color: #475569;
  font-size: 0.8125rem; line-height: 1.6; letter-spacing: 0.01em;
  cursor: pointer; white-space: nowrap;
  transition: background .15s, color .15s, box-shadow .15s;
}
.cmp-preset:hover { background: #e2e8f0; }
.cmp-preset.is-on {
  background: hsl(var(--brand-1)); color: #fff; font-weight: 600;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .14);
}
.cmp-preset-note { margin: 0.5rem 0 0; font-size: 0.75rem; color: hsl(var(--brand-1)); }
.cmp-chip-group { margin-bottom: 1rem; }
.cmp-chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.cmp-chip {
  padding: 0.34rem 0.8rem; border: 1px solid hsl(var(--border)); border-radius: 999px;
  background: #fff; font-size: 0.8125rem; color: #475569; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.cmp-chip:hover { border-color: hsl(var(--brand-1) / 0.5); color: hsl(var(--brand-1)); }
.cmp-chip.is-on { background: hsl(var(--brand-1)); border-color: hsl(var(--brand-1)); color: #fff; font-weight: 600; }
.cmp-custom-row { display: flex; align-items: center; gap: 0.6rem; margin: -0.4rem 0 1rem; }
.cmp-custom-row .field { margin-bottom: 0; flex: 0 1 14rem; }
.cmp-custom-row[hidden] { display: none !important; }
.cmp-subrow { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin: -0.5rem 0 1rem; }
.cmp-subrow .field { margin-bottom: 0; flex: 0 1 9rem; }
.cmp-subrow[hidden] { display: none !important; }
.cmp-subrow .cmp-chip { padding: 0.26rem 0.65rem; font-size: 0.75rem; }


/* 单行「导出体积预估」条（.est-inline —— 无实时预览的工具用）。
   ★ 必须可换行：文案含「约 1234 KB（省 42%）」+ 备注，窄栏位不能顶出去。 */
.est-inline {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.3rem 0.4rem;
  margin: 0.7rem 0 0.9rem; padding: 0.6rem 0.75rem;
  border: 1px solid hsl(var(--brand-2) / 0.26);
  border-radius: 0.7rem;
  background: hsl(var(--brand-2) / 0.06);
  font-size: 0.8125rem; color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums; line-height: 1.4;
  min-width: 0; overflow-wrap: anywhere;
}
.est-inline .ei-ico {
  flex-shrink: 0; font-weight: 700; color: hsl(var(--brand-2));
  width: 1.05rem; text-align: center;
}
.est-inline .ei-txt { min-width: 0; }
.est-inline .ei-txt > b { color: hsl(var(--brand-1)); font-weight: 700; }
.est-inline .ei-note { opacity: 0.8; }

/* ★ 第 35 轮：预估免责声明（全局统一，极小浅灰 */
.est-note {
  display: block; flex-basis: 100%;
  font-size: 0.65rem; line-height: 1.35; color: #9ca3af;
  margin-top: 0.15rem; user-select: none;
}
.live-stats .est-note, span.est-note { display: inline; margin-top: 0; }

/* ======================================================================
   11.3 第 39 轮：批量压缩「左右分栏 SaaS 工作台」（.bgc-*）
   左 ≈65-70% = 待处理文件池（紧凑行列表：缩略图 + 文件名 + 体积/尺寸/帧数 + 移除，限高内部滚动）
   右 300-350px = 全局参数控制台（平台预设 / 四组胶囊卡片 / 高级参数 / 智能预警 / 预估 / 执行）
   ★ 与 .v2g-* 同构（左工作区 + 右侧栏独立滚动），但参数全量胶囊化、卡片纯白 + shadow-sm。
   ★ 第 40 轮：待处理缩略图 64px → 192px（放大 3×）；行内标注尺寸/帧数；超长文件名折叠可展开。
   ====================================================================== */
.bgc-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; margin-top: 1.5rem; }
.bgc-left, .bgc-right { min-width: 0; display: flex; flex-direction: column; gap: 0.9rem; }
@media (min-width: 1024px) {
  .bgc-split { grid-template-columns: minmax(0, 1fr) 21rem; align-items: start; }   /* 右栏 336px（300-350 区间内） */
  /* ★ 第 41 轮：右栏不再自成滚动容器（原 max-height+overflow-y:auto 会把吸底页脚
     钉在该容器底部，而该容器底部常在视口之外 → 主按钮仍看不见）。
     改为让页面整体滚动，.bgc-dock 以 sticky bottom:0 吸附**视口底部**，
     从而「无论参数怎么滚，主按钮永远可见」。 */
  .bgc-right { padding: 2px; }
}
@media (max-width: 1023px) { .bgc-right { position: static; max-height: none; overflow: visible; } }

/* ---- 通用卡片：纯白底 + 浅阴影（= bg-white + shadow-sm） ---- */
.bgc-page .bgc-card {
  border: 1px solid hsl(var(--border) / 0.75);
  border-radius: 0.9rem;
  background: #fff;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
  padding: 0.85rem 0.9rem;
}
.bgc-card-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.45rem; margin-bottom: 0.6rem; }
.bgc-card-head b { font-size: 0.875rem; font-weight: 700; }
.bgc-card-head .sub { font-size: 0.7rem; color: hsl(var(--muted-foreground)); }
/* ★ 右栏 panel 容器降级为「透明列」：卡片各自承担边框与阴影，避免双层白卡。
   ★ 第 41 轮（呼吸感）：模块间留白 0.85rem → 1.5rem（space-y-6），
     并在相邻模块之间画一条浅灰细分割线（border-gray-100），提升模块区分度。 */
.bgc-page .panel {
  border: 0; border-radius: 0; background: transparent; box-shadow: none;
  padding: 0; display: flex; flex-direction: column; gap: 1.5rem;
}
/* 模块间浅灰细分割线：用 ::after 画在留白正中（不侵占卡片自身圆角 / 内边距） */
.bgc-page .panel > *:not(:last-child) { position: relative; }
.bgc-page .panel > *:not(:last-child)::after,
.bgc-page .cmp-simple > *:not(:last-child)::after {
  content: ""; position: absolute; left: 2px; right: 2px; bottom: -0.75rem;
  height: 1px; background: #f3f4f6; pointer-events: none;
}
/* ★ 第 41 轮：四组参数胶囊卡（目标大小 / 压缩策略 / 尺寸模式 / 抽帧比例）
   —— 之前 .cmp-simple 无任何布局规则，卡片是「零间距相贴」的（用户感知为「过密」）。
   补上列向 1.5rem 间距（space-y-6），组与组之间形成清晰呼吸带。 */
.bgc-page .cmp-simple { display: flex; flex-direction: column; gap: 1.5rem; }
.bgc-page .cmp-simple > *:not(:last-child) { position: relative; }

/* ---- 左栏：待处理文件池 ---- */
.bgc-pool-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.65rem; }
.bgc-pool-title { font-size: 0.9375rem; font-weight: 700; }
.bgc-pool-count { font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
.bgc-pool-spacer { flex: 1 1 auto; }
.bgc-mini {
  display: inline-flex; align-items: center; gap: 0.25rem;
  /* ★ 第 41 轮：由「描边药丸」改为标准次级小按钮（bg-gray-100 hover:bg-gray-200 rounded text-sm）。
     显式 border:0 —— gif.css 全局 button reset 给的是 background:none，此处自带背景色必须写死边框。 */
  border: 0; background: #f3f4f6; cursor: pointer;
  border-radius: 0.375rem; padding: 0.25rem 0.75rem;
  font-size: 0.875rem; font-weight: 600; color: #374151;
  white-space: nowrap;                       /* 窄屏禁止「继续添加」逐字折行 */
  transition: background-color .15s, color .15s;
}
/* 窄屏（<480px）：池头改两行流式——标题+计数一行，操作按钮另起一行 */
@media (max-width: 479px) {
  .bgc-pool-head { flex-wrap: wrap; row-gap: 0.45rem; }
  .bgc-pool-spacer { display: none; }
  .bgc-pool-title { font-size: 0.875rem; white-space: nowrap; }
}
.bgc-mini:hover { background: #e5e7eb; color: #111827; }
.bgc-mini.is-danger:hover { background: #fee2e2; color: #b91c1c; }
.bgc-mini svg { width: 0.85em; height: 0.85em; }
/* ★ 第 41 轮：提示语从「卡片外独立段落」移入文件池卡片底部，并调浅（text-gray-400 text-xs text-center mt-4） */
.bgc-pool-tip { margin: 1rem 0 0; font-size: 0.75rem; line-height: 1.5; color: #9ca3af; text-align: center; }

/* ★ 紧凑行列表：一行一条、行高固定、绝对禁止全尺寸大图预览；
     列表区限高 60vh + 内部滚动（max-h-[60vh] overflow-y-auto 等效） */
.bgc-page .list-wrap {
  margin: 0; padding-right: 2px;
  max-height: 60vh; overflow-y: auto; overscroll-behavior: contain;
}
.bgc-page .file-row {
  display: flex; align-items: center; justify-content: space-between; gap: 0.7rem;
  min-height: 4.6rem; padding: 0.45rem 0.55rem;
  border: 1px solid hsl(var(--border) / 0.7); border-radius: 0.7rem;
  background: hsl(var(--muted) / 0.28);
  transition: background-color .15s, border-color .15s;
}
.bgc-page .file-row + .file-row { margin-top: 0.4rem; }
.bgc-page .file-row:hover { background: hsl(var(--accent) / 0.55); border-color: hsl(var(--brand-2) / 0.45); }
.bgc-page .file-row .fr-thumb {
  width: 12rem; height: 12rem; flex-shrink: 0;         /* ★ 第 40 轮：4rem→12rem（预览放大 3×） */
  border-radius: 0.5rem; overflow: hidden;
  background: #f3f4f6;                                  /* bg-gray-100 */
  border: 1px solid hsl(var(--border) / 0.6);
  display: flex; align-items: center; justify-content: center;
  color: hsl(var(--muted-foreground));
}
.bgc-page .file-row .fr-thumb img, .bgc-page .file-row .fr-thumb video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.bgc-page .file-row .fr-meta { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 0.1rem; }
.bgc-page .file-row .fr-meta b {
  font-size: 0.8125rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: pointer;                                      /* ★ 第 40 轮：文件名可点击展开/收起 */
}
/* ★ 第 40 轮：超长文件名默认折叠为单行省略号，点击后展开为多行（最多 4 行） */
.bgc-page .file-row .fr-meta b.is-exp {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4;
  white-space: normal; overflow-wrap: anywhere; overflow: hidden;
}
.bgc-page .file-row .fr-meta span { font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.bgc-page .file-row .fr-act { flex: 0 0 auto; display: flex; align-items: center; }
.bgc-page .file-row .fr-del:hover { border-color: hsl(0 84% 60% / 0.5); color: hsl(0 72% 46%); }

/* ---- 右栏：胶囊卡片在卡片体内的边距重排 ---- */
.bgc-card .cmp-mode-head { margin-bottom: 0; }
.bgc-card .cmp-chip-row { gap: 0.4rem; }
.bgc-card .cmp-tiers { gap: 0.4rem; }
.bgc-card .cmp-subrow { margin: 0.5rem 0 0; }
.bgc-preset-note { margin: 0.6rem 0 0; font-size: 0.75rem; font-weight: 600; color: #059669; }   /* ★ 绿字回显 */
/* 侧栏仅 336px：预设药丸禁止折成两行（"微信/QQ表情" 曾被拆成两行） */
.bgc-page .cmp-preset { white-space: nowrap; }
.bgc-exec { padding: 0.9rem; }
.bgc-exec .btn-grad { width: 100%; }

/* ★ 第 42 轮：行右侧独立「对比数据列」（承接第 41 轮口径：明细在左栏行内）
   结构 = 原体积(灰) ➔(浅灰箭头) 预估区间(品牌蓝加粗)。
   行容器本身已是 flex items-center justify-between —— 左信息 / 中对比 / 右缘[X]。
   注意：fr-est 已不在 .fr-meta 内，不受 `.fr-meta span` 灰色规则影响。 */
.bgc-page .file-row .fr-estcol {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; row-gap: 0.1rem;                       /* 窄屏兜底：允许折行但不溢出 */
  font-size: 0.8125rem; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.bgc-page .file-row .fr-estcol .fr-old { color: hsl(var(--muted-foreground)); }
.bgc-page .file-row .fr-estcol .fr-arrow { color: #9ca3af; font-size: 0.75rem; margin: 0 0.15rem; }
.bgc-page .file-row .fr-estcol .fr-est { color: #0062ff; font-weight: 700; }          /* 品牌蓝 */
.bgc-page .file-row .fr-estcol .fr-est.is-pending { color: #9ca3af; font-weight: 600; }
.bgc-page .file-row .fr-estcol .fr-est.is-fail { color: #b45309; font-weight: 600; }
/* ★ 第 42 轮窄屏兜底（r39 G4）：≤640px 时 12rem 缩略图 + 对比列 + [X] 挤不进一行，
   允许行内换行 —— 对比列与 [X] 折到第二行（对比列右对齐、与 [X] 同排），信息不丢、零溢出。 */
@media (max-width: 640px) {
  .bgc-page .file-row { flex-wrap: wrap; row-gap: 0.3rem; }
  .bgc-page .file-row .fr-estcol { flex: 1 1 auto; }
}

/* ★ 预估面板在窄侧栏内的换行兜底（长文件名 / 区间文案绝不撑出横向滚动）
   ★ 第 42 轮：右栏预估面板收敛为「单行全局汇总」共 N 个文件 | 预计总计：约 A - B
     —— est-sum 与 est-foot 同排 flex（分隔符 | 由 .est-sum::after 绘制），
     免责声明 est-note 独占一行；逐文件对比在左栏行右侧 .fr-estcol。 */
.bgc-page .est-panel {
  margin: 0; overflow-x: hidden; border: 0; background: transparent; padding: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.45rem;
}
.bgc-page .est-panel .est-sum {
  font-size: 0.8125rem; line-height: 1.45; white-space: nowrap;
  color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums;
}
.bgc-page .est-panel .est-sum b { color: hsl(var(--foreground)); font-weight: 700; }
.bgc-page .est-panel .est-sum::after { content: "|"; margin-left: 0.45rem; color: #e5e7eb; }
.bgc-page .est-panel .est-foot { font-size: 0.8125rem; line-height: 1.45; }
.bgc-page .est-panel .est-foot .est-note {
  flex-basis: 100%; display: block; margin-top: 0.25rem; font-size: 0.6875rem;
}

/* ★ 第 41 轮：吸底页脚 —— 「全局预估 + 批量压缩主按钮」包裹其中。
   桌面端以 sticky bottom:0 吸附**视口底部**（此时右栏不再自成滚动容器，由页面整体滚动），
   因此无论上方参数滚到哪里，主按钮永远停在可视区底部；窄屏（<1024px）回落常规流以免遮挡。 */
.bgc-dock {
  display: flex; flex-direction: column; gap: 0.75rem;
  padding: 1rem 2px;                      /* 第 42 轮：p-4（水平由列内边距兜住） */
  border-top: 1px solid #f3f4f6;          /* border-t border-gray-100 */
  background: rgba(255, 255, 255, .92);   /* bg-white/90 */
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.05);   /* ★ 第 42 轮：顶部投影强化悬浮感 */
  z-index: 10;
}
@media (min-width: 1024px) { .bgc-dock { position: sticky; bottom: 0; } }
.bgc-dock .bgc-exec { border: 0; box-shadow: none; background: transparent; padding: 0; }

/* ★ 压缩比 <15% 告警：本工作台改用黄色底（与需求口径一致），
     类名 / 标题文案 / 三个一键修复入口保持原样（测试守门不变） */
.bgc-page .cmp-crit { margin: 0; background: #fefce8; border-color: #fde047; color: #854d0e; }
.bgc-page .cmp-crit .cmp-fix { color: #a16207; text-decoration-color: #fde047; }
.bgc-page .cmp-crit .cmp-fix:hover { color: #713f12; text-decoration-color: #ca8a04; }
.bgc-page .cmp-warn { margin: 0; }

/* ======================================================================
   12. 结果卡片（.result-card 系 —— 全部工具的输出行）
   ★ 第 32 轮重构：flex items-center justify-between p-4 两端布局；
     左组 .rc-left = 80px object-cover 小卡缩略图（rounded-md + gray-200 边框）
     + 文件名/体积垂直居中；右侧 = 眼睛图标「预览」按钮 + 下载。
     ★ 预览改为居中 Modal（.rc-modal），旧行内展开 .rc-full 已废除。
   ====================================================================== */
.result-card {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem;
  border: 1px solid hsl(var(--border) / 0.8);
  border-radius: 0.85rem; padding: 1rem;
  background: #fff; transition: border-color .15s, background-color .15s;
}
.result-card:hover { border-color: hsl(var(--brand-2) / 0.45); background: hsl(var(--accent) / 0.4); }
.rc-left { display: flex; align-items: center; gap: 1rem; min-width: 0; flex: 1; }
.rc-prev {
  height: 5rem; width: 5rem; flex-shrink: 0; overflow: hidden;
  border-radius: 0.375rem; background: hsl(var(--muted));
  border: 1px solid #e5e7eb;
  display: flex; align-items: center; justify-content: center;
  cursor: zoom-in; transition: box-shadow .15s;
}
.rc-prev:hover { box-shadow: 0 0 0 2px hsl(var(--brand-2) / 0.35); }
.rc-prev img, .rc-prev video, .rc-prev canvas { width: 100%; height: 100%; object-fit: cover; }
.rc-meta { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.rc-meta b { font-size: 0.8125rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rc-meta span { font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
.rc-act { display: flex; flex-shrink: 0; align-items: center; gap: 0.35rem; }
/* 眼睛图标「预览」轻量按钮（hover 浅灰底） */
.rc-preview-btn:hover { background: #f3f4f6; }

/* ---- 结果预览 Modal（第 32 轮）：深色遮罩 + 白底卡片，居中大图 ---- */
.rc-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; }
.rc-modal-mask { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.7); }
.rc-modal-card {
  position: relative; z-index: 1; background: #fff; border-radius: 1rem;
  box-shadow: 0 25px 60px rgba(0, 0, 0, 0.35);
  width: min(48rem, calc(100vw - 2rem));
  max-height: calc(100vh - 4rem); display: flex; flex-direction: column; overflow: hidden;
}
.rc-modal-close {
  position: absolute; top: 0.6rem; right: 0.6rem; z-index: 2;
  width: 2.1rem; height: 2.1rem; display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 9999px; background: rgba(255, 255, 255, 0.92); color: #374151;
  cursor: pointer; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}
.rc-modal-close:hover { background: #fff; color: #111827; }
.rc-modal-stage { display: flex; align-items: center; justify-content: center; background: #111827; min-height: 12rem; }
.rc-modal-stage img, .rc-modal-stage video {
  display: block; max-width: 100%; max-height: 70vh; width: auto; height: auto; object-fit: contain;
}
.rc-modal-foot {
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  padding: 0.85rem 1rem;
}
.rc-modal-size { font-size: 0.8125rem; color: #4b5563; font-variant-numeric: tabular-nums; }

/* ---- 品牌字标（「慢」字蓝底方块）----
   ★ 第 33 轮修复错位：方块必须有 inline-flex 居中 + 字符 line-height:1，
     否则「慢」按行内基线排布，视觉上偏移到方块左上角。 */
.brand-logo {
  background: linear-gradient(135deg, hsl(var(--brand-1)), hsl(var(--brand-2)));
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; border-radius: 0.55rem; overflow: hidden;
}
.brand-logo-char {
  color: #fff; font-weight: 800; font-size: 1.3rem; line-height: 1;
  font-family: "'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif";
  user-select: none;
  transform: translateY(0.02em);   /* 中文字形基线补偿，视觉垂直居中 */
}
@media (min-width: 640px) { .brand-logo-char { font-size: 1.45rem; } }

/* ======================================================================
   13. 视频转 GIF · 现代编辑器工作台（状态隔离 + 左右分栏）
   ----------------------------------------------------------------------
   设计目标（对齐 Canva / Kap 这类现代编辑器）：
     ① 状态隔离：初始只留「巨大柔和拖拽区」；上传后平滑切入左右分栏工作台。
     ② 左右分栏：左侧 = 视频预览 + Icon 标注工具栏 + 双滑块时间轴；
                  右侧 = 参数悬浮卡（带刻度 Slider）+ 底部放大主 CTA。
     ③ 样式细节：统一 rounded-xl（0.75rem）、极轻柔和阴影、充足留白。

   ★ 圆角/间距取自 Tailwind 刻度（近似值，无构建依赖）：
     rounded-xl = 0.75rem   rounded-2xl = 1rem     rounded-3xl = 1.5rem
     p-5 = 1.25rem          p-6 = 1.5rem           gap-4 = 1rem
   ★ 柔和阴影（Soft Shadow）= 极小偏移 + 大模糊 + 极低透明度，
     与「重投影」区别开，只用于提升层级感，不喧宾夺主。
   ====================================================================== */
:root {
  --v2g-radius: 0.75rem;        /* rounded-xl */
  --v2g-radius-lg: 1rem;        /* rounded-2xl */
  --v2g-radius-xl: 1.5rem;      /* rounded-3xl */
  --v2g-soft: 0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 16px rgba(15, 23, 42, 0.05);
  --v2g-soft-lg: 0 1px 3px rgba(15, 23, 42, 0.05), 0 12px 32px rgba(15, 23, 42, 0.07);
  --v2g-gap: 1.25rem;
}

/* ---------- 13.1 视区容器（拖拽区 ↔ 工作台 交替） ---------- */
/* 未上传时工作台整体不占位；上传后淡入上滑，形成「切换视区」的观感。 */
.v2g-ws { display: none; }
.v2g-ws.is-open {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--v2g-gap);
  animation: v2gIn .34s cubic-bezier(.22, .61, .36, 1) both;
}
@keyframes v2gIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
/* 大宽屏（16:9 桌面）→ 左预览区自适应 + 右参数栏固定宽 */
@media (min-width: 1024px) {
  .v2g-ws.is-open { grid-template-columns: minmax(0, 1fr) 21rem; align-items: start; }
}
@media (prefers-reduced-motion: reduce) {
  .v2g-ws.is-open { animation: none; }
}

/* ---------- 13.2 巨大柔和的拖拽上传区（Hero Dropzone） ---------- */
.dz-hero {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1.15rem;
  width: 100%; min-height: 22rem;
  padding: 3.5rem 2rem;
  text-align: center; cursor: pointer;
  border: 2px dashed hsl(var(--brand-2) / 0.34);
  border-radius: var(--v2g-radius-xl);
  background:
    radial-gradient(120% 90% at 50% 0%, hsl(var(--brand-3) / 0.10), transparent 62%),
    hsl(var(--muted) / 0.45);
  transition: border-color .2s ease, background-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.dz-hero:hover, .dz-hero.over {
  border-color: hsl(var(--brand-2));
  background:
    radial-gradient(120% 90% at 50% 0%, hsl(var(--brand-3) / 0.18), transparent 62%),
    hsl(var(--accent) / 0.55);
  box-shadow: var(--v2g-soft-lg);
}
.dz-hero:active { transform: scale(.995); }
/* 云端上传 Icon：大号、蓝底渐变、带柔和光晕 */
.dz-hero-ico {
  display: flex; align-items: center; justify-content: center;
  width: 5.5rem; height: 5.5rem;
  border-radius: 1.75rem;
  color: #fff;
  background: linear-gradient(135deg, hsl(var(--brand-1)), hsl(var(--brand-3)));
  box-shadow: 0 10px 28px hsl(var(--brand-1) / 0.28);
}
.dz-hero-ico svg { width: 2.6rem; height: 2.6rem; }
.dz-hero-main { display: flex; flex-direction: column; gap: 0.45rem; }
.dz-hero-main b { font-size: 1.2rem; font-weight: 700; letter-spacing: -0.01em; }
.dz-hero-main span { font-size: 0.875rem; color: hsl(var(--muted-foreground)); }
.dz-hero-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; }
.dz-hero-tags i {
  font-style: normal; font-size: 0.6875rem; font-weight: 600;
  padding: 0.2rem 0.6rem; border-radius: 999px;
  background: hsl(var(--background) / 0.85); color: hsl(var(--muted-foreground));
  border: 1px solid hsl(var(--border) / 0.8);
}
.dz-hero .btn-primary { padding: 0.6rem 1.5rem; border-radius: 999px; font-weight: 700; }
/* ★ file input 是 hidden 的（hidden 属性已被 [hidden]{display:none!important} 兜住），
   再加一层防御：某些浏览器对 hidden + flex 子项的处理不一致，这里显式钉死。 */
.dz-hero input[type="file"] { display: none !important; }

/* ---------- 13.3 通用卡片（软阴影 + 圆角 + 留白） ---------- */
.v2g-card {
  border: 1px solid hsl(var(--border) / 0.7);
  border-radius: var(--v2g-radius-lg);
  background: hsl(var(--background) / 0.95);
  box-shadow: var(--v2g-soft);
  overflow: hidden;
}
.v2g-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  padding: 0.9rem 1.15rem;
  border-bottom: 1px solid hsl(var(--border) / 0.55);
}
.v2g-card-head b { font-size: 0.875rem; font-weight: 700; }
.v2g-card-head .sub { font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
.v2g-card-body { padding: 1.15rem; }

/* ---------- 13.4 左侧：视频预览舞台 ---------- */
.v2g-stage {
  position: relative; width: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
  background: hsl(var(--muted) / 0.55);
}
.v2g-stage-inner {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  line-height: 0; max-width: 100%;
}
/* ★ 自适应等比缩放 + 圆角：宽高比由 JS 按视频元数据写入 aspect-ratio */
.v2g-stage video {
  display: block;
  max-width: 100%; max-height: 30rem;
  border-radius: var(--v2g-radius);
  background: #000;
  object-fit: contain;
}
.v2g-stage .ov-layer { border-radius: var(--v2g-radius); overflow: hidden; }

/* 底栏：时间轴 + 片段读数 */
.v2g-foot {
  padding: 0.9rem 1.15rem 1.15rem;
  border-top: 1px solid hsl(var(--border) / 0.55);
  background: hsl(var(--muted) / 0.22);
}
.v2g-foot-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 0.4rem 0.9rem; margin-bottom: 0.7rem;
}
.v2g-foot-head .t { font-size: 0.8125rem; font-weight: 700; }
.v2g-foot-head .v { font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
.v2g-foot-head .v b { color: hsl(var(--brand-1)); font-weight: 700; }

/* ---------- 13.5 双滑块可视化时间轴 ---------- */
.v2g-tl { padding-top: 0.15rem; }
.v2g-tl-rail {
  position: relative; height: 1.5rem;
  margin: 0 0.55rem;                    /* 给两端把手留出溢出空间 */
  touch-action: none !important;        /* 拖动时不要让页面跟着滚 */
}
/* 轨道 */
.v2g-tl-track {
  position: absolute; left: 0; right: 0; top: 50%; height: 0.4rem;
  transform: translateY(-50%);
  border-radius: 999px; background: hsl(var(--border));
}
/* 选区高亮（在两个把手之间） */
.v2g-tl-sel {
  position: absolute; top: 50%; height: 0.4rem;
  transform: translateY(-50%);
  border-radius: 999px;
  background: linear-gradient(90deg, hsl(var(--brand-1)), hsl(var(--brand-3)));
}
/* 把手 */
.v2g-tl-h {
  position: absolute; top: 50%; z-index: 3;
  width: 1.05rem; height: 1.05rem; margin-left: -0.525rem; margin-top: -0.525rem;
  border-radius: 999px; background: #fff;
  border: 2px solid hsl(var(--brand-1));
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.28);
  cursor: grab;
  transition: box-shadow .15s ease, transform .12s ease;
}
.v2g-tl-h:hover { box-shadow: 0 0 0 6px hsl(var(--brand-2) / 0.16), 0 1px 4px rgba(15, 23, 42, 0.28); }
.v2g-tl-h.is-active { cursor: grabbing; transform: scale(1.12); box-shadow: 0 0 0 8px hsl(var(--brand-2) / 0.22), 0 1px 4px rgba(15, 23, 42, 0.3); }
/* 刻度 */
.v2g-tl-scale {
  position: relative; height: 1.05rem; margin: 0.15rem 0.55rem 0;
  font-size: 0.6875rem; color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}
/* ★ 三个刻度必须显式定位：absolute 无 left 时全部塌缩到静态起点（实测踩坑） */
.v2g-tl-scale span { position: absolute; top: 0; white-space: nowrap; }
.v2g-tl-scale span:nth-child(1) { left: 0; }
.v2g-tl-scale span:nth-child(2) { left: 50%; transform: translateX(-50%); }
.v2g-tl-scale span:nth-child(3) { left: 100%; transform: translateX(-100%); }
/* 视频元数据未就绪 / 时长未知 → 时间轴整体置灰且不可拖 */
.v2g-tl.is-off, .v2g-tl.is-off * { cursor: not-allowed; }
.v2g-tl.is-off .v2g-tl-track { opacity: 0.5; }
.v2g-tl.is-off .v2g-tl-sel { opacity: 0.35; }
.v2g-tl.is-off .v2g-tl-h { opacity: 0.6; }
.v2g-tl.is-off .v2g-tl-h:hover { box-shadow: 0 1px 4px rgba(15, 23, 42, 0.28); }

/* ---------- 13.6 标注工具栏（Icon 化） ---------- */
.v2g-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem;
  padding: 0.55rem 0.65rem;
  border-bottom: 1px solid hsl(var(--border) / 0.55);
  background: hsl(var(--background) / 0.98);
}
.v2g-toolbar-btn {
  display: inline-flex; align-items: center; gap: 0.35rem;
  height: 2.1rem; padding: 0 0.7rem;
  border: 1px solid transparent; border-radius: var(--v2g-radius);
  background: transparent; color: hsl(var(--foreground) / 0.82);
  font-family: inherit; font-size: 0.78125rem; font-weight: 600;
  white-space: nowrap; cursor: pointer;
  transition: background-color .14s ease, color .14s ease, border-color .14s ease;
}
.v2g-toolbar-btn svg { flex-shrink: 0; width: 1.05rem; height: 1.05rem; }
.v2g-toolbar-btn:hover { background: hsl(var(--accent)); color: hsl(var(--brand-1)); border-color: hsl(var(--brand-2) / 0.28); }
.v2g-toolbar-btn:active { transform: translateY(1px); }
.v2g-toolbar-btn.is-ghost { color: hsl(var(--muted-foreground)); }
.v2g-toolbar-btn.is-danger:hover { background: hsl(0 84% 60% / 0.1); color: hsl(0 72% 46%); border-color: hsl(0 84% 60% / 0.3); }
/* 分隔线 */
.v2g-toolbar-sep { width: 1px; height: 1.35rem; margin: 0 0.3rem; background: hsl(var(--border)); }
.v2g-toolbar-spacer { flex: 1; min-width: 0.5rem; }
/* 工具栏右侧的片段计数徽标 */
.v2g-toolbar-badge {
  font-size: 0.6875rem; font-weight: 700; color: hsl(var(--brand-1));
  background: hsl(var(--brand-2) / 0.12);
  padding: 0.18rem 0.55rem; border-radius: 999px;
  white-space: nowrap;
}
/* 只显示图标、不显示文字的紧凑按钮（窄屏用） */
.v2g-toolbar-btn.icon-only { padding: 0 0.5rem; }
.v2g-toolbar-btn.icon-only .lb { display: none; }
@media (max-width: 560px) {
  .v2g-toolbar-btn .lb { display: none; }
  .v2g-toolbar-btn { padding: 0 0.55rem; }
}

/* ---------- 13.7 右侧参数栏 ---------- */
.v2g-side { display: flex; flex-direction: column; gap: var(--v2g-gap); }
@media (min-width: 1024px) {
  /* 粘性悬浮卡片：长页面滚动时参数始终可见 */
  .v2g-side { position: sticky; top: 1rem; }
}
.v2g-side .field { margin-bottom: 1.05rem; }
.v2g-side .field:last-child { margin-bottom: 0; }

/* 带刻度 Slider：数值右对齐、刻度在下方 */
.v2g-slider { display: flex; flex-direction: column; gap: 0.35rem; }
.v2g-slider-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.v2g-slider-top > label { font-size: 0.8125rem; font-weight: 600; color: hsl(var(--foreground) / 0.85); }
.v2g-slider-val {
  min-width: 3.4rem; text-align: right;
  font-size: 0.75rem; font-weight: 700; color: hsl(var(--brand-1));
  font-variant-numeric: tabular-nums;
  background: hsl(var(--brand-2) / 0.1);
  padding: 0.1rem 0.45rem; border-radius: 0.45rem;
}
.v2g-slider input[type="range"] { width: 100%; margin: 0; }
.v2g-slider-scale {
  display: flex; justify-content: space-between;
  font-size: 0.6875rem; color: hsl(var(--muted-foreground));
  font-variant-numeric: tabular-nums;
}
/* 分段选择（替换 Select） */
.v2g-chips { display: flex; gap: 0.35rem; }
.v2g-chip {
  flex: 1; min-width: 0;
  height: 2.15rem; padding: 0 0.4rem;
  border: 1px solid hsl(var(--border)); border-radius: var(--v2g-radius);
  background: hsl(var(--background)); color: hsl(var(--muted-foreground));
  font-family: inherit; font-size: 0.78125rem; font-weight: 600;
  cursor: pointer; white-space: nowrap;
  transition: border-color .14s ease, background-color .14s ease, color .14s ease, box-shadow .14s ease;
}
.v2g-chip:hover { border-color: hsl(var(--brand-2) / 0.5); color: hsl(var(--brand-1)); }
.v2g-chip.is-on {
  border-color: hsl(var(--brand-1));
  background: hsl(var(--brand-2) / 0.1);
  color: hsl(var(--brand-1));
  box-shadow: 0 0 0 3px hsl(var(--brand-2) / 0.12);
}

/* ---------- 13.8 主 CTA（右栏最底部 · 全局最显眼） ---------- */
.v2g-cta-wrap {
  padding: 1.15rem;
  border-top: 1px solid hsl(var(--border) / 0.55);
  background: hsl(var(--muted) / 0.22);
}
.v2g-cta {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  width: 100%; min-height: 3.25rem;
  padding: 0.9rem 1.25rem;
  border: 0; border-radius: var(--v2g-radius);
  font-family: inherit; font-size: 1rem; font-weight: 700; letter-spacing: 0.01em;
  color: #fff; cursor: pointer;
  background: linear-gradient(135deg, hsl(var(--brand-1)), hsl(var(--brand-3)));
  box-shadow: 0 6px 18px hsl(var(--brand-1) / 0.32);
  transition: filter .15s ease, transform .12s ease, box-shadow .15s ease;
}
.v2g-cta:hover:not(:disabled) { filter: brightness(1.05); box-shadow: 0 10px 26px hsl(var(--brand-1) / 0.4); }
.v2g-cta:active:not(:disabled) { transform: translateY(1px); }
.v2g-cta:disabled { opacity: 0.6; cursor: not-allowed; box-shadow: none; }
.v2g-cta svg { width: 1.15rem; height: 1.15rem; }
.v2g-cta-note {
  margin-top: 0.55rem; text-align: center;
  font-size: 0.6875rem; color: hsl(var(--muted-foreground));
}
.v2g-cta .progress { margin-top: 0; }
/* CTA 下方的进度条（导出时出现） */
.v2g-cta-wrap .progress { margin-top: 0.7rem; }

/* ---------- 13.9 兼容层：老结构（.video-stage 等）在新工作台内不再出现，
   但 screen-recorder / crop-gif 仍在用，故此段只做隔离，不改老样式。 ---------- */
.v2g-stage .video-stage { margin: 0; padding: 0; background: transparent; border-radius: 0; }
.v2g-stage-list { padding: 0 1.15rem 1.15rem; }

/* ---------- 13.10 窄屏：分栏退化为单列堆叠 ---------- */
@media (max-width: 1023px) {
  .dz-hero { min-height: 17rem; padding: 2.5rem 1.25rem; }
  .dz-hero-ico { width: 4.5rem; height: 4.5rem; border-radius: 1.4rem; }
  .dz-hero-ico svg { width: 2.1rem; height: 2.1rem; }
  .dz-hero-main b { font-size: 1.05rem; }
  .v2g-stage video { max-height: 22rem; }
}

/* ---------- 13.11 当前文件条（工作台上方的「当前视频」信息栏） ----------
   ★ renderFileList 生成的 .fr-thumb / .fr-meta 在全站样式里从未定义过
     （历史遗留缺口，其它工具的文件列表一直是裸排版）。
     这里只在 .v2g-page 作用域内补齐，避免影响其它 17 个工具的既有验收。 */
.v2g-page .list-wrap { margin: 0 0 1rem; }
.v2g-page .file-row {
  padding: 0.55rem 0.75rem;
  border-radius: var(--v2g-radius);
  background: hsl(var(--muted) / 0.35);
  border-color: hsl(var(--border) / 0.55);
  box-shadow: none;
}
.v2g-page .file-row:hover { background: hsl(var(--accent) / 0.5); }
/* ★ 第 37b 轮：以下 4 条原本选中的是「旧横排 .file-row」的缩略图容器，
   但类名 .fr-thumb 在第 21 轮卡式改造后被 .fc-body 复用 → 2.4rem 方框把
   video 全宽预览挤成黑块（video-to-gif 顶部悬浮小方块的真实成因）。
   现全部限定到 .file-row 作用域内：旧横排若再现也只在横排里生效，
   永不误伤 .fc-body 内的全宽预览。 */
.v2g-page .file-row .fr-thumb {
  height: 2.4rem; width: 2.4rem; flex-shrink: 0;
  border-radius: 0.55rem; overflow: hidden;
  background: hsl(var(--muted)); border: 1px solid hsl(var(--border) / 0.6);
  display: flex; align-items: center; justify-content: center;
}
.v2g-page .file-row .fr-thumb img, .v2g-page .file-row .fr-thumb video { width: 100%; height: 100%; object-fit: cover; background: #000; }
.v2g-page .file-row .fr-meta { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 0.05rem; }
.v2g-page .file-row .fr-meta b {
  font-size: 0.8125rem; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.v2g-page .file-row .fr-meta span {
  font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums;
}
.v2g-page .file-row .fr-act { display: flex; flex-shrink: 0; align-items: center; gap: 0.35rem; }
.v2g-page .file-row .fr-act .icon-btn:hover { border-color: hsl(0 84% 60% / 0.5); color: hsl(0 72% 46%); }

/* ---------- 13.12 第 37 轮：浅色专业工作台（左右分栏升级） ----------
   左 = 主工作区（标注栏 + 画布卡 + 时间轴卡 + 结果卡），右 = 340px 参数控制台（独立滚动）。
   覆盖 13.1–13.8 的旧栅格与配色，浅色 SaaS 观感。 */
.v2g-ws.is-open { gap: 1rem; }
@media (min-width: 1024px) {
  .v2g-ws.is-open {
    grid-template-columns: minmax(0, 1fr) 21.5rem;   /* 左 ≈70% / 右 344px */
    align-items: start;
    padding: 1rem;
    background: hsl(var(--muted) / 0.38);
    border: 1px solid hsl(var(--border) / 0.5);
    border-radius: var(--v2g-radius-xl);
  }
  .v2g-left { display: flex; flex-direction: column; gap: 0.9rem; min-width: 0; }
  .v2g-side {
    position: sticky; top: 5.5rem;
    max-height: calc(100vh - 7.5rem);
    overflow-y: auto; overscroll-behavior: contain;
    padding: 2px;                                     /* 给滚动条留位，防溢出裁切 */
  }
}
/* 快捷工具栏：居中横向线性操作栏（悬浮态浅灰圆角） */
.v2g-toolbar { justify-content: center; border: 0; background: transparent; padding: 0.15rem 0; }
.v2g-toolbar-btn { border: 1px solid transparent; border-radius: 0.55rem; }
.v2g-toolbar-btn:hover { background: hsl(var(--accent)); color: hsl(var(--brand-1)); border-color: transparent; }
/* 画布卡：纯白 + 细边框 + 圆角；内部浅灰网格指示透明通道 */
.v2g-canvas-card { background: hsl(var(--background)); }
.v2g-stage {
  padding: 1.4rem;
  background:
    repeating-conic-gradient(hsl(var(--muted) / 0.55) 0 25%, hsl(var(--background)) 0 50%) 0 0 / 18px 18px;
}
.v2g-stage-inner { border-radius: var(--v2g-radius); overflow: hidden; }
/* 专业时间轴卡：时间读数行 + 品牌蓝选区 */
.v2g-tl-card { padding: 0.85rem 1.15rem 1.05rem; }
.v2g-tl-times {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 0.55rem;
  font-size: 0.8125rem; font-variant-numeric: tabular-nums; font-weight: 600;
}
.v2g-tl-times .cur { color: hsl(var(--brand-1)); }
.v2g-tl-times .total { color: hsl(var(--muted-foreground)); font-weight: 500; }
.v2g-tl-sel { background: hsl(var(--brand-1) / 0.18); }
.v2g-tl-h { background: hsl(var(--brand-1)); }
/* 导出卡：预计帧数/时长 大数字读数 */
.v2g-exp-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; }
.v2g-exp-stat {
  display: flex; flex-direction: column; gap: 0.15rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid hsl(var(--border) / 0.6); border-radius: var(--v2g-radius);
  background: hsl(var(--muted) / 0.3);
}
.v2g-exp-stat i { font-style: normal; font-size: 0.6875rem; color: hsl(var(--muted-foreground)); }
.v2g-exp-stat b { font-size: 1.05rem; font-weight: 700; color: hsl(var(--brand-1)); font-variant-numeric: tabular-nums; }
.v2g-est-line { margin: 0.6rem 0 0.2rem; font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }

/* ---------- 13.13 第 37 轮：结果信息卡（嵌入左栏底部） ---------- */
.v2g-result { display: flex; flex-direction: column; gap: 0.6rem; }
.v2g-result[hidden] { display: none !important; }
.v2g-rc-head { display: flex; align-items: baseline; gap: 0.6rem; padding: 0 0.15rem; }
.v2g-rc-head b { font-size: 0.9375rem; font-weight: 700; }
.v2g-rc-head span { font-size: 0.75rem; color: hsl(var(--muted-foreground)); }
.result-card.v2g-rc {
  display: flex; align-items: flex-start; gap: 1rem;
  margin: 0; padding: 1.1rem;
  border: 1px solid hsl(var(--border) / 0.8); border-radius: var(--v2g-radius-lg);
  background: hsl(var(--background)); box-shadow: var(--v2g-soft);
}
.v2g-rc-thumb {
  width: 8rem; height: auto; flex-shrink: 0; align-self: flex-start;
  border: 1px solid hsl(var(--border) / 0.7); border-radius: 0.5rem;
  background: repeating-conic-gradient(hsl(var(--muted) / 0.5) 0 25%, #fff 0 50%) 0 0 / 14px 14px;
}
.v2g-rc-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.7rem; }
.v2g-rc-meta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.25rem 0.9rem;
  font-size: 0.8125rem;
}
.v2g-rc-meta span { display: flex; gap: 0.4rem; min-width: 0; }
.v2g-rc-meta i { font-style: normal; color: hsl(var(--muted-foreground)); flex-shrink: 0; }
.v2g-rc-meta b { color: hsl(var(--foreground)); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
.v2g-rc-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.v2g-rc-actions .btn-grad { padding: 0.5rem 1.1rem; border-radius: 999px; font-size: 0.875rem; font-weight: 700; }
.v2g-rc-actions .btn-ghost { padding: 0.45rem 0.95rem; border-radius: 999px; font-size: 0.8125rem; }
.v2g-linkbtn {
  border: 0; background: none; cursor: pointer; padding: 0.25rem 0.4rem;
  font-size: 0.8125rem; color: hsl(var(--muted-foreground)); border-radius: 0.45rem;
}
.v2g-linkbtn:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
.v2g-linkbtn.is-danger:hover { color: hsl(0 72% 46%); background: hsl(0 84% 60% / 0.08); }
.v2g-rc-divider { height: 1px; background: hsl(var(--border) / 0.7); }
.v2g-rc-chain-title { font-size: 0.8125rem; font-weight: 600; color: hsl(var(--foreground) / 0.8); }
.v2g-rc-chain { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.v2g-chain-btn {
  padding: 0.3rem 0.75rem; border: 1px solid hsl(var(--border) / 0.8); border-radius: 999px;
  background: hsl(var(--muted) / 0.4); cursor: pointer;
  font-size: 0.75rem; color: hsl(var(--foreground) / 0.8);
  transition: background .15s, color .15s, border-color .15s;
}
.v2g-chain-btn:hover { background: hsl(var(--accent)); color: hsl(var(--brand-1)); border-color: hsl(var(--brand-2) / 0.4); }
/* 窄屏：结果卡纵向堆叠，分栏退化保持 13.10 的单列 */
@media (max-width: 1023px) {
  .result-card.v2g-rc { flex-direction: column; }
  .v2g-rc-thumb { width: 100%; max-height: 16rem; object-fit: contain; }
  .v2g-side { position: static; max-height: none; overflow: visible; }
}
