
:root{
  /* color-scheme 决定原生控件（复选框、滑块、日期选择器、滚动条）跟随哪套配色。
     不声明的话，深色主题下这些控件仍是浅色，会白得刺眼。 */
  color-scheme: light;
  --bg:#f5f6f9; --panel:#ffffff; --panel-2:#fafbfd; --border:#e6e8ef; --border-2:#eef0f6;
  /* muted / faint 都按 WCAG AA 正文标准取到 4.5:1 以上（原先 faint 只有 2.62:1） */
  --text:#151a22; --muted:#5f6675; --faint:#6a7280;
  --accent:#4f46e5; --accent-2:#7c3aed; --accent-soft:#eef0ff; --accent-text:#ffffff;
  --accent-glow:rgba(79,70,229,.28);
  --ok:#059669; --ok-soft:#e7f7f0; --warn:#b45309; --warn-soft:#fdf3e3; --err:#dc2626; --err-soft:#fdecec;
  --radius:14px; --radius-sm:9px;
  --shadow:0 1px 2px rgba(16,24,40,.05), 0 1px 3px rgba(16,24,40,.06);
  --shadow-md:0 4px 14px rgba(16,24,40,.09);
  --shadow-lg:0 10px 30px rgba(16,24,40,.12);
  --ring:0 0 0 3px rgba(79,70,229,.18);
  --code-bg:#f3f4f9;
}
html[data-theme="dark"]{
  color-scheme: dark;
  --bg:#0d1015; --panel:#151920; --panel-2:#11151b; --border:#252b36; --border-2:#1d222b;
  --text:#e7eaf0; --muted:#98a1b0; --faint:#7d8798;
  --accent:#7c8cff; --accent-2:#a78bfa; --accent-soft:#1e2440; --accent-text:#0d1015;
  --accent-glow:rgba(124,140,255,.26);
  --ok:#34d399; --ok-soft:#12291f; --warn:#fbbf24; --warn-soft:#2c2412; --err:#f87171; --err-soft:#2c1618;
  --shadow:0 1px 2px rgba(0,0,0,.5);
  --shadow-md:0 4px 14px rgba(0,0,0,.45);
  --shadow-lg:0 10px 30px rgba(0,0,0,.5);
  --ring:0 0 0 3px rgba(124,140,255,.26);
  --code-bg:#11151b;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:system-ui,-apple-system,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  font-size:14px; line-height:1.6; -webkit-font-smoothing:antialiased;
}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono","Courier New",monospace}
h1,h2,h3,h4,p{margin:0}
.muted{color:var(--muted)}
a{color:var(--accent)}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:var(--border);border-radius:8px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--faint);background-clip:content-box}
::-webkit-scrollbar-track{background:transparent}

/* ---- 键盘焦点环 ----
   原先只有输入框有聚焦样式，键盘 Tab 到按钮上完全看不出来焦点在哪。
   只在键盘导航（:focus-visible）时出现，鼠标点击不会多出一圈描边。 */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ---- 尊重系统的「减弱动态效果」 ---- */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important;
  }
}

.app{display:flex;height:100vh;overflow:hidden}

/* ============ Sidebar ============ */
.sidebar{
  width:272px;flex:none;background:var(--panel);border-right:1px solid var(--border);
  display:flex;flex-direction:column;z-index:60;
}
.brand{display:flex;align-items:center;gap:10px;padding:16px 16px 12px}
.logo{
  width:34px;height:34px;border-radius:10px;flex:none;display:grid;place-items:center;color:#fff;
  background:linear-gradient(135deg,var(--accent),var(--accent-2));box-shadow:0 4px 12px var(--accent-glow);
}
.brand-name{font-weight:700;font-size:15px;letter-spacing:.2px}
.brand-sub{font-size:11px;color:var(--faint);margin-top:-2px}
.search-wrap{padding:4px 12px 10px;position:relative}
.search-wrap .ic{position:absolute;left:22px;top:50%;transform:translateY(-50%);color:var(--faint);pointer-events:none;display:flex}
#search{
  width:100%;padding:9px 10px 9px 36px;border:1px solid var(--border);border-radius:var(--radius-sm);
  background:var(--panel-2);color:var(--text);font-size:13px;outline:none;transition:.15s;
}
#search:focus{border-color:var(--accent);background:var(--panel);box-shadow:0 0 0 3px var(--accent-soft)}
.nav{flex:1;overflow-y:auto;padding:4px 10px 20px}
.nav-group{margin-bottom:6px}
.nav-cat{
  display:flex;align-items:center;gap:7px;font-size:11px;font-weight:600;letter-spacing:.6px;
  color:var(--faint);text-transform:uppercase;padding:10px 8px 6px;
}
.nav-cat .cat-ic{display:flex;flex:none;opacity:.9}
.nav-item{
  display:flex;align-items:center;gap:10px;width:100%;text-align:left;border:0;background:transparent;
  color:var(--text);padding:8px 10px;border-radius:var(--radius-sm);cursor:pointer;font-size:13.5px;
  font-family:inherit;transition:.12s;position:relative;
}
.nav-item:hover{background:var(--panel-2)}
.nav-item.active{background:var(--accent-soft);color:var(--accent);font-weight:600}
/* 选中项左侧一道短竖条：扫视一长串列表时，比单纯换底色好找得多 */
.nav-item.active::before{
  content:'';position:absolute;left:-10px;top:50%;transform:translateY(-50%);
  width:3px;height:17px;border-radius:0 3px 3px 0;background:var(--accent);
}
html[data-theme="dark"] .nav-item.active{color:var(--accent)}
.nav-item .ic{display:flex;color:var(--faint);flex:none}
.nav-item.active .ic{color:var(--accent)}
.nav-item .label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
/* 「这个工具里还留着东西」（记住了设置或留着结果）时点一个小圆点，
   一眼就能看出刚才那个任务没丢 */
