/* navbar.css 不再用 @import（会绕过版本号缓存破除）；改由 t.js 带版本号注入 <link> */
/* 工具页共享样式 */
/* 与主站 design-tokens.css 对齐（改这里 = 219 个工具页同时跟上主站视觉） */
:root {
  --bg: #f8f9fb; --card: #fff; --primary: #2563eb; --primary-dark: #1d4ed8;
  --text: #1f2937; --text-strong: #111827; --muted: #6b7280; --text-tertiary: #9ca3af;
  --border: #e5e7eb; --divider: #eef2f7; --input-border: #d1d5db;
  --danger: #dc2626; --danger-tint: #fef2f2; --danger-border: #fca5a5;
  --ok: #059669; --ok-tint: #ecfdf5; --ok-border: #a7f3d0;
  --warn: #d97706; --warn-tint: #fffbeb; --warn-border: #fde68a;
  --brand-soft: #eff6ff; --brand-soft-border: #bfdbfe; --surface-2: #f8fafc; --neutral-100: #f3f4f6;
  --r-sm: 12px; --r-md: 16px; --r-lg: 20px; --r-xl: 24px; --r-pill: 999px;
  --sh-1: 0 8px 24px rgb(15 23 42 / 8%); --sh-2: 0 16px 40px rgb(15 23 42 / 12%);
  --focus-ring: 0 0 0 3px rgb(37 99 235 / 22%);
}
* { box-sizing: border-box; }
body {
  margin: 0; padding: 20px 16px 40px;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  background: var(--bg); color: var(--text); line-height: 1.6;
}
.wrap { max-width: 860px; margin: 0 auto; }
.top { display: flex; align-items: center; margin-bottom: 8px; font-size: 14px; position: relative; }
.top a { color: var(--primary); text-decoration: none; }
/* 顶部“最近使用”下拉 */
.hist-wrap { position: relative; margin-right: 12px; }
#histBtn { cursor: pointer; white-space: nowrap; }
.hist-drop { display: none; position: absolute; top: 100%; right: 0; z-index: 80; min-width: 200px; max-width: 300px;
  background: #fff; border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,.16);
  padding: 6px; margin-top: 6px; max-height: 60vh; overflow-y: auto; }
.hist-drop.open { display: block; }
.hist-drop a { display: block; color: var(--text); font-size: 13px; padding: 7px 10px; border-radius: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hist-drop a:hover { background: #eff6ff; color: var(--primary); }
.hist-drop .hist-clear { color: var(--muted); border-top: 1px solid var(--border); margin-top: 4px; font-size: 12px; }
.hist-empty { padding: 8px 10px; color: var(--muted); font-size: 13px; }
.top select { padding: 5px 8px; border: 1px solid var(--border); border-radius: 8px; background: #fff; font-size: 13px; }
.navbar { margin-bottom: 14px; }  /* 菜单栏样式在 navbar.css（@import 于文件顶部），此处仅补工具页间距 */
h1 { font-size: 20px; margin: 8px 0 14px; }
.card {
  background: var(--card); border-radius: 14px; padding: 18px;
  box-shadow: 0 1px 4px rgba(0,0,0,.06); margin-bottom: 14px;
}
textarea, input[type=text], input[type=number], input[type=datetime-local] {
  width: 100%; border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 12px; font-size: 14px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: #fff; color: var(--text);
}
textarea { min-height: 160px; resize: vertical; }
textarea:focus, input:focus { outline: 2px solid var(--primary); border-color: transparent; }
.row { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0; align-items: center; }
button {
  padding: 9px 16px; font-size: 14px; font-weight: 600; cursor: pointer;
  border: none; border-radius: 9px; background: var(--primary); color: #fff;
}
button:hover { background: var(--primary-dark); }
button.sec { background: #fff; color: var(--text); border: 1px solid var(--border); font-weight: 500; }
button.sec:hover { background: #f3f4f6; }
.msg { font-size: 13px; margin-top: 8px; min-height: 18px; }
.msg.err { color: var(--danger); }
.msg.ok { color: var(--ok); }
.muted { color: var(--muted); font-size: 13px; }
label.opt { font-size: 13px; color: var(--muted); display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.kv { display: grid; grid-template-columns: auto 1fr auto; gap: 8px 12px; align-items: center; font-size: 14px; }
.kv .k { color: var(--muted); white-space: nowrap; }
.kv .v { font-family: ui-monospace, Menlo, Consolas, monospace; word-break: break-all; }
.copy-btn { padding: 4px 10px; font-size: 12px; }
/* 工具介绍（SEO 内容区） */
.about h2 { font-size: 15px; margin: 0 0 8px; }
.about h2 + p, .about p { font-size: 14px; margin: 6px 0; color: var(--text); }
.about .rel { font-size: 14px; }
.about .rel a { color: var(--primary); text-decoration: none; margin-right: 12px; }
.about .rel a:hover { text-decoration: underline; }
/* 工具目录 */
.tool-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.tool-card {
  display: block; background: var(--card); border-radius: 12px; padding: 16px;
  box-shadow: 0 1px 4px rgba(0,0,0,.06); text-decoration: none; color: var(--text);
  transition: transform .1s, box-shadow .1s;
}
.tool-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,.1); }
.tool-card .ic { font-size: 24px; }
.tool-card .nm { font-weight: 700; margin: 6px 0 2px; }
.tool-card .ds { font-size: 12px; color: var(--muted); }
/* 工具评分（t.js 注入到页脚） */
.rate-box {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 8px;
  margin: 18px 0 4px; font-size: 13px; color: var(--muted);
}
.rate-box .rate-btn {
  padding: 5px 14px; font-size: 13px; font-weight: 500; background: #fff;
  color: var(--text); border: 1px solid var(--border); border-radius: 20px;
}
.rate-box .rate-btn:hover { background: #f3f4f6; }
/* 地址生成器（addr.js 注入）：左侧分组资料 + 右侧热门地址侧栏 */
.ag-wrap { display: grid; grid-template-columns: 1fr 220px; gap: 18px; align-items: start; }
.ag-bar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.ag-sec { margin-bottom: 18px; }
.ag-sec:last-child { margin-bottom: 0; }
.ag-sec-h { font-size: 13px; font-weight: 700; color: var(--primary); border-left: 3px solid var(--primary); padding-left: 8px; margin-bottom: 4px; }
.ag-row { display: flex; align-items: center; gap: 10px; padding: 9px 4px; border-bottom: 1px solid var(--border); font-size: 14px; }
.ag-row:last-child { border-bottom: none; }
.ag-lbl { color: var(--muted); width: 84px; flex-shrink: 0; }
.ag-val { flex: 1; word-break: break-word; }
.ag-copy { opacity: 0; border: none; background: none; cursor: pointer; color: var(--muted); font-size: 12px; padding: 2px 8px; border-radius: 6px; transition: opacity .1s; white-space: nowrap; }
.ag-row:hover .ag-copy { opacity: 1; }
.ag-copy:hover { background: #f3f4f6; color: var(--primary); }
.ag-side { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.ag-side-h { background: #f3f4f6; padding: 9px 12px; font-weight: 600; font-size: 13.5px; }
.ag-side a { display: block; padding: 8px 12px; font-size: 13px; color: var(--primary); text-decoration: none; border-top: 1px solid var(--border); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ag-side a:hover { background: #eff6ff; }
.ag-side a.cur { background: #eff6ff; font-weight: 600; }
@media (max-width: 640px) { .ag-wrap { grid-template-columns: 1fr; } .ag-copy { opacity: 1; } }


/* ===================================================================
   工具箱目录页（/tools/、/zh/tools/）
   尺寸真源：uitools/screens/T01.spec.yaml（首页）+ T04.spec.yaml（分类详情）
   验收：同名 .accept.yaml（scripts/run-accept.js 在浏览器里跑 getComputedStyle）
   手机：标题栏 56 + 主体 358（首页列表 ↔ 分类详情二选一）
   桌面：顶栏 64 + 左侧栏 416（sticky）+ 右内容区 1120 + 页脚 72
   作用域限定在 .toolbox-page，不影响 219 个工具页自身样式
   =================================================================== */
.toolbox-page { background: var(--bg); padding: 0; }
.toolbox-page #hdr, .toolbox-page #ftr { display: none; }
.toolbox-page svg { width: 20px; height: 20px; flex: 0 0 auto; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.toolbox-page a { text-decoration: none; color: inherit; }
.toolbox-page :focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-sm); }

/* —— 手机标题栏（56） —— */
.mobile-titlebar {
  display: flex; align-items: center; gap: 8px; height: 56px; padding: 0 8px;
  background: var(--card); border-bottom: 1px solid var(--divider);
  position: sticky; top: 0; z-index: 20;
}
.mobile-titlebar[hidden] { display: none; }
.mobile-titlebar h1, .mobile-titlebar .title {
  flex: 1; margin: 0; text-align: center;
  font-size: 20px; line-height: 28px; font-weight: 600; color: var(--text-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mobile-titlebar .back-main, .mobile-titlebar .back-tools,
.mobile-titlebar .favorites-entry, .mobile-titlebar .focus-category-search,
.mobile-titlebar .tool-help {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: 0 0 44px;
  border: none; background: none; padding: 0; cursor: pointer; color: var(--text);
}
.mobile-titlebar .back-main svg, .mobile-titlebar .back-tools svg,
.mobile-titlebar .focus-category-search svg, .mobile-titlebar .tool-help svg { width: 20px; height: 20px; }
.mobile-titlebar .favorites-entry svg { width: 22px; height: 22px; }
.mobile-titlebar .favorites-entry .ic-star-on { display: none; }

/* —— 外壳 —— */
.toolbox-shell { display: block; padding: 0 16px; }

/* —— 侧栏 / 手机首页主体 —— */
.toolbox-sidebar { display: flex; flex-direction: column; gap: 16px; padding: 12px 0 32px; }
/* 正文标题只为 SEO 与读屏存在（.sr-only）——可见标题在手机标题栏里，不重复出现 */
.tool-count { font-size: 13px; line-height: 18px; color: var(--muted); }

.tool-search-box, .category-search-box {
  display: flex; align-items: center; gap: 8px; height: 48px; padding: 0 12px;
  background: var(--card); border: 1px solid var(--input-border); border-radius: var(--r-sm);
}
.tool-search-box svg, .category-search-box svg { width: 20px; height: 20px; color: var(--muted); }
.tool-search-box input, .category-search-box input {
  flex: 1; min-width: 0; border: none; outline: none; background: none;
  font: inherit; font-size: 15px; color: var(--text);
}
.tool-search-box input::-webkit-search-cancel-button,
.category-search-box input::-webkit-search-cancel-button { display: none; }
#toolSearch, #categorySearch { width: 100%; }
.load-more-wrap { display: block; text-align: center; }
#categorySearchClear {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-right: -12px;
  border: none; background: none; padding: 0; cursor: pointer; color: var(--muted);
}
#categorySearchClear svg { width: 18px; height: 18px; }
#categorySearchClear[hidden] { display: none; }

/* 五大类列表 */
.category-list {
  min-height: 280px; background: var(--card);
  border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1);
  overflow: hidden;
}
.category-row {
  display: flex; align-items: center; gap: 12px; height: 56px; padding: 0 12px;
  background: var(--card); border-bottom: 1px solid var(--divider); cursor: pointer;
}
.category-row:last-child { border-bottom: none; }
.category-row[aria-current] { background: var(--brand-soft); color: var(--primary); }
.category-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: 0 0 36px;
  background: var(--brand-soft); border-radius: var(--r-sm); color: var(--primary);
}
.category-icon svg { width: 20px; height: 20px; }
.category-name { flex: 1; font-size: 15px; line-height: 22px; font-weight: 500; color: var(--text-strong); }
.category-row[aria-current] .category-name { color: var(--primary); }
.category-count { font-size: 13px; line-height: 18px; color: var(--muted); }
.category-chevron { display: inline-flex; color: var(--text-tertiary); }
.category-chevron svg { width: 18px; height: 18px; }

/* 常用工具 */
.favorite-section { display: flex; flex-direction: column; gap: 12px; }
.favorite-head { display: flex; align-items: center; gap: 8px; }
.favorite-section h2 { margin: 0; font-size: 17px; line-height: 24px; font-weight: 600; color: var(--text-strong); }
.favorite-section .favorites-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px;
  background: var(--brand-soft); border-radius: var(--r-pill); color: var(--primary); font-size: 12px;
}
.favorite-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 12px; row-gap: 12px; }
.favorite-tool-card {
  display: flex; align-items: center; gap: 8px; min-height: 72px; padding: 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1);
}
.favorite-tool-card .tool-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: 0 0 36px;
  background: var(--brand-soft); border-radius: var(--r-sm); color: var(--primary);
}
.favorite-tool-card .tool-icon svg { width: 20px; height: 20px; }
.fav-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
/* 通用 .tool-name（给分类工具卡用）带 nowrap+ellipsis，收藏卡另有自己的换行策略，
   这里必须显式还原，否则桌面折叠区的两行夹断会被打成一行截断 */
.favorite-tool-card .tool-name { font-size: 14px; line-height: 20px; font-weight: 600; color: var(--text-strong);
  white-space: normal; overflow: visible; text-overflow: clip; }
.favorite-tool-card .tool-category { font-size: 12px; line-height: 18px; color: var(--muted); }

.favorite-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: 0 0 44px; margin: -8px -10px -8px 0;
  border: none; background: none; padding: 0; cursor: pointer; color: var(--muted);
}
.favorite-toggle svg { width: 20px; height: 20px; }
.favorite-toggle .ic-star-on { display: none; }
.favorite-toggle.is-on { color: var(--primary); }
.favorite-toggle.is-on .ic-star { display: none; }
.favorite-toggle.is-on .ic-star-on { display: block; }

.rail-icon { display: none; }                     /* 只在折叠态的图标栏里用 */
.view-all-tools {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  height: 44px; color: var(--primary); font-size: 15px; font-weight: 600;
}
.view-all-tools svg { width: 18px; height: 18px; }

.privacy-note {
  display: flex; align-items: center; gap: 8px; min-height: 56px; padding: 0 12px;
  background: var(--brand-soft); border: 1px solid var(--brand-soft-border);
  border-radius: var(--r-sm); font-size: 13px; line-height: 20px; color: var(--text);
}
.privacy-note svg { width: 18px; height: 18px; color: var(--primary); }
.sidebar-foot { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.sidebar-foot a { color: var(--primary); }

/* —— 分类详情 —— */
.toolbox-detail { display: flex; flex-direction: column; gap: 16px; padding: 12px 0 32px; }
/* navbar.css 也定义了 .crumb（工具页面包屑）且在 t.css 之后注入——这里必须加一层作用域才压得住 */
.toolbox-detail .crumb { display: none; align-items: center; gap: 8px; height: 44px; margin: 0; font-size: 13px; color: var(--muted); }
.toolbox-detail .crumb a { color: var(--muted); text-decoration: none; }
.toolbox-detail .crumb a:hover { color: var(--primary); text-decoration: none; }
.crumb-sep { display: inline-flex; color: var(--text-tertiary); }
.crumb-sep svg { width: 16px; height: 16px; }
.crumb-cur { color: var(--text-strong); font-weight: 600; }

.category-summary {
  display: flex; align-items: flex-start; gap: 12px; min-height: 112px; padding: 16px;
  background: var(--brand-soft); border: 1px solid var(--brand-soft-border); border-radius: var(--r-md);
}
.category-summary .category-icon { width: 48px; height: 48px; flex: 0 0 48px; background: var(--card); }
.category-summary .category-icon svg { width: 26px; height: 26px; }
.category-summary-copy { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.category-summary h2 { margin: 0; font-size: 20px; line-height: 28px; font-weight: 600; color: var(--text-strong); }
.category-summary .category-count { font-size: 13px; line-height: 18px; color: var(--primary); }
.category-description {
  margin: 0; font-size: 13px; line-height: 20px; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.category-heading { display: none; }

.category-filter-stack {
  display: flex; flex-direction: column; gap: 8px;
  min-height: 112px; padding: 8px 16px; margin: 0 -16px;
  background: var(--bg); position: sticky; top: 56px; z-index: 10;
}
.subcategory-tabs { display: flex; align-items: center; gap: 8px; height: 40px; overflow-x: auto; scrollbar-width: none; }
.subcategory-tabs::-webkit-scrollbar { display: none; }
.subcategory-tabs[hidden] { display: none; }
.subcategory-tabs [role=tab] {
  display: inline-flex; align-items: center; height: 40px; padding: 0 12px; flex: 0 0 auto;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-pill);
  font: inherit; font-size: 13px; color: var(--text); cursor: pointer; white-space: nowrap;
}
.subcategory-tabs [role=tab][aria-selected=true] { background: var(--primary); border-color: var(--primary); color: #fff; }

.filter-result-count { min-height: 24px; font-size: 13px; line-height: 18px; color: var(--muted); }
.filter-result-count[hidden] { display: none; }

.subcategory-section { display: flex; flex-direction: column; gap: 12px; }
.subcategory-section[hidden] { display: none; }
.section-heading { display: flex; align-items: center; gap: 8px; height: 44px; }
.section-heading h3 { margin: 0; font-size: 17px; line-height: 24px; font-weight: 600; color: var(--text-strong); }
.section-count { font-size: 13px; line-height: 18px; color: var(--muted); }
.open-subcategory {
  display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px;
  min-width: 104px; height: 44px; margin-left: auto;
  font-size: 13px; font-weight: 600; color: var(--primary);
}
.open-subcategory[hidden] { display: none; }
.open-subcategory svg { width: 18px; height: 18px; }

.category-tool-list { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 8px; column-gap: 16px; }
.category-tool-overflow { display: none; }
.category-tool-card {
  display: flex; align-items: center; gap: 12px; min-height: 76px; padding: 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-sm);
}
.category-tool-card:hover { border-color: var(--brand-soft-border); }
.category-tool-card .tool-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: 0 0 40px;
  background: var(--brand-soft); border-radius: var(--r-sm); color: var(--primary);
}
.category-tool-card .tool-icon svg { width: 22px; height: 22px; }
.tool-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.tool-name { font-size: 14px; line-height: 20px; font-weight: 600; color: var(--text-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tool-description { font-size: 12px; line-height: 18px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.load-more-tools {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; height: 44px;
  background: var(--card); border: 1px solid var(--primary); border-radius: var(--r-sm);
  font: inherit; font-size: 14px; font-weight: 600; color: var(--primary); cursor: pointer;
}
.load-more-tools[hidden] { display: none; }

.category-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  min-height: 220px; padding: 24px; text-align: center;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
}
.category-empty[hidden] { display: none; }
.empty-icon {
  display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px;
  background: var(--brand-soft); border-radius: var(--r-pill); color: var(--primary);
}
.empty-icon svg { width: 24px; height: 24px; }
.empty-title { margin: 0; font-size: 15px; line-height: 22px; color: var(--text); }
.clear-filter {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 120px; height: 44px; padding: 0 16px;
  background: var(--primary); border: none; border-radius: var(--r-sm);
  font: inherit; font-size: 14px; font-weight: 600; color: #fff; cursor: pointer;
}
.back-to-top {
  position: fixed; right: 16px; bottom: 24px; z-index: 30;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; background: var(--primary); color: #fff;
  border-radius: var(--r-pill); box-shadow: var(--sh-2);
}
.back-to-top[hidden] { display: none; }

/* —— 顶栏 / 页脚（桌面） —— */
.tools-header { display: none; }
.tools-footer { min-height: 72px; background: var(--card); border-top: 1px solid var(--divider); }
.footer-inner {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 72px; padding: 0 16px; font-size: 13px; color: var(--muted);
}
.footer-inner a { color: var(--primary); }

/* —— 手机：首页 ↔ 分类详情 二选一 —— */
@media (max-width: 1023px) {
  /* 桌面专属控件绝不能漏到手机端——它们没有 display 兜底时会被 t.css 的 button 基础样式
     渲染成整条蓝色主按钮（实测踩过：手机首页出现三条蓝条）。 */
  #toolboxSidebarToggle,
  .sidebar-search-action,
  .sidebar-favorites-action { display: none !important; }
  /* 分类行的名称与计数在手机端也要留空隙（桌面的 grid/gap 规则只在 ≥1024 生效） */
  .category-meta { display: inline-flex; align-items: center; gap: 8px; }
  .category-cell { display: block; min-width: 0; flex: 1; }
  .category-flex { display: none; }
  /* 手机没有折叠区：标题常显、网格无视桌面的收起状态 */
  #sidebarFavoritesToggle { display: none; }
  #sidebarFavorites[hidden] { display: flex; }

  /* —— 手机首页信息层级（T13 定案）——
     顺序：标题栏 → (sr-only h1) → 总数 → 搜索 → 常用工具 → 分类列表 → 查看全部 → 隐私条。
     搜索提到收藏之前：打开工具箱最常见的动作是「找工具」，不该先穿过收藏区。
     间距不再靠 flex gap，改成契约里逐条写死的 margin，好让「全部落在 844 首屏内」可被断言。 */
  .mobile-toolbox { gap: 0; padding-bottom: 24px; }
  .mobile-toolbox > .tool-count { order: 1; margin-bottom: 8px; }
  .mobile-toolbox > #toolSearch { order: 2; }
  .mobile-toolbox > .favorite-section { order: 3; margin-top: 16px; gap: 0; }
  .mobile-toolbox > .category-list { order: 4; margin-top: 16px; }
  .mobile-toolbox > .view-all-tools { order: 5; margin-top: 12px; }
  .mobile-toolbox > .privacy-note { order: 6; margin-top: 12px; }
  .mobile-toolbox > .sidebar-foot { order: 7; margin-top: 16px; }

  /* 常用工具：一行一个（用户定案）。
     2×2 网格在 390 宽下把「Unix Timestamp Converter」折成四行；改横滑轨道后名字栏只有 130px，
     219 个英文名有 77 个（35%）被省略——英文是主场，横向省下来的宽度不值。
     竖排单列后名字栏 ~252px，几乎所有英文名都能完整显示，也和桌面侧栏的排法一致。
     行高压到 44（不是 56）：4 行 ×44 + 3×8 = 200，比原轨道多 136，首屏底边 676→812，仍 ≤844。 */
  .favorite-rail {
    display: flex; flex-direction: column; gap: 8px; margin-top: 8px;
  }
  .favorite-rail .favorite-tool-card {
    width: 100%; height: 44px; min-height: 0; padding: 0 8px;
    display: grid; grid-template-columns: 28px minmax(0, 1fr) 44px; align-items: center;
    column-gap: 8px; gap: 8px;
  }
  .favorite-rail .favorite-tool-card .tool-icon { width: 28px; height: 28px; flex: 0 0 28px; }
  .favorite-rail .favorite-tool-card .tool-icon svg { width: 16px; height: 16px; }
  .favorite-rail .fav-copy { min-width: 0; gap: 0; }
  /* .tool-name 是 <span>：不显式 block 的话 overflow/text-overflow 都不生效，长名字会压到星上 */
  .favorite-rail .tool-name { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* 收藏区里再标一次所属分类是冗余：这里的任务是认出工具并打开它 */
  .favorite-rail .tool-category { display: none; }
  .favorite-rail .favorite-toggle { margin: 0; }
  .toolbox-shell.in-category .toolbox-sidebar { display: none; }
  .toolbox-shell:not(.in-category) .toolbox-detail { display: none; }
  .mobile-toolbox { width: 100%; }
  /* 工具页手机端没有「首页列表 ↔ 详情」二选一：侧栏是桌面专属，正文永远是工具本体 */
  .tool-page .toolbox-sidebar { display: none; }
  .tool-page .toolbox-detail { display: flex !important; }
}

/* —— 桌面：顶栏 64 + 侧栏 416 + 内容 1120 —— */
@media (min-width: 1024px) {
  .mobile-titlebar { display: none !important; }
  .tools-header.desktop {
    display: block; height: 64px; background: var(--card);
    border-bottom: 1px solid var(--divider); position: sticky; top: 0; z-index: 20;
  }
  /* 通栏 + padding 0 32：跟主站 .topbar.app-header 一致。
     原来是 1376 居中容器，品牌起点落在 96 而主站在 32，两个顶栏一眼就错位。 */
  .header-inner {
    display: flex; align-items: center; gap: 24px; height: 64px;
    width: 100%; padding: 0 32px;
  }
  .header-lang { margin-left: auto; }   /* 靠右，对应主站顶栏右端的设置钮位置 */
  /* 顶栏必须和主站长一样——用户切到工具箱不该觉得换了个站。
     以下逐值对齐主站 app.css 的 #appBarTitle / .desktop-nav（那边是真源，这里跟随）：
     品牌 20/28/600 + letter-spacing -.01em + 28px 主色标记；导航 64 高、gap 8、
     padding 0 14、15/500，选中态是 **3px 下划线 + 主色 + 600**，不是胶囊底色。 */
  .header-brand {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 20px; line-height: 28px; font-weight: 600; letter-spacing: -.01em; color: var(--text-strong);
  }
  .header-brand svg { width: 28px; height: 28px; color: var(--primary); }
  .desktop-nav { display: flex; align-items: stretch; height: 64px; gap: 8px; margin-left: 8px; flex: 1; }
  .desktop-nav .nav-item {
    display: inline-flex; align-items: center; padding: 0 14px;
    border: 0; border-bottom: 3px solid transparent; background: transparent;
    font-size: 15px; font-weight: 500; color: var(--text);
  }
  .desktop-nav .nav-item:hover { color: var(--primary); }
  .desktop-nav .nav-item.active,
  .desktop-nav .nav-item[aria-current] { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }
  .header-lang { font-size: 13px; color: var(--primary); }

  .toolbox-shell {
    display: grid; grid-template-columns: 272px minmax(0, 1fr);
    align-items: start; min-height: 664px; padding: 0;
  }
  /* 侧栏压进 1536×800（顶栏 64 → 可用 736，本侧栏最坏内容约 648）：不设 max-height、不内滚，
     全页只有页面一条滚动轴。真源 uitools/FRAMEWORK.md §2.4 + T01.spec desktopSidebarPolicy */
  .toolbox-sidebar > * { flex: 0 0 auto; }
  .toolbox-sidebar {
    width: 272px; padding: 16px; gap: 0; align-self: start;
    background: var(--card); border-right: 1px solid var(--divider);
    position: sticky; top: 64px; max-height: none; overflow: visible;
    min-height: calc(100vh - 64px);   /* 白底铺到视口底，否则内容矮时侧栏下方会露出灰底、分隔线断掉 */
  }
    .toolbox-sidebar .tool-count { height: 36px; display: flex; align-items: center; margin-bottom: 8px; padding-left: 44px; }
  .toolbox-sidebar #toolSearch { height: 44px; background: var(--bg); margin-bottom: 12px; }
  /* 常用工具折叠区（方案 B）：触发器常驻、内容默认收起——首屏纵向竞争最小，标签文案完整 */
  #sidebarFavoritesToggle {
    display: flex; align-items: center; gap: 8px; width: 240px; height: 44px; padding: 0 12px;
    margin-bottom: 12px; background: var(--card); border: 1px solid var(--border);
    border-radius: var(--r-sm); color: var(--text-strong);
    font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  }
  #sidebarFavoritesToggle:hover { background: var(--surface-2); }
  #sidebarFavoritesToggle > svg:first-of-type { width: 18px; height: 18px; color: var(--primary); }
  #sidebarFavoritesToggle .favorites-label { flex: 1; text-align: left; }
  #sidebarFavoritesToggle .favorites-count {
    min-width: 22px; height: 20px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center;
    background: var(--brand-soft); border-radius: var(--r-pill); color: var(--primary); font-size: 12px;
  }
  #sidebarFavoritesToggle [data-icon=chevron-down] { width: 16px; height: 16px; color: var(--text-tertiary); transition: transform .15s; }
  [data-favorites-state=expanded] #sidebarFavoritesToggle [data-icon=chevron-down] { transform: rotate(180deg); }
  #sidebarFavorites[hidden] { display: none; }
  /* 单列 240，不是两列 116。两列时算术上根本不成立：
     116 − 边框 2 − 内边距 16 − 图标 28 − gap 12 − 星标 44 = 名字栏只剩 24px，
     实测 219 个英文名 **0 个** 能完整显示（页面上就是「Ima g…」「QR C…」）。
     改单列后名字栏 156px，193/219 完整显示；高度 4×36+3×8=168，比原来的 128 只多 40，
     侧栏内容底 673→713，仍在「绝不自己滚动」的 736 预算内。 */
  #sidebarFavorites {
    display: grid; grid-template-columns: 240px; row-gap: 8px;
    width: 240px; margin: -4px 0 12px;
  }
  #sidebarFavorites .favorite-tool-row { width: 240px; height: 36px; min-height: 0; padding: 0 8px; gap: 8px; }
  #sidebarFavorites .favorite-tool-row .tool-icon { width: 24px; height: 24px; flex: 0 0 24px; }
  #sidebarFavorites .favorite-tool-row .tool-icon svg { width: 15px; height: 15px; }
  #sidebarFavorites .favorite-tool-row .fav-copy { display: block; min-width: 0; }
  /* .tool-name 是 <span>：容器降成 block 后它就退回 inline，overflow/text-overflow 对 inline 无效，
     长名字会直接溢出压到星标上。必须显式给它 display:block。 */
  #sidebarFavorites .favorite-tool-row .tool-name { display: block; font-size: 13px; line-height: 18px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* 星标视觉压到 36 行高里，但命中区仍保持 44（只纵向外扩）。
     不能再往右拉负边距——那会吃掉与工具名之间的 8px 间隔，长名字会直接贴到星上。 */
  #sidebarFavorites .favorite-tool-row .favorite-toggle { margin: -4px 0; }
  #sidebarFavorites .favorite-empty {
    grid-column: 1 / -1; display: flex; align-items: center; justify-content: center;
    width: 240px; height: 56px; background: var(--surface-2); border: 1px solid var(--border);
    border-radius: var(--r-sm); font-size: 13px; color: var(--muted);
  }
  .toolbox-sidebar .category-list {
    width: 240px; height: 220px; min-height: 0; margin-bottom: 12px;
    background: none; border: none; box-shadow: none; overflow: visible;
  }
  /* 名称不再 flex:1 撑满：改 grid「图标 32 / 名称+计数 max-content / 弹性尾部 / chevron 18」，
     多余宽度全部落到尾部空列，行内不再出现近 200px 的中段空白（FRAMEWORK §2.4 分类行节奏） */
  .toolbox-sidebar .category-row {
    display: grid; grid-template-columns: 32px max-content max-content 18px; align-items: center;
    justify-content: start; height: 44px; padding: 0 8px; column-gap: 8px; gap: 8px;
    border-bottom: none; border-radius: var(--r-sm); background: none;
  }
  .toolbox-sidebar .category-cell { display: block; min-width: 0; }
  .toolbox-sidebar .category-meta { display: inline-flex; align-items: center; width: max-content; column-gap: 8px; gap: 8px; }
  .toolbox-sidebar .category-name { flex: 0 0 auto; flex-grow: 0; }
  .toolbox-sidebar .category-count { margin-left: 0; }
  .toolbox-sidebar .category-flex { display: block; }
  .toolbox-sidebar .category-row:hover { background: var(--surface-2); }
  .toolbox-sidebar .category-row[aria-current] { background: var(--brand-soft); }
  .toolbox-sidebar .category-icon { width: 32px; height: 32px; flex: 0 0 32px; }
  .toolbox-sidebar .category-icon svg { width: 18px; height: 18px; }
  .toolbox-sidebar .favorite-section { display: contents; }
  .toolbox-sidebar .favorite-head { display: none; }          /* 桌面用折叠触发器代替标题+徽标 */
  .toolbox-sidebar .favorite-section h2 { display: none; }   /* 桌面用折叠触发器代替标题 */
  .toolbox-sidebar .favorite-section h2 { height: 24px; margin-bottom: 8px; }
  /* 定高会把单列 4 行（168）压进 128 里溢出——高度交给内容，只保留下外边距 */
  .toolbox-sidebar .favorite-grid { row-gap: 8px; margin-bottom: 12px; }
  .toolbox-sidebar .favorite-tool-row { min-height: 0; padding: 8px; gap: 8px; border-radius: var(--r-sm); box-shadow: none; }
  .toolbox-sidebar .favorite-tool-row .tool-icon { width: 32px; height: 32px; flex: 0 0 32px; }
  .toolbox-sidebar .favorite-tool-row .tool-icon svg { width: 18px; height: 18px; }
  .toolbox-sidebar .favorite-tool-row .tool-category { display: none; }   /* 60 高只放得下工具名 */
  .toolbox-sidebar .view-all-tools { width: 240px; height: 44px; margin-bottom: 12px; border-radius: var(--r-sm); }
  .toolbox-sidebar .view-all-tools[aria-current] { background: var(--brand-soft); }
  .toolbox-sidebar .privacy-note { width: 240px; height: 56px; min-height: 0; padding: 0 8px; }

  /* 折叠开关放侧栏**左上角**（用户指定）：图标「☰」，一眼就是「开关侧栏」。
     分隔线上那个位置留给真正的返回按钮——用户原话说那里本来就该是返回。 */
  #toolboxSidebarToggle {
    position: absolute; top: 12px; inset-inline-start: 12px; z-index: 21;
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; padding: 0;
    background: none; border: none; border-radius: var(--r-sm);
    color: var(--text-tertiary); cursor: pointer;
  }
  #toolboxSidebarToggle:hover { background: var(--surface-2); }
  #toolboxSidebarToggle svg { width: 18px; height: 18px; }
  [data-sidebar-state=collapsed] #toolboxSidebarToggle { inset-inline-start: 14px; }
  [data-sidebar-state=collapsed] .rail-icon { display: inline-flex; }
  .toolbox-sidebar { position: sticky; }

  /* 折叠态：72 宽图标栏（内宽 44），右区随之变宽并从 3 列变 4 列——不用负 margin 假装扩宽 */
  [data-sidebar-state=collapsed] .toolbox-shell { grid-template-columns: 72px minmax(0, 1fr); }
  [data-sidebar-state=collapsed] .toolbox-sidebar {
    width: 72px; padding-left: 14px; padding-right: 14px;
    /* 菜单钮是绝对定位在顶部（12 + 44 = 56），图标栏内容必须从它下面开始排，
       否则第一项（搜索）会和菜单钮叠在一起（实测踩过） */
    padding-top: 64px;
  }
  [data-sidebar-state=collapsed] .toolbox-sidebar .tool-count,
  [data-sidebar-state=collapsed] .toolbox-sidebar .tool-search-box,
  [data-sidebar-state=collapsed] .toolbox-sidebar .category-cell,
  [data-sidebar-state=collapsed] .toolbox-sidebar .category-meta,
  [data-sidebar-state=collapsed] .toolbox-sidebar .category-flex,
  [data-sidebar-state=collapsed] .toolbox-sidebar .category-chevron,
  [data-sidebar-state=collapsed] .toolbox-sidebar .favorite-section,
  [data-sidebar-state=collapsed] #sidebarFavoritesToggle,
  [data-sidebar-state=collapsed] #sidebarFavorites,
  [data-sidebar-state=collapsed] .toolbox-sidebar .rail-text,
  [data-sidebar-state=collapsed] .toolbox-sidebar .sidebar-foot { display: none; }
  [data-sidebar-state=collapsed] .toolbox-sidebar .category-row {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; padding: 0; position: relative;
  }
  [data-sidebar-state=collapsed] .toolbox-sidebar .category-row[aria-current]::before {
    content: ''; position: absolute; inset-inline-start: -8px; top: 10px;
    width: 3px; height: 24px; border-radius: var(--r-pill); background: var(--primary);
  }
  [data-sidebar-state=collapsed] .toolbox-sidebar .view-all-tools,
  [data-sidebar-state=collapsed] .toolbox-sidebar .privacy-note {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; min-height: 0; padding: 0;
  }
  [data-sidebar-state=collapsed] .toolbox-sidebar .privacy-note { background: none; border-color: transparent; }
  .sidebar-search-action, .sidebar-favorites-action { display: none; }
  [data-sidebar-state=collapsed] .sidebar-search-action,
  [data-sidebar-state=collapsed] .sidebar-favorites-action {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; padding: 0;
    background: none; border: none; border-radius: var(--r-sm); color: var(--text); cursor: pointer;
  }
  [data-sidebar-state=collapsed] .sidebar-search-action:hover,
  [data-sidebar-state=collapsed] .sidebar-favorites-action:hover { background: var(--surface-2); }
  [data-sidebar-state=collapsed] .toolbox-detail .category-tool-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  .toolbox-detail { display: flex !important; padding: 32px; gap: 16px; background: var(--bg); }
  .toolbox-detail .crumb { display: flex; }
  .category-summary { display: none; }
  .category-heading { display: flex; align-items: center; gap: 16px; min-height: 96px; }
  .category-heading .category-icon { width: 48px; height: 48px; flex: 0 0 48px; background: var(--brand-soft); }
  .category-heading .category-icon svg { width: 26px; height: 26px; }
  .category-heading-copy { display: flex; flex-direction: column; gap: 4px; }
  .category-heading h2 { margin: 0; font-size: 28px; line-height: 36px; font-weight: 600; color: var(--text-strong); }
  .category-heading .category-count { font-size: 13px; line-height: 18px; color: var(--primary); }

  .category-filter-stack { position: static; min-height: 0; padding: 0; margin: 0; gap: 12px; }
  #categorySearch { width: 480px; max-width: 100%; height: 48px; }
  .subcategory-tabs { overflow-x: visible; flex-wrap: wrap; height: auto; min-height: 40px; }

  .category-tool-list { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 16px; row-gap: 12px; }
  /* 工具名/说明在桌面一律允许折行（各限 2 行）。原来只在 ≥1440 放开，可 1024–1439 这段卡最窄、
     英文名最长，反而被单行省略截成「JSON Form…」「Base64 Enc…」——英文是主场，不能这么截。
     .tool-copy 是 flex 容器，其子项的 -webkit-box 会被块级化导致 line-clamp 失效，故容器降 block。 */
  .category-tool-card .tool-copy { display: block; }
  .category-tool-card .tool-name { white-space: normal;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .category-tool-card .tool-description { white-space: normal; margin-top: 2px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
}
@media (min-width: 1440px) {
  .category-tool-list, [data-sidebar-state=collapsed] .category-tool-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .category-tool-card {
    min-height: 104px; padding: 16px; align-items: flex-start;
    border-radius: var(--r-md); box-shadow: var(--sh-1);
  }
  /* 单子分类大类：分节标题/数量/「查看全部」都是重复信息，桌面直接平铺 */
  .subcategory-section[data-single-subgroup] .section-heading { display: none; }
  .load-more-tools { min-width: 160px; width: auto; align-self: center; padding: 0 24px; }
  .sidebar-foot { display: none; }
}

/* ===================================================================
   T02 工具详情页外壳 + 219 页共用控件
   真源：uitools/screens/T02.spec.yaml（universalControls / variants）
   验收：T02.accept.yaml。外壳由 public/tools/toolshell.js 运行时注入。
   =================================================================== */
:root {
  --qd-font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  --qd-mono: ui-monospace, SFMono-Regular, "Cascadia Code", "Roboto Mono", monospace;
  --neutral-50: #f8fafc;
  --disabled-bg: #e8eef7; --disabled-border: #dbe3ee; --disabled-text: #94a3b8;
  --brand-hover: #1d4ed8; --brand-pressed: #1e40af; --brand-soft-pressed: #dbeafe;
  --danger-hover: #b91c1c; --danger-soft: #fef2f2; --danger-brd: #fecaca;
  --success: #059669; --success-soft: #ecfdf5; --success-brd: #a7f3d0;
  --warning: #d97706; --warning-soft: #fffbeb; --warning-brd: #fde68a;
}
body { font-family: var(--qd-font); }

/* —— 外壳 —— */
.tool-page .mobile-titlebar h1 { font-size: 20px; line-height: 28px; font-weight: 600; margin: 0; }
.mobile-titlebar button, .mobile-titlebar .tool-help {
  background: none; border: none; padding: 0; color: var(--text); font: inherit; box-shadow: none;
}
.mobile-titlebar button:hover { background: none; }
.mobile-tool-detail { width: 100%; }
.tool-detail .crumb { display: flex; align-items: center; gap: 4px; overflow-x: auto; white-space: nowrap; scrollbar-width: none; }
/* 16 个地址生成器共用的行内复制钮只有 46×18，同样低于 24。它在页面自己的 <style> 里定义，
   这里补一条最小高度即可（不动它的显隐逻辑——手机端已有 opacity 兜底）。 */
.ag-row .ag-copy { min-height: 24px; }

/* 面包屑每一级都是导航控件，命中区不能只有文字那 21px 高（WCAG 2.5.8 AA 要求 ≥24）。
   容器 44 高且垂直居中，给链接撑到 32 不会改变容器高度。 */
.tool-detail .crumb a, .tool-detail .crumb [data-level],
.toolbox-detail .crumb a, .toolbox-detail .crumb [data-level] {
  display: inline-flex; align-items: center; min-height: 32px;
}
.tool-detail .crumb::-webkit-scrollbar { display: none; }
.tool-detail .crumb .crumb-sep svg { width: 16px; height: 16px; }

.tool-heading {
  display: flex; align-items: flex-start; gap: 12px; min-height: 124px; padding: 16px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.tool-heading .tool-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; flex: 0 0 48px;
  background: var(--brand-soft); border-radius: var(--r-sm); color: var(--primary);
}
.tool-heading .tool-icon svg { width: 26px; height: 26px; }
.tool-heading-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; min-width: 0; flex: 1; }
.tool-heading h2 { margin: 0; font-size: 20px; line-height: 28px; font-weight: 600; color: var(--text-strong); }
.tool-heading .tool-description {
  margin: 0; font-size: 13px; line-height: 20px; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.local-processing-badge {
  display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px;
  background: var(--brand-soft); border: 1px solid var(--brand-soft-border); border-radius: var(--r-pill);
  color: var(--primary); font-size: 12px; line-height: 18px; font-weight: 600;
}
.local-processing-badge svg { width: 16px; height: 16px; }

.card.tool-workspace, .card.result-panel, .tool-detail > .card {
  display: flex; flex-direction: column; gap: 16px; padding: 16px; margin: 0;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1);
  max-width: none;
}
.tool-support-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.tool-support-grid .card { border-radius: var(--r-lg); }
.tool-settings { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }

/* 结果本身就是 textarea/输入框时，外面这层不要再画框——否则「卡片→灰框→输入框」三层套娃 */
.result-panel .result-body:has(> textarea),
.result-panel .result-body:has(> input),
.result-panel .result-body:has(> .empty-state + textarea) {
  background: none; border: none; padding: 0; min-height: 0;
}
.result-panel .result-body, .result-output {
  min-height: 160px; padding: 16px; overflow: auto;
  background: var(--neutral-50); border: 1px solid var(--border); border-radius: var(--r-md);
  font-family: var(--qd-font); font-size: 14px; line-height: 20px; white-space: pre-wrap; word-break: break-word;
}
.result-output[data-format=code], .result-panel .result-body[data-format=code] { font-family: var(--qd-mono); }
/* 注意：这里**不能**写 display —— 显隐归 .tool-detail[data-ui-state] 状态机管，
   写了会以更高特异性压过状态机，导致空态和结果同时出现（实测踩过） */
.result-panel .empty-state {
  flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  min-height: 128px; color: var(--muted); text-align: center;
}
.empty-title { margin: 0; font-size: 14px; line-height: 20px; color: var(--muted); }

/* —— 文件投放区 —— */
#fileDrop, .file-dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  min-height: 160px; padding: 24px; cursor: pointer; text-align: center;
  background: var(--brand-soft); border: 2px dashed var(--primary); border-radius: var(--r-md);
  color: var(--primary); font-size: 14px; line-height: 20px;
}
#fileDrop svg, .file-dropzone svg { width: 28px; height: 28px; }
#fileDrop:hover, .file-dropzone:hover { background: var(--brand-soft-pressed); }

/* —— 219 页共用控件 —— */
/* :where() 让这串 :not() 不贡献特异性——否则 (0,5,1) 会把下面按 data-format 指定字体的规则压掉 */
.tool-detail input:where(:not([type=range]):not([type=checkbox]):not([type=radio]):not([type=file])),
.tool-detail select, .tool-detail textarea, .tool-detail .file-picker {
  width: 100%; height: 48px; padding: 0 12px;
  background: var(--card); border: 1px solid var(--input-border); border-radius: var(--r-sm);
  color: var(--text); font-family: var(--qd-font); font-size: 14px; line-height: 20px;
}
.tool-detail input[data-format=code], .tool-detail textarea[data-format=code],
.tool-detail input[data-format=json], .tool-detail input[data-format=url],
.tool-detail input[data-format=hash], .tool-detail input[data-format=regex],
.tool-detail textarea { font-family: var(--qd-mono); }
.tool-detail input[data-format=prose], .tool-detail textarea[data-format=prose] { font-family: var(--qd-font); }
.tool-detail input:focus, .tool-detail select:focus, .tool-detail textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: var(--focus-ring);
}
.tool-detail input:disabled, .tool-detail select:disabled, .tool-detail textarea:disabled {
  background: var(--disabled-bg); border-color: var(--disabled-border); color: var(--disabled-text); cursor: not-allowed;
}
.tool-detail textarea { min-height: 160px; height: auto; padding: 12px; resize: vertical; overflow-y: auto; }
.tool-detail input[type=number] { text-align: end; }
.number-stepper { display: inline-flex; align-items: center; gap: 4px; }
.number-stepper button {
  width: 44px; height: 44px; padding: 0; flex: 0 0 44px;
  background: var(--card); border: 1px solid var(--input-border); border-radius: var(--r-sm);
  color: var(--text); font: inherit; cursor: pointer;
}
.file-picker { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }

.action-primary, .action-secondary, .action-danger, .tool-detail button.action {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 48px; padding: 0 16px; border: 1px solid transparent; border-radius: var(--r-sm);
  font-family: var(--qd-font); font-size: 14px; line-height: 20px; font-weight: 600; cursor: pointer;
}
.action-primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.action-primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.action-primary:active { background: var(--brand-pressed); border-color: var(--brand-pressed); }
.action-secondary { background: var(--card); border-color: var(--primary); color: var(--primary); }
.action-secondary:hover { background: var(--brand-soft); border-color: var(--brand-hover); color: var(--brand-hover); }
.action-secondary:active { background: var(--brand-soft-pressed); border-color: var(--brand-pressed); color: var(--brand-pressed); }
.action-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.action-danger:hover, .action-danger:active { background: var(--danger-hover); border-color: var(--danger-hover); }
.action-primary:disabled, .action-secondary:disabled, .action-danger:disabled {
  background: var(--disabled-bg); border-color: var(--disabled-border); color: var(--disabled-text); cursor: not-allowed;
}
.copy-action {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-width: 44px; height: 44px; padding: 0 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-sm);
  color: var(--text); font-family: var(--qd-font); font-size: 13px; line-height: 18px; font-weight: 600; cursor: pointer;
}
.copy-action:hover { background: var(--surface-2); }
.copy-action svg { width: 16px; height: 16px; }
.copy-action .ic-check { display: none; }
.copy-action.is-done { color: var(--success); border-color: var(--success-brd); background: var(--success-soft); }
.copy-action.is-done .ic-copy { display: none; }
.copy-action.is-done .ic-check { display: inline; }

.tool-message {
  display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 12px;
  border: 1px solid transparent; border-radius: var(--r-sm); font-size: 13px; line-height: 20px;
}
.tool-message svg { width: 18px; height: 18px; flex: 0 0 18px; }
.tool-message.info { background: var(--brand-soft); border-color: var(--brand-soft-border); color: var(--primary); }
.tool-message.success { background: var(--success-soft); border-color: var(--success-brd); color: var(--success); }
.tool-message.warning { background: var(--warning-soft); border-color: var(--warning-brd); color: var(--warning); }
.tool-message.error { background: var(--danger-soft); border-color: var(--danger-brd); color: var(--danger); }

/* —— 五态：由 .tool-detail[data-ui-state] 统一驱动，工具脚本只需改这一个属性（T02 states） —— */
.tool-progress, .partial-result, .error-state, .ideal-result,
.empty-state, .tool-message, .cancel-action, .continue-action, .retry-action,
.download-action, .copy-action { display: none; }
.tool-detail[data-ui-state=empty] .empty-state { display: flex; }
.tool-detail[data-ui-state=loading] .tool-progress { display: block; }
.tool-detail[data-ui-state=loading] .tool-message.info,
.tool-detail[data-ui-state=loading] .cancel-action { display: flex; }
.tool-detail[data-ui-state=partial] .partial-result { display: block; }
.tool-detail[data-ui-state=partial] .tool-message.warning,
.tool-detail[data-ui-state=partial] .continue-action,
.tool-detail[data-ui-state=partial] .download-action,
.tool-detail[data-ui-state=partial] .copy-action { display: flex; }
.tool-detail[data-ui-state=error] .error-state,
.tool-detail[data-ui-state=error] .tool-message.error,
.tool-detail[data-ui-state=error] .retry-action { display: flex; }
.tool-detail[data-ui-state=ideal] .ideal-result,
.tool-detail[data-ui-state=ideal] .tool-message.success,
.tool-detail[data-ui-state=ideal] .download-action,
.tool-detail[data-ui-state=ideal] .copy-action { display: flex; }
.tool-detail[data-ui-state=loading] #compressAction,
.tool-detail[data-ui-state=loading] .action-primary:not(.download-action) { pointer-events: none; }
.ideal-result, .partial-result { flex-direction: column; gap: 12px; }
.ideal-result img { max-width: 100%; max-height: 280px; border-radius: var(--r-sm); border: 1px solid var(--border); }
.result-stats { margin: 0; font-size: 14px; line-height: 20px; font-weight: 600; color: var(--text-strong); }
.failed-list { margin: 0; padding-left: 20px; font-size: 13px; line-height: 20px; color: var(--danger); }
.setting { display: flex; flex-direction: column; gap: 6px; }
.setting-label { font-size: 13px; line-height: 18px; color: var(--muted); }
.slider-row { display: flex; align-items: center; gap: 8px; height: 48px; }
.slider-row input[type=range] { flex: 1; }
.slider-row #qVal { min-width: 40px; text-align: right; font-family: var(--qd-mono); font-size: 13px; }
.tool-progress {
  align-items: center; gap: 8px; height: 8px; border-radius: var(--r-pill);
  background: var(--brand-soft); overflow: hidden;
}
.tool-progress > .bar { height: 100%; background: var(--primary); border-radius: var(--r-pill); transition: width .2s; }

.tool-workspace .row { display: flex; flex-wrap: wrap; gap: 12px; margin: 0; }
/* 主操作只有在「本行只有它一个按钮」时才满宽（imgcompress 那种单一主操作）；
   一排还有其它按钮时满宽会变成一条突兀的蓝横幅（json/base64 这类多动作页） */
.tool-workspace .action-primary.action-block { width: 100%; }
.result-panel .row { display: flex; flex-wrap: wrap; gap: 12px; margin: 0; }

.tool-page .tools-footer { min-height: 96px; }
.tool-page .tools-footer .footer-inner { flex-direction: column; gap: 4px; min-height: 96px; }

@media (min-width: 1024px) {
  .tool-page .toolbox-shell { min-height: 764px; }
  .toolbox-detail.tool-detail { display: flex !important; }
  .toolbox-detail .tool-heading { min-height: 104px; }
  .toolbox-detail .tool-heading .tool-icon { width: 56px; height: 56px; flex: 0 0 56px; border-radius: var(--r-md); }
  .toolbox-detail .tool-heading .tool-icon svg { width: 28px; height: 28px; }
  .tool-page .card.tool-workspace { padding: 24px; gap: 20px; }
  .tool-page .card.result-panel { padding: 24px; gap: 16px; }
  /* 侧栏收窄到 272 后工作区内宽 1152 → 按 2:1:1 分成 552/276/276（契约值），比写死像素更抗断点变化 */
  .tool-settings { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); gap: 24px; }
  /* 侧栏折叠后工作区变宽（内宽 1352），设置区按契约放大到 640/320/344；
     用 minmax 让更窄的桌面也能优雅收缩，不硬撑出横向滚动 */
  [data-sidebar-state=collapsed] .tool-settings {
    grid-template-columns: minmax(0, 640px) minmax(0, 320px) minmax(0, 1fr);
  }
  .tool-support-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  #fileDrop, .file-dropzone { min-height: 172px; }
  .tool-page .tools-footer { min-height: 72px; }
  .tool-page .tools-footer .footer-inner { flex-direction: row; min-height: 72px; }
}