.nav-dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none;opacity:0;transition:opacity .15s}
.nav-item.has-state .nav-dot{opacity:1}
.nav-empty{color:var(--faint);font-size:13px;padding:24px 10px;text-align:center}
.side-foot{padding:10px 16px;border-top:1px solid var(--border);font-size:11px;color:var(--faint);display:flex;justify-content:space-between;align-items:center;gap:8px}

/* ============ Main ============ */
.main{flex:1;display:flex;flex-direction:column;min-width:0}
.topbar{
  height:56px;flex:none;display:flex;align-items:center;gap:12px;padding:0 18px;
  border-bottom:1px solid var(--border);background:var(--panel);z-index:30;
}
.crumb{display:flex;align-items:center;gap:9px;font-weight:600;overflow:hidden;white-space:nowrap}
.crumb .ic{display:flex;color:var(--accent)}
.crumb .sep{color:var(--faint);font-weight:400}
.spacer{flex:1}
.ibtn{
  width:34px;height:34px;border:1px solid var(--border);background:var(--panel-2);color:var(--text);
  border-radius:var(--radius-sm);display:grid;place-items:center;cursor:pointer;transition:.12s;flex:none;
}
.ibtn:hover{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
#menuBtn{display:none}
.content{flex:1;overflow-y:auto;padding:26px 26px 60px;scroll-behavior:smooth}
.tool{max-width:920px;margin:0 auto}
.tool-head{display:flex;gap:14px;align-items:flex-start;margin-bottom:20px}
.tool-ic{
  width:46px;height:46px;flex:none;border-radius:12px;display:grid;place-items:center;color:#fff;
  background:linear-gradient(135deg,var(--accent),var(--accent-2));box-shadow:0 4px 14px var(--accent-glow);
}
.tool-head h2{font-size:20px;letter-spacing:.2px}
.tool-head p{font-size:13px;margin-top:2px}
/* 标题块吃掉剩余宽度，把「清除记忆」按钮顶到右边 */
.tool-head .tool-title{flex:1;min-width:0}
.tool-reset{
  margin-left:auto;flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  border:1px solid var(--border);background:var(--panel);color:var(--faint);cursor:pointer;transition:.12s;
}
.tool-reset:hover{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
.tool-reset[hidden]{display:none}
.tool-body{display:flex;flex-direction:column;gap:16px}

/* ============ Components ============ */
.card{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden}
.card-head{padding:12px 16px;border-bottom:1px solid var(--border-2);display:flex;align-items:center;justify-content:space-between;gap:10px}
.card-head h3{font-size:13.5px;font-weight:600}
.card-body{padding:16px}
.card-body>*+*{margin-top:12px}
.field{display:block}
.field-label{display:block;font-size:12.5px;font-weight:600;color:var(--muted);margin-bottom:6px}
.field-label .hint{font-weight:400;color:var(--faint);font-style:normal;margin-left:6px}
.input{
  width:100%;padding:9px 11px;border:1px solid var(--border);border-radius:var(--radius-sm);
  background-color:var(--panel-2);color:var(--text);font-size:13.5px;font-family:inherit;outline:none;transition:.15s;
}
textarea.input{resize:vertical;line-height:1.6}
.input:focus{border-color:var(--accent);background-color:var(--panel);box-shadow:var(--ring)}
/* 占位文字用 --faint，深色主题下也能看清（浏览器默认值不可控） */
.input::placeholder{color:var(--faint);opacity:1}
/* 展开箭头直接用 ICONS 里同一份 Lucide chevron-down（启动时发布成 --ic-chevron）。
   原来用两段 linear-gradient 拼三角形，在高分屏上边缘发虚、还会随字号错位。 */
select.input{
  cursor:pointer;appearance:none;-webkit-appearance:none;padding-right:34px;
  background-image:var(--ic-chevron,none);
  background-repeat:no-repeat;background-position:calc(100% - 12px) center;background-size:15px 15px;
}
.row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.row>.input{width:auto;flex:1;min-width:90px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.btn{
  padding:9px 15px;border:1px solid var(--border);background:var(--panel-2);color:var(--text);
  border-radius:var(--radius-sm);font-size:13.5px;font-family:inherit;font-weight:500;cursor:pointer;transition:.12s;
  display:inline-flex;align-items:center;gap:7px;white-space:nowrap;
}
.btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.btn.primary{background:linear-gradient(135deg,var(--accent),var(--accent-2));color:#fff;border-color:transparent;box-shadow:0 2px 8px var(--accent-glow)}
.btn.primary:hover{color:#fff;filter:brightness(1.07);box-shadow:0 4px 14px var(--accent-glow)}
.btn.ghost{background:transparent;border-color:transparent;color:var(--muted)}
.btn.ghost:hover{background:var(--panel-2);color:var(--text)}
.btn.sm{padding:6px 11px;font-size:12.5px}
/* ---- 下载按钮 .dl：所有工具的「产出出口」----
   用户在这一屏里唯一必须找到的动作就是「把结果拿走」，所以给它最强的视觉权重：
   实心主题色 + 下载图标 + 比普通主按钮更大的尺寸 + 更重的阴影，
   刻意与 .btn.primary 拉开一档，避免「下载」淹没在一片同色按钮里。
   图标同样走 mask + currentColor，颜色自动跟随主题，路径数据只有 ICONS 一份。 */
.btn.dl,.ibtn.dl{
  background:linear-gradient(135deg,var(--accent),var(--accent-2));color:#fff;
  border-color:transparent;font-weight:600;box-shadow:0 3px 12px var(--accent-glow);
}
.btn.dl{padding:11px 19px;font-size:14px;border-radius:10px}
.ibtn.dl{width:auto;height:auto;padding:8px 14px;font-size:12.5px;border-radius:var(--radius-sm);
  display:inline-flex;align-items:center;gap:6px}
.ibtn.dl .ic{display:flex;align-items:center}
.btn.dl:hover,.ibtn.dl:hover{
  color:#fff;background:linear-gradient(135deg,var(--accent),var(--accent-2));border-color:transparent;
  filter:brightness(1.08);box-shadow:0 7px 20px var(--accent-glow);transform:translateY(-1px);
}
/* 放在 :hover 之后，按下时才盖得回「下沉」反馈（两者会同时命中） */
.btn.dl:active,.ibtn.dl:active{transform:translateY(1px)}
.btn.dl:before,.dl-title:before{
  content:'';width:16px;height:16px;flex:none;background-color:currentColor;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-image:var(--ic-download,none);mask-image:var(--ic-download,none);
}
/* 下载区：把终点动作从文件列表里提出来独立成块，左侧一道主题色竖条标记 */
.dl-bar{margin-top:14px;padding:13px 14px;background:var(--panel-2);border:1px solid var(--border);
  border-left:3px solid var(--accent);border-radius:var(--radius);box-shadow:var(--shadow)}
.dl-title{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:700;color:var(--accent);margin-bottom:8px}
.dl-note{font-size:12.5px;color:var(--muted);margin-bottom:10px}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  padding:6px 12px;border:1px solid var(--border);background:var(--panel-2);color:var(--text);
  border-radius:999px;font-size:12.5px;font-family:inherit;cursor:pointer;transition:.12s;
}
.chip:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.chip.on{background:var(--accent);border-color:var(--accent);color:#fff}
/* 页面选择器：页码格。每个格子就是一个页码，点一下切换选中 */
.pscope-sum{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px}
.pchips{
  display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;padding:8px;max-height:138px;overflow:auto;
  border:1px solid var(--border-2);border-radius:var(--radius-sm);background:var(--panel-2);
}
.pchip{
  min-width:34px;height:30px;padding:0 7px;border:1px solid var(--border);border-radius:7px;
  background:var(--panel);color:var(--muted);font-family:inherit;font-size:12.5px;cursor:pointer;
  font-variant-numeric:tabular-nums;transition:.12s;
}
.pchip:hover{border-color:var(--accent);color:var(--accent)}
.pchip.on{background:var(--accent);border-color:var(--accent);color:var(--accent-text);font-weight:700}
.pchip:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
/* 逐页裁剪的「页面状态条」：哪几页已经单独设过框一眼看得出来。
   .set = 已单独设置（绿）　.cur = 当前正开着的那页（描边） */
.pstrip{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:10px;max-height:104px;overflow:auto;padding:2px}
.pchip.set{background:var(--ok-soft);border-color:var(--ok);color:var(--ok);font-weight:700}
.pchip.cur{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent)}
.pscope .field{margin-bottom:0}
/* 3×3 位置选择器：九宫格本身就是「位置」这个信息的形状，比下拉列表直观 */
.posgrid{display:inline-grid;grid-template-columns:repeat(3,1fr);gap:3px;padding:3px;
  border:1px solid var(--border-2);border-radius:var(--radius-sm);background:var(--panel-2)}
.poscell{width:30px;height:26px;padding:0;border:1px solid var(--border);border-radius:5px;
  background:var(--panel);cursor:pointer;transition:.12s}
.poscell:hover{border-color:var(--accent)}
.poscell.on{background:var(--accent);border-color:var(--accent)}
.poscell.on::after{content:"";display:block;width:7px;height:7px;margin:0 auto;border-radius:50%;background:var(--accent-text)}
.poscell:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.posrow{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap}
.posrow .field{margin-bottom:0}
/* 按下时轻微下沉，给一个「确实点到了」的触感反馈 */
.btn:active,.chip:active,.ibtn:active,.nav-item:active,.lb-btn:active{transform:translateY(1px)}
.check{display:inline-flex;align-items:center;gap:7px;font-size:13px;cursor:pointer;user-select:none;padding:4px 2px}
.check input{width:15px;height:15px;accent-color:var(--accent);cursor:pointer}
.outbox{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden}
.out-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border-bottom:1px solid var(--border-2);background:var(--panel-2)}
.out-head span{font-size:12.5px;font-weight:600}
.out{
  margin:0;padding:14px;min-height:56px;max-height:440px;overflow:auto;white-space:pre-wrap;word-break:break-word;
  font-size:13px;line-height:1.65;background:var(--code-bg);color:var(--text);
}
.out:empty::before{content:attr(data-empty);color:var(--faint)}
.stat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
.stat{background:var(--panel-2);border:1px solid var(--border-2);border-radius:var(--radius-sm);padding:12px 14px}
.stat-label{font-size:11.5px;color:var(--muted);margin-bottom:4px}
.stat-val{font-size:22px;font-weight:700;letter-spacing:.3px;font-variant-numeric:tabular-nums}
.kv{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px dashed var(--border-2);font-size:13.5px}
.kv:last-child{border-bottom:0}
.kv .k{color:var(--muted)}
.kv .v{font-weight:600;font-variant-numeric:tabular-nums;word-break:break-all;text-align:right}
.pill{display:inline-block;padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:600;background:var(--accent-soft);color:var(--accent)}
.badge-ok{background:var(--ok-soft);color:var(--ok)}
.badge-warn{background:var(--warn-soft);color:var(--warn)}
.badge-err{background:var(--err-soft);color:var(--err)}
/* 三类提示框：左边留出图标位，图标用 Lucide 路径做遮罩、取 currentColor 上色，
   于是颜色自动跟着各自的语义色与主题走，且路径数据只有 ICONS 那一份。 */
.err-box,.ok-box,.hint-box{position:relative;border-radius:var(--radius-sm)}
.err-box::before,.ok-box::before,.hint-box::before{
  content:'';position:absolute;left:13px;top:12px;width:16px;height:16px;
  background-color:currentColor;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain;
}
.err-box::before{-webkit-mask-image:var(--ic-warn,none);mask-image:var(--ic-warn,none)}
.ok-box::before{-webkit-mask-image:var(--ic-ok,none);mask-image:var(--ic-ok,none)}
.hint-box::before{-webkit-mask-image:var(--ic-hint,none);mask-image:var(--ic-hint,none)}
.err-box{padding:10px 12px 10px 38px;background:var(--err-soft);color:var(--err);font-size:13px;border:1px solid transparent}
.ok-box{padding:10px 12px 10px 38px;background:var(--ok-soft);color:var(--ok);font-size:13px}
.hint-box{padding:10px 12px 10px 38px;background:var(--accent-soft);color:var(--accent);font-size:12.5px}
.mt0{margin-top:0!important}
.diff{font-size:12.5px;line-height:1.6}
.diff-line{display:block;padding:0 10px;white-space:pre-wrap;word-break:break-all;border-radius:4px}
.diff-line.add{background:var(--ok-soft);color:var(--ok)}
.diff-line.del{background:var(--err-soft);color:var(--err)}
.diff-line.same{color:var(--muted)}
.diff-line .sign{display:inline-block;width:1.4em;font-weight:700;opacity:.85}
mark{background:#fde68a;color:#7c2d12;border-radius:3px;padding:0 1px}
html[data-theme="dark"] mark{background:#7c5b12;color:#fde68a}
.color-row{display:flex;gap:10px;align-items:center}
.swatch{width:52px;height:52px;border-radius:10px;border:1px solid var(--border);flex:none}
input[type=color]{width:52px;height:52px;padding:0;border:1px solid var(--border);border-radius:10px;background:transparent;cursor:pointer}
input[type=range]{width:100%;accent-color:var(--accent)}
.drop{
  border:2px dashed var(--border);border-radius:var(--radius);padding:26px 18px;text-align:center;cursor:pointer;
  color:var(--muted);font-size:13.5px;transition:.15s;background:var(--panel-2);
}
.drop:hover,.drop.over{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.drop .ic{display:block;margin:0 auto 8px;width:36px;height:36px;color:var(--accent);transition:transform .16s ease}
.drop:hover .ic,.drop.over .ic{transform:translateY(-3px)}
.preview-wrap{display:flex;justify-content:center;background:var(--code-bg);border-radius:var(--radius-sm);padding:12px;border:1px solid var(--border-2)}
.preview-wrap img{max-width:100%;max-height:520px;border-radius:6px}
.qr-wrap{display:flex;justify-content:center;padding:18px;background:#fff;border-radius:var(--radius-sm);border:1px solid var(--border-2)}
.qr-wrap img{image-rendering:pixelated;max-width:100%}
.timer{font-size:56px;font-weight:700;text-align:center;font-variant-numeric:tabular-nums;letter-spacing:2px;padding:10px 0}
.timer.warn{color:var(--err)}
.btn.danger{border-color:var(--err);color:var(--err)}
.btn.danger:hover{background:var(--err-soft);border-color:var(--err);color:var(--err)}
.btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}
.rec-preview{width:100%;max-height:70vh;border-radius:var(--radius-sm);background:#000;display:block}
.rec-bar{display:flex;align-items:center;gap:12px;margin-top:12px;flex-wrap:wrap}
.rec-clock{font-size:22px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:1px;min-width:74px}
.rec-status{display:inline-flex;align-items:center;gap:7px;font-size:13px}
.rec-dot{width:9px;height:9px;border-radius:50%;background:var(--faint);display:inline-block;flex:none}
.rec-dot.on{background:var(--err);animation:recpulse 1.1s infinite}
.rec-dot.pause{background:var(--warn)}
@keyframes recpulse{0%,100%{opacity:1}50%{opacity:.25}}
canvas.pick{cursor:crosshair;max-width:100%;border-radius:var(--radius-sm);border:1px solid var(--border);display:block}
.palette{display:flex;gap:8px;flex-wrap:wrap}
.pal{width:56px;height:44px;border-radius:8px;border:1px solid var(--border);cursor:pointer;position:relative;overflow:hidden;transition:.12s}
.pal:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg)}
.pal span{position:absolute;left:0;right:0;bottom:0;font-size:9px;text-align:center;background:rgba(0,0,0,.55);color:#fff;font-family:ui-monospace,monospace;padding:2px 0}
.backdrop{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:55;backdrop-filter:blur(2px)}
.toast{
  position:fixed;left:50%;bottom:32px;transform:translate(-50%,20px);background:#151a22;color:#fff;
  padding:10px 20px;border-radius:999px;font-size:13.5px;box-shadow:var(--shadow-lg);opacity:0;pointer-events:none;
  transition:.25s;z-index:200;
}
html[data-theme="dark"] .toast{background:#e7eaf0;color:#151a22}
.toast.show{opacity:1;transform:translate(-50%,0)}
.spin{width:16px;height:16px;border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:sp .7s linear infinite;display:inline-block}
@keyframes sp{to{transform:rotate(360deg)}}

/* ---- PDF 工具：页面网格 ---- */
.pgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:14px}
.pcard{position:relative;border:1px solid var(--border);border-radius:10px;background:var(--panel-2);padding:8px;cursor:pointer;transition:.12s;user-select:none}
.pcard:hover{border-color:var(--accent);box-shadow:var(--shadow-md)}
.pcard.sel{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 2px var(--accent-soft)}
.pcard.over{border-color:var(--accent);border-style:dashed;transform:translateY(-2px)}
.pcard.dragging{opacity:.4}
.pthumb{position:relative;height:288px;display:flex;align-items:center;justify-content:center;background:#fff;border-radius:6px;overflow:hidden;margin-bottom:6px}
.pthumb img{max-width:100%;max-height:100%;object-fit:contain;display:block}
.pthumb.rot img{max-width:72%;max-height:72%}
.pzoom{position:absolute;right:5px;top:5px;width:28px;height:28px;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.92);color:#334155;cursor:zoom-in;display:grid;place-items:center;padding:0;font-family:inherit;opacity:.66;transition:.12s;box-shadow:0 1px 4px rgba(16,24,40,.14)}
.pzoom .lu{display:block}
.pzoom:hover{opacity:1;border-color:var(--accent);color:var(--accent)}
.pmeta{font-size:11.5px;color:var(--muted);text-align:center}
.pcard-diff{border-color:#e11d48;box-shadow:0 0 0 2px rgba(225,29,72,.13)}
.pcard-diff .pmeta{color:#e11d48;font-weight:600}
.pacts{display:flex;gap:4px;justify-content:center;margin-top:5px;flex-wrap:wrap}
/* 行内小按钮改用 Lucide 图标后，尺寸按图标重新定：既对齐了，也把点击区放大到手指够得着 */
.mini{width:26px;height:24px;border:1px solid var(--border);background:var(--panel);color:var(--muted);border-radius:6px;cursor:pointer;padding:0;display:grid;place-items:center;font-family:inherit;transition:.12s}
.mini .lu{display:block}
.mini:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.mini.del:hover{border-color:var(--err);color:var(--err);background:var(--err-soft)}
.out-body{padding:12px}
/* ---- PDF 工具：裁剪 / 框选 ---- */
.crop-wrap{position:relative;display:inline-block;line-height:0;border:1px solid var(--border);border-radius:6px;overflow:hidden;background:#fff;max-width:100%}
.crop-wrap canvas{display:block;max-width:100%;max-height:70vh;width:auto;height:auto;cursor:crosshair}
.crop-shade{position:absolute;background:rgba(79,70,229,.22);border:1px dashed var(--accent);pointer-events:none}
.wm-preview{position:relative;display:inline-block;max-width:100%}
.progress{height:7px;border-radius:999px;background:var(--border);overflow:hidden;margin-top:8px}
.progress>i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--accent),var(--accent-2));transition:width .2s}

/* ---- PDF 工具：结果预览（生成后先看效果，再决定下载） ---- */
.pv-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:14px}
.pv-card{border:1px solid var(--border);border-radius:10px;background:var(--panel-2);padding:8px;transition:.12s}
.pv-card.zoom{cursor:zoom-in}
.pv-card.zoom:hover{border-color:var(--accent);box-shadow:var(--shadow-md)}
.pcard.zoom{cursor:zoom-in}
.pcard.zoom:hover{border-color:var(--accent)}
/* 两个 auto + max-* 保证等比缩放不变形；不同尺寸的页面各自居中 */
.pv-card img{max-width:100%;max-height:520px;width:auto;height:auto;margin:0 auto;object-fit:contain;background:#fff;border-radius:6px;display:block}
.pv-cap{font-size:12px;color:var(--muted);text-align:center;margin-top:6px}
/* ---- 视频工具：设置实时预览（改参数即见效果，无需先跑一遍） ---- */
.vp-box{margin-top:2px}
.vp-strip{display:flex;gap:8px;overflow-x:auto;padding:8px;border:1px solid var(--border);border-radius:10px;background:var(--code-bg);min-height:84px;align-items:center;justify-content:flex-start}
.vp-strip:empty{min-height:0;border:0;padding:0}
.vp-cell{margin:0;flex:none;display:flex;flex-direction:column;align-items:center;gap:3px;border:2px solid transparent;border-radius:8px;padding:3px;transition:.12s}
.vp-cell.on{border-color:var(--accent);background:var(--accent-soft)}
.vp-cell img{height:62px;width:auto;max-width:160px;object-fit:contain;border-radius:5px;background:#fff;display:block}
.vp-cell figcaption{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.vp-note{font-size:12.5px;color:var(--muted);margin-top:8px;min-height:17px}
.pv-more{grid-column:1/-1;display:grid;place-items:center;border:1px dashed var(--border);border-radius:10px;color:var(--faint);font-size:12.5px;text-align:center;padding:16px 8px;line-height:1.5}
.pv-solo{background:#fff;border:1px solid var(--border);border-radius:10px;padding:8px;display:flex;justify-content:center}
.pv-solo img{max-width:100%;max-height:74vh;object-fit:contain;display:block;border-radius:6px;cursor:zoom-in}
.pv-live{position:relative;border:1px solid var(--border);border-radius:10px;background:var(--panel-2);padding:10px;min-height:120px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px}
.pv-live img{max-width:100%;max-height:74vh;object-fit:contain;display:block;background:#fff;border-radius:6px;box-shadow:var(--shadow)}
.pv-live canvas{cursor:zoom-in}
/* ---- 实时预览的翻页条：多页 PDF 才翻得动，单页时整条隐藏 ---- */
.pvnav{display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;max-width:100%}
.pvnav-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;border-radius:8px;border:1px solid var(--border);background:var(--panel);color:var(--muted);cursor:pointer;transition:.12s}
.pvnav-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}
.pvnav-btn:disabled{opacity:.35;cursor:default}
.pvnav-num{width:64px;text-align:center;font:inherit;font-size:13px;padding:5px 6px;border-radius:8px;border:1px solid var(--border);background:var(--panel);color:var(--text)}
.pvnav-num:focus{outline:none;border-color:var(--accent);box-shadow:var(--ring)}
/* ---- 大图查看：滚轮缩放 / 拖动平移 / 双击复位 ---- */
.lb{position:fixed;inset:0;z-index:90;background:rgba(0,0,0,.82);display:flex;align-items:center;justify-content:center;padding:20px;animation:fade .12s ease;overflow:hidden}
.lb-inner{max-width:97vw;max-height:97vh;background:var(--panel);border-radius:12px;padding:12px;display:flex;flex-direction:column;gap:8px;align-items:center;box-shadow:var(--shadow-lg)}
.lb-stage{overflow:hidden;display:flex;align-items:center;justify-content:center;cursor:grab}
.lb-stage.grabbing{cursor:grabbing}
.lb-stage img{max-width:93vw;max-height:86vh;object-fit:contain;display:block;background:#fff;border-radius:6px;user-select:none;-webkit-user-drag:none}
.lb-stage img.anim{transition:transform .14s ease}
.lb-bar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:center;max-width:100%;background:var(--panel-2);border:1px solid var(--border);border-radius:10px;padding:5px 9px}
.lb-btn{font:inherit;font-size:12.5px;color:var(--muted);background:var(--panel);border:1px solid var(--border);border-radius:8px;padding:3px 11px;cursor:pointer;line-height:1.7;transition:.12s}
.lb-btn:hover{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
.lb-num{font-size:12.5px;color:var(--muted);min-width:44px;text-align:center;font-variant-numeric:tabular-nums}
.lb-cap{font-size:12.5px;color:var(--muted)}
.lb-tip{font-size:11.5px;color:var(--faint)}
/* 回看产出物的浮层：内层直接用 pdf-common 的 renderFilePreview，
   所以外观与「结果预览」完全一致（PDF 出页、图片可点开放大、压缩包列条目）。 */
.ov-inner{width:min(1000px,94vw)}
.ov-head{width:100%;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.ov-name{
  flex:1;min-width:0;font-size:13.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono","Courier New",monospace;
}
.ov-meta{flex:none;display:flex;align-items:center;gap:5px;font-size:11.5px;color:var(--faint);font-variant-numeric:tabular-nums}
.ov-meta .dot{opacity:.5}
.ov-body{width:100%;max-height:68vh;overflow:auto;display:flex;flex-direction:column;align-items:center}
.ov-nope{font-size:13px;color:var(--muted);text-align:center;line-height:1.9;padding:36px 14px}
.ov-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:center}
/* 产出不再是死胡同：能「接着处理」（把这份文件装进另一个工具当输入），
   也能「回到原工具」（参数已还原，改一改再做一次）。 */
.ov-acts{
  width:100%;display:flex;flex-direction:column;gap:9px;
  padding:11px 13px;border:1px solid var(--border);border-radius:12px;background:var(--panel-2);
}
.ov-act{display:flex;align-items:flex-start;gap:10px}
.ov-act-k{
  flex:none;display:inline-flex;align-items:center;gap:5px;
  font-size:11.5px;color:var(--muted);line-height:25px;white-space:nowrap;
}
.ov-act-k .ic{display:flex}
.ov-chips{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:6px}
.ov-chip{
  font:inherit;font-size:12px;line-height:1;color:var(--text);background:var(--panel);
  border:1px solid var(--border);border-radius:999px;padding:6px 11px;cursor:pointer;transition:.12s;
}
.ov-chip:hover{border-color:var(--accent);color:var(--accent)}
.ov-chip:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.ov-chip.more{color:var(--muted);border-style:dashed}
.ov-none{font-size:12px;color:var(--faint);line-height:25px}
.ov-back{
  font:inherit;font-size:12px;line-height:1;display:inline-flex;align-items:center;gap:6px;
  color:var(--accent);background:transparent;border:1px solid var(--accent);border-radius:999px;
  padding:6px 12px;cursor:pointer;transition:.12s;
}
.ov-back:hover{background:var(--accent);color:var(--accent-text)}
.ov-back:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
@keyframes fade{from{opacity:0}to{opacity:1}}

/* ============ 历史记录（右侧面板） ============
   放最近打开过的工具与导出 / 复制动作，按时间倒序、按天分组。
   桌面端常驻在主体右侧；窗口不够宽时改为从右侧滑出的抽屉，
   免得把工具内容区挤得只剩一条缝。 */
.hist{
  width:288px;flex:none;min-width:0;background:var(--panel);border-left:1px solid var(--border);
  display:flex;flex-direction:column;z-index:40;
}
.app.no-hist .hist{display:none}
.hist-head{display:flex;align-items:center;gap:8px;padding:14px 12px 8px 14px}
.hist-head .t{flex:1;min-width:0;display:flex;align-items:center;gap:7px;font-size:13.5px;font-weight:600}
.hist-head .ic{display:flex;color:var(--accent)}
.hist-list{flex:1;overflow-y:auto;overscroll-behavior:contain;padding:0 10px 18px;position:relative}
.hist-day{font-size:11px;font-weight:600;letter-spacing:.5px;color:var(--faint);padding:12px 6px 5px}
.hist-item{
  display:flex;gap:9px;align-items:flex-start;width:100%;text-align:left;border:0;background:transparent;
  color:var(--text);padding:8px 9px;border-radius:var(--radius-sm);cursor:pointer;font-family:inherit;transition:.12s;
}
.hist-item:hover{background:var(--panel-2)}
.hist-item:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.hist-item.on{background:var(--accent-soft)}
/* 「定位」到的那一条：左侧一根强调色竖条，和「当前工具」的淡底高亮区分开 */
.hist-item.sel{background:var(--panel-2);box-shadow:inset 3px 0 0 var(--accent)}
.hist-item.on.sel{background:var(--accent-soft)}
/* 定位后把文件名整条展开、时间换成绝对时刻，方便核对「到底是哪一次操作」 */
.hist-item.sel .hist-file{white-space:normal;word-break:break-all}
.hist-item.sel .hist-name{white-space:normal}
.hist-ic{
  width:26px;height:26px;margin-top:1px;border-radius:8px;flex:none;display:grid;place-items:center;
  background:var(--panel-2);color:var(--faint);border:1px solid var(--border-2);
}
/* 产出类动作用语义色，扫一眼就能和「只是点进来看看」区分开 */
.hist-item.k-export .hist-ic{background:var(--ok-soft);color:var(--ok);border-color:transparent}
.hist-item.k-copy .hist-ic{background:var(--accent-soft);color:var(--accent);border-color:transparent}
.hist-main{flex:1;min-width:0}
.hist-row{display:flex;align-items:center;gap:6px}
.hist-name{flex:1;min-width:0;font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hist-n{
  flex:none;font-size:10.5px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--muted);
  background:var(--panel-2);border:1px solid var(--border-2);border-radius:999px;padding:0 6px;
}
/* 「当前」标记：点自己那条不产生新记录、也不重渲染，标出来免得用户以为点了没反应 */
.hist-cur{
  flex:none;font-size:10px;font-weight:700;line-height:15px;letter-spacing:.3px;
  color:var(--accent-text);background:var(--accent);border-radius:999px;padding:0 7px;
}
/* 「回看产出」：这条记录当时下载的那份文件还在内存里，点开能直接看内容 / 再次下载。
   条目行本身是 role=button 的 div，这里才能塞一个真正的 button（按钮不能嵌套）。 */
.hist-view{
  flex:none;align-self:center;display:inline-flex;align-items:center;gap:4px;
  font:inherit;font-size:11px;line-height:1;color:var(--ok);background:var(--ok-soft);
  border:1px solid transparent;border-radius:999px;padding:4px 9px 4px 7px;cursor:pointer;transition:.12s;
}
.hist-view:hover{border-color:var(--ok)}
.hist-view .ic{display:flex}
/* 定位条：点过的条目会「选中」，可以顺着时间线逐条往更早 / 更近翻看 */
.hist-nav{display:flex;align-items:center;gap:6px;padding:0 14px 8px}
.hist-step{
  display:inline-flex;align-items:center;gap:3px;font:inherit;font-size:11.5px;line-height:1;
  color:var(--muted);background:var(--panel-2);border:1px solid var(--border-2);
  border-radius:999px;padding:4px 9px 4px 7px;cursor:pointer;transition:.12s;white-space:nowrap;
}
.hist-step .ic{display:flex}
.hist-step:hover:not([disabled]){color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
.hist-step[disabled]{opacity:.42;cursor:default}
.hist-pos{flex:1;min-width:0;text-align:right;font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums}
.hist-meta{display:flex;align-items:center;gap:5px;min-width:0;margin-top:1px;font-size:11.5px;color:var(--faint)}
.hist-meta .dot{opacity:.5}
/* 文件名是用户数据：用等宽体、单行省略，并打 data-notr 免得被词典误翻 */
.hist-file{
  margin-top:2px;font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono","Courier New",monospace;
}
.hist-empty{color:var(--faint);font-size:13px;text-align:center;line-height:1.9;padding:46px 16px}
.hist-foot{
  flex:none;padding:9px 14px;border-top:1px solid var(--border);font-size:11px;color:var(--faint);
  display:flex;align-items:center;justify-content:space-between;gap:8px;
}
/* 「留存 N 份产出 · X MB」比「仅存本机」长，窄面板下要能自己收进去 */
.hist-foot .hist-out{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------- 工具页面内的「最近使用」 ----------
   每个工具的页面底部列出「用这个工具做过什么」，不用去右侧翻全局列表。
   样式刻意比右侧面板轻一档：它是补充信息，不能抢工具本身的主体地位。 */
.tool-hist{
  margin-top:16px;border:1px solid var(--border-2);border-radius:var(--radius);
  background:var(--panel-2);padding:12px 13px 11px;
}
.th-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}
.th-t{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:600;color:var(--text)}
.th-t .ic{display:flex;color:var(--muted)}
.th-n{font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums}
.th-empty{font-size:12.5px;color:var(--faint);line-height:1.65}
.th-list{display:flex;flex-direction:column;gap:1px}
.th-row{
  display:flex;align-items:center;gap:8px;width:100%;text-align:left;font:inherit;
  color:var(--text);background:transparent;border:0;border-radius:8px;
  padding:6px 7px;cursor:pointer;transition:background .12s;
}
.th-row:hover{background:var(--panel)}
.th-row:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.th-ic{flex:none;display:flex;color:var(--faint)}
/* 与右侧面板同一套语义色，两边看着是一回事 */
.th-row.k-use .th-ic{color:var(--accent)}
.th-row.k-export .th-ic{color:var(--ok)}
.th-row.k-copy .th-ic{color:var(--accent)}
.th-kind{flex:none;font-size:12.5px}
.th-file{
  flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:11.5px;color:var(--muted);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono","Courier New",monospace;
}
.th-n2{
  flex:none;font-size:10.5px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--muted);
  background:var(--panel);border:1px solid var(--border-2);border-radius:999px;padding:0 6px;
}
.th-at{flex:none;margin-left:auto;font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums}
.th-more{font-size:11px;color:var(--faint);padding:5px 7px 0}

/* 遮罩要压住移动端侧栏（.sidebar z-index:60），抽屉再压在遮罩之上 */
.hist-mask{display:none;position:fixed;inset:0;z-index:61;background:rgba(0,0,0,.42);backdrop-filter:blur(2px)}
.ibtn.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
@media (max-width:1200px){
  .hist{
    position:fixed;right:0;top:0;bottom:0;width:min(320px,86vw);z-index:62;
    transform:translateX(102%);transition:transform .22s ease;box-shadow:var(--shadow-lg);
    padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);
  }
  .app.no-hist .hist{display:flex}          /* 抽屉靠 transform 收起，不靠 display */
  .app.hist-on .hist{transform:none}
  .app.hist-on .hist-mask{display:block}
}

/* ============ 语言切换 ============ */
.lang-wrap{position:relative;flex:none}
#langBtn{display:flex;align-items:center;gap:5px;width:auto;padding:0 9px;font-family:inherit;font-size:12.5px;font-weight:600}
#langBtn .code{letter-spacing:.3px}
.lang-menu{
  position:absolute;right:0;top:calc(100% + 8px);min-width:186px;z-index:120;
  background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);padding:6px;display:none;
}
.lang-menu.show{display:block}
.lang-item{
  display:flex;align-items:center;justify-content:space-between;gap:14px;width:100%;
  border:0;background:transparent;color:var(--text);font-family:inherit;font-size:13.5px;
  padding:8px 10px;border-radius:var(--radius-sm);cursor:pointer;text-align:left;transition:.12s;
}
.lang-item:hover{background:var(--panel-2)}
.lang-item.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.lang-item .lang-code{font-size:11px;color:var(--faint);font-family:ui-monospace,monospace}
.lang-item.on .lang-code{color:var(--accent)}
.lang-item .tick{opacity:0;flex:none;display:flex}
.lang-item.on .tick{opacity:1}

@media (max-width:860px){
  .sidebar{position:fixed;left:0;top:0;bottom:0;transform:translateX(-100%);transition:transform .22s ease;box-shadow:var(--shadow-lg)}
  .sidebar.open{transform:none}
  .backdrop.show{display:block}
  #menuBtn{display:grid}
  .content{padding:18px 14px 60px}
  .grid2,.grid3{grid-template-columns:1fr}
  .tool-ic{width:40px;height:40px}
  .tool-head h2{font-size:18px}
  .timer{font-size:44px}
  /* 触屏：把点击目标撑大。手指比鼠标指针钝得多，23×21 的小按钮在手机上很难点中。 */
  .ibtn{width:38px;height:38px}
  .mini{width:30px;height:28px}
  .pzoom{width:32px;height:32px}
  .nav-item{padding:10px}
  /* 刘海屏 / 圆角屏（viewport-fit=cover）按安全区避让，
     否则横屏时侧栏会被状态栏压住、底部内容会顶到 Home 指示条下面。
     把基础值留在前面：浏览器不认 env() 时整条声明被丢弃，自动回落到基础值。 */
  .sidebar{padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom)}
  .topbar{padding-left:max(14px,env(safe-area-inset-left));padding-right:max(14px,env(safe-area-inset-right))}
  .content{padding-left:max(14px,env(safe-area-inset-left));padding-right:max(14px,env(safe-area-inset-right))}
  .content{padding-bottom:calc(60px + env(safe-area-inset-bottom))}
}