/* 折叠态的图标提示气泡：只解释，不临时展开侧栏（FRAMEWORK §2.5） */
.sidebar-tooltip {
  position: fixed; z-index: 60; pointer-events: none;
  min-width: 96px; max-width: 240px; min-height: 36px; padding: 8px 12px;
  display: flex; align-items: center;
  background: var(--text-strong); color: #fff; border-radius: var(--r-sm);
  box-shadow: var(--sh-2); font-size: 13px; line-height: 18px;
}
.sidebar-tooltip[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .toolbox-shell, .toolbox-sidebar { transition: grid-template-columns .18s ease-out, width .18s ease-out; }
}

/* ===================================================================
   旧类名 → T02 控件契约的映射层
   219 个工具页是历年手写的，统一用 button.sec（次）/ 裸 button（主）/ .copy-btn（复制）
   / .msg + .err|.ok（提示）。这里只做**样式映射**，不改任何页面的 HTML 与脚本——
   零回归风险地让全部工具页一次跟上新控件规格。逐页接入五态（data-ui-state）另行进行。
   注意：带其它类名的按钮（.fn/.op/.on 等计算器按键）不在映射范围内，避免撑坏键盘布局。
   =================================================================== */
/* 裸 button 默认按「次操作」呈现（也是无脚本时的兜底）；哪一个该是主操作由 toolshell.js
   运行时判断后加 .action-primary —— 一排里 ≥3 个平级动作时谁都不提升，避免整排实心蓝糊成一片。 */
.tool-detail button:not([class]) {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 48px; padding: 0 16px;
  background: var(--card); border: 1px solid var(--primary); border-radius: var(--r-sm);
  font-family: var(--qd-font); font-size: 14px; line-height: 20px; font-weight: 600; color: var(--primary); cursor: pointer;
}
.tool-detail button:not([class]):hover { background: var(--brand-soft); border-color: var(--brand-hover); color: var(--brand-hover); }
.tool-detail button:not([class]):active { background: var(--brand-soft-pressed); border-color: var(--brand-pressed); color: var(--brand-pressed); }
.tool-detail button:not([class]):disabled {
  background: var(--disabled-bg); border-color: var(--disabled-border); color: var(--disabled-text); cursor: not-allowed;
}
.tool-detail button.sec:not(.copy-btn) {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 48px; padding: 0 16px;
  background: var(--card); border: 1px solid var(--primary); border-radius: var(--r-sm);
  font-family: var(--qd-font); font-size: 14px; line-height: 20px; font-weight: 600; color: var(--primary); cursor: pointer;
}
.tool-detail button.sec:not(.copy-btn):hover { background: var(--brand-soft); border-color: var(--brand-hover); color: var(--brand-hover); }
.tool-detail button.sec:not(.copy-btn):active { background: var(--brand-soft-pressed); border-color: var(--brand-pressed); color: var(--brand-pressed); }
.tool-detail .copy-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-width: 44px; height: 44px; padding: 0 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-sm);
  font-family: var(--qd-font); font-size: 13px; line-height: 18px; font-weight: 600; color: var(--text); cursor: pointer;
}
.tool-detail .copy-btn:hover { background: var(--surface-2); }

/* 提示条：页面用 msg.className = 'msg err' / 'msg ok' 切状态，映射到四态提示的视觉 */
.tool-detail .msg {
  display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 12px;
  border: 1px solid transparent; border-radius: var(--r-sm); font-size: 13px; line-height: 20px;
}
.tool-detail .msg:empty { display: none; }            /* 空提示不占位，避免每页凭空多出 48px */
.tool-detail .msg.err { background: var(--danger-soft); border-color: var(--danger-brd); color: var(--danger); }
.tool-detail .msg.ok { background: var(--success-soft); border-color: var(--success-brd); color: var(--success); }
.tool-detail .msg.muted { min-height: 0; padding: 0; border: none; background: none; color: var(--muted); }

/* 读文件等真耗时环节的忙碌指示：顶部一条不确定进度条。
   只给「确实要等」的操作用——200 个毫秒级完成的工具不加，假进度比没有更糟。 */
.tool-detail[data-busy] { position: relative; }
.tool-detail[data-busy]::before {
  content: ''; position: absolute; inset-inline: 0; top: 0; height: 3px; z-index: 5;
  background: linear-gradient(90deg, transparent, var(--primary), transparent);
  background-size: 40% 100%; background-repeat: no-repeat;
  animation: tool-busy 1s linear infinite; border-radius: var(--r-pill);
}
@keyframes tool-busy { from { background-position: -40% 0 } to { background-position: 140% 0 } }
@media (prefers-reduced-motion: reduce) {
  .tool-detail[data-busy]::before { animation: none; background: var(--primary); background-size: 100% 100%; opacity: .5; }
}

/* 外壳提供的取消按钮：只在「确实能中断」的操作进行中出现（读文件可 abort，WebCrypto 不行，
   所以不给后者假按钮）。 */
.shell-cancel {
  display: inline-flex; align-items: center; justify-content: center;
  height: 44px; padding: 0 16px; align-self: flex-start;
  background: var(--card); border: 1px solid var(--danger-brd); border-radius: var(--r-sm);
  font-family: var(--qd-font); font-size: 14px; font-weight: 600; color: var(--danger); cursor: pointer;
}
.shell-cancel:hover { background: var(--danger-soft); }
.shell-cancel[hidden] { display: none; }

/* 面包屑行：返回按钮 + 面包屑。返回只在「站内点进来」或「不在首页」时出现，
   否则不显示——一个点了没反应的返回按钮比没有更糟。 */
.crumb-row { display: flex; align-items: center; gap: 8px; }
/* 返回钮改成绝对定位后不再占横向空间，面包屑应铺满整行（T01 契约断言 .crumb 宽度 = 内容区宽） */
.crumb-row > .crumb { flex: 1; min-width: 0; }
/* 返回按钮坐在侧栏与内容区的分隔线上——用户明确要求放这个位置：
   `chevron-left` 悬在分隔线上本来就读作「返回」，之前放折叠钮才会被误认。
   文字在桌面隐藏，只留箭头，避免又变成一个抢眼的胶囊。 */
.detail-back {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  background: var(--card); border: 1px solid var(--divider); border-radius: var(--r-pill);
  box-shadow: var(--sh-1); color: var(--text); cursor: pointer;
}
.detail-back > span { display: none; }        /* 只留箭头，文案交给 aria-label 与 tooltip */
.detail-back:hover { background: var(--surface-2); color: var(--primary); border-color: var(--brand-soft-border); }
.detail-back svg { width: 18px; height: 18px; }
.detail-back[hidden] { display: none; }
@media (min-width: 1024px) {
  .toolbox-detail { position: relative; }
  .detail-back { position: absolute; top: 16px; inset-inline-start: -22px; z-index: 21; }
  .crumb-row { min-height: 44px; }
}
@media (max-width: 1023px) { .crumb-row .detail-back { display: none; } }  /* 手机已有标题栏返回 */
