/* components.css — B 方案重构新增组件类（与 style.css 互补，覆盖统一布局下的工具页） */

/* ---------- 工具页 hero ---------- */
.tool-hero { text-align: center; padding: 24px 0 20px; }
.tool-hero h1 { font-size: 28px; margin: 14px 0 8px; }
.tool-hero .subtitle { color: var(--text-sub); font-size: 14px; }

/* ---------- 工具内容卡片 ---------- */
.tool-card-block {
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: 14px; padding: 24px; margin-top: 8px;
}
.field-label { display: block; font-size: 13px; color: var(--text-sub); margin: 14px 0 6px; font-weight: 600; }
.text-input {
  width: 100%; padding: 10px 12px; border: 2px solid var(--border);
  border-radius: 8px; font-size: 16px; font-family: inherit; transition: border-color .2s; /* 16px 防 iOS 聚焦自动放大 */
}
.text-input:focus { outline: none; border-color: var(--primary); }
.text-input.small { max-width: 120px; }
.input-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.chk { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-sub); margin: 6px 10px 6px 0; cursor: pointer; }
.chk input { width: 16px; height: 16px; accent-color: var(--primary); }
.actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 16px 0; }

/* ---------- tabs（分段控件 / segmented control） ---------- */
/* 全站「互斥模式切换」统一用这一套：外圈软主色把多个选项圈成「一组切换项」，
   激活项 = 浅填充(#eef2ff) + 主色描边 + 主色字——与实心填充的 .btn-primary 彻底区分开，
   避免「切换模式」和「执行动作」视觉撞脸（新用户分不清哪个是按钮）。
   注意：.tab 未选中时也要保留 2px 透明边框，否则激活时描边会撑开布局造成抖动 */
.tabs {
  display: inline-flex; gap: 4px; margin-bottom: 16px; padding: 4px;
  background: var(--bg-card); border: 1px solid var(--primary-soft); border-radius: 10px;
}
.tab {
  padding: 7px 18px; border: 2px solid transparent; background: transparent;
  border-radius: 7px; cursor: pointer; font-size: 14px; color: var(--text-sub);
  font-family: inherit; transition: all .2s; white-space: nowrap;
}
.tab:hover { color: var(--primary); }
.tab.active {
  border-color: var(--primary); color: var(--primary); background: #eef2ff;
}

/* ---------- 模式卡（带副标的多选项卡：大小写/拼音/繁简/全半角等） ---------- */
/* 与 .tabs 同一套激活语义（浅填充 + 主色描边 + 主色字）；未选中为灰边卡片，
   用于选项需要一行英文副标说明的场景。原 case-convert 内联定义，现提升为全局以统一全站 */
.cc-modes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px; margin-bottom: 16px;
}
/* 紧凑变体：少数选项（2-3 个）不要 1fr 均分铺满整行——每格会占约 33% 宽（PC 约 200px），
   而卡片内容（主标 + 英文/拼音副标）实际只需 120-160px，多出的宽度变成左右大片空白、看着散。
   max-content 按内容算宽 + justify-content:start 整组靠左，窄屏由 auto-fit 自动折行。
   选择器写 .cc-modes.cc-compact(0,2,0) 压过 .cc-modes(0,1,0)：同为 (0,1,0) 时胜负由
   内联/外部 CSS 的加载顺序决定，不可靠，必须靠特异性稳赢（.mode-card 被 .field label 盖掉的教训）。
   6 个等多选项（case-convert）继续用上面的 1fr 均分铺满 */
.cc-modes.cc-compact {
  grid-template-columns: repeat(auto-fit, minmax(120px, max-content));
  justify-content: start;
}
.cc-mode {
  padding: 10px 8px; border: 2px solid var(--border); border-radius: 8px;
  background: var(--bg-card); cursor: pointer; text-align: center;
  font-size: 13px; font-weight: 500; color: var(--text-sub);
  font-family: inherit; transition: all .2s;
}
.cc-mode:hover { border-color: var(--primary); color: var(--primary); }
.cc-mode.active {
  border-color: var(--primary); background: #eef2ff; color: var(--primary); font-weight: 600;
}
.cc-mode .mode-en {
  display: block; font-size: 11px; opacity: .7; margin-top: 2px; font-weight: 400;
}
.mode-pane { margin-bottom: 8px; }

/* ---------- hash ---------- */
.hash-checks { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.hash-result-list { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.hash-result-row { display: flex; align-items: center; gap: 10px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
.hash-name { font-weight: 600; min-width: 88px; color: var(--primary-dark); }
.hash-val { flex: 1; font-family: Consolas, Monaco, monospace; font-size: 13px; word-break: break-all; color: var(--text-main); }
.hash-val.empty { color: var(--text-muted); }
.hash-copy-btn { border: 1px solid var(--border); background: var(--bg-card); border-radius: 6px; padding: 4px 12px; cursor: pointer; font-size: 12px; color: var(--text-sub); }
.hash-copy-btn:hover { border-color: var(--primary); color: var(--primary); }

/* ---------- outputs ---------- */
.output-box {
  margin-top: 14px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 8px; padding: 14px; font-family: Consolas, Monaco, monospace;
  font-size: 13px; word-break: break-all; color: var(--text-main); min-height: 44px;
}
.big-output { margin-top: 14px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 16px; font-size: 18px; font-family: Consolas, Monaco, monospace; word-break: break-all; text-align: center; color: var(--primary-dark); }
.pw-bar-wrap { height: 8px; background: var(--bg-soft); border-radius: 4px; overflow: hidden; margin: 12px 0 4px; border: 1px solid var(--border); }
.pw-bar { height: 100%; width: 0%; background: var(--success); transition: width .3s; }
.strength-label { font-size: 13px; color: var(--text-sub); }
.batch-list { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.batch-item { display: flex; align-items: center; gap: 10px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; }
.batch-item span { color: var(--text-muted); font-size: 12px; }
.batch-item code { flex: 1; word-break: break-all; }
.btn.sm, .btn-ghost.sm { padding: 4px 10px; font-size: 12px; }

/* ---------- result grid (age/tax/date) ---------- */
.result-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-top: 16px; }
.result-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 16px; text-align: center; }
.result-card.wide { grid-column: 1 / -1; }
.result-card .num { font-size: 22px; font-weight: 700; color: var(--primary-dark); word-break: break-all; }
.result-card .label { font-size: 12px; color: var(--text-sub); margin-top: 4px; }
.detail-box { margin-top: 14px; font-size: 14px; color: var(--text-sub); line-height: 1.8; }

/* ---------- tax ---------- */
.tax-result-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-top: 16px; }
.tax-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 16px; text-align: center; }
.tax-card.highlight { background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: #fff; }
.tax-card.highlight .num, .tax-card.highlight .label { color: #fff; }
.tax-card .num { font-size: 20px; font-weight: 700; color: var(--primary-dark); word-break: break-all; }
.tax-card .label { font-size: 12px; color: var(--text-sub); margin-top: 4px; }
.tax-table-wrap { margin-top: 16px; overflow-x: auto; }
.tax-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.tax-table th, .tax-table td { border: 1px solid var(--border); padding: 8px 10px; text-align: right; }
.tax-table th { background: var(--bg-soft); color: var(--text-sub); }
.tax-table td:first-child, .tax-table th:first-child { text-align: center; }
.tax-note { font-size: 12px; color: var(--text-muted); margin-top: 8px; }

/* ---------- banners ---------- */
.warn-banner { background: var(--warning-bg); border-left: 4px solid var(--warning); color: var(--warning-text); padding: 12px 14px; border-radius: 8px; font-size: 13px; line-height: 1.7; margin-bottom: 16px; }
.info-banner { background: var(--info-bg); border-left: 4px solid var(--info); color: var(--info-text); padding: 12px 14px; border-radius: 8px; font-size: 13px; line-height: 1.7; margin-bottom: 16px; }
.file-name { font-size: 13px; color: var(--text-sub); margin-top: 8px; }

/* ---------- slider ---------- */
.slider { width: 100%; accent-color: var(--primary); }

/* ---------- results table (rmb batch) ---------- */
.result-table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 13px; }
.result-table th, .result-table td { border: 1px solid var(--border); padding: 8px 10px; }
.result-table th { background: var(--bg-soft); color: var(--text-sub); }

/* ---------- crypto strength ---------- */
.cry-strength { font-size: 13px; margin: 8px 0; }
.cry-strength.weak { color: var(--danger); }
.cry-strength.medium { color: var(--warning); }
.cry-strength.strong { color: var(--success-dark); }

/* ---------- btn ghosts ---------- */
.btn-ghost { background: var(--bg-soft); color: var(--text-sub); border: 1px solid var(--border); }
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); }

/* ---------- dropzone reuse (already in style.css, ensure spacing) ---------- */
hr { border: none; border-top: 1px solid var(--border); margin: 18px 0; }

/* ---------- 广告位 ---------- */
.ad-slot { margin: 1.5rem auto 0.5rem; text-align: center; min-height: 100px; line-height: 0; }
.ad-slot ins { display: block; margin: 0 auto; }

/* ---------- 广告位 ---------- */
.ad-slot { margin: 1.5rem auto 0.5rem; text-align: center; min-height: 100px; line-height: 0; }
.ad-slot ins { display: block; margin: 0 auto; }

/* ---------- 联盟推荐卡片（高转化版） ---------- */
.affiliate-card {
  margin: 1.75rem auto 0; max-width: 720px;
  border-radius: 14px; overflow: hidden;
  border: 1px solid #ffd8b8;
  background: linear-gradient(135deg, #fff6ec 0%, #ffffff 65%);
  box-shadow: 0 3px 14px rgba(247, 103, 7, .10);
  position: relative;
}
.affiliate-card .aff-main {
  display: flex; align-items: center; gap: .75rem;
  padding: .9rem 1.1rem; text-decoration: none; color: inherit;
  min-height: 62px;
}
.affiliate-card .aff-main:hover { background: rgba(255, 148, 58, .06); }
.affiliate-card .aff-tag {
  position: absolute; top: -1px; right: -1px;
  font-size: .62rem; color: #fff; background: #e8590c;
  padding: .12rem .5rem; border-radius: 0 13px 0 8px;
  letter-spacing: .06em;
}
.affiliate-card .aff-icon { flex: 0 0 auto; font-size: 1.7rem; line-height: 1; }
.affiliate-card .aff-body { flex: 1 1 auto; min-width: 0; }
.affiliate-card .aff-label {
  display: block; font-size: .66rem; color: #e8590c;
  font-weight: 700; letter-spacing: .12em; margin-bottom: .2rem;
}
.affiliate-card .aff-text {
  display: block; font-size: .95rem; color: #2b2b2b;
  line-height: 1.45; word-break: break-all;
}
.affiliate-card .aff-cta {
  flex: 0 0 auto;
  background: linear-gradient(135deg, #ff922b, #f76707);
  color: #fff; font-size: .85rem; font-weight: 700;
  padding: .5rem .95rem; border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(247, 103, 7, .35);
  transition: transform .15s ease, box-shadow .15s ease;
}
.affiliate-card .aff-main:hover .aff-cta { transform: translateX(2px); box-shadow: 0 3px 10px rgba(247, 103, 7, .45); }
@media (max-width: 560px) {
  .affiliate-card .aff-icon { display: none; }
  .affiliate-card .aff-cta { font-size: .78rem; padding: .42rem .7rem; }
}

/* ---------- 触屏设备（手机 / 平板）：小控件可点范围扩到 ≥40px ----------
   2026-09-10 自检 B2：实测 .icon-btn 32×32、.dp-clear 20×20、.chk input 16×16、
   .fav-btn 内边距仅 2px，均低于 40–44px 的舒适点击范围，手机上点不中 / 点到隔壁。
   仅在「主指针为粗指针」时生效 → 桌面（精确指针）像素级不变、观感零影响。
   说明：.icon-btn 常以「上移 / 下移 / 删除」三个一组紧邻出现，**不能**用透明热区向外扩
   （会盖住隔壁按钮、反而更容易点错），故直接给足自身尺寸；两者间距 6px，40px 不会重叠。
   本文件在 style.css 之后加载，故此处覆盖同特异性规则可稳赢（不赌顺序）。 */
@media (pointer: coarse) {
  .icon-btn { min-width: 40px; min-height: 40px; }

  /* 日期清空叉：放大到 40×40，并同步加大输入框右侧留白，避免压住正文 */
  .dp-clear { width: 40px; height: 40px; right: 2px; font-size: 16px; }
  .dp-clear.is-date { right: 24px; }
  .dp-cell > input { padding-right: 44px !important; }
  .dp-cell > input[type="date"] { padding-right: 62px !important; }

  /* 卡片收藏星标：位于卡片角、周边无相邻控件，用透明热区外扩（视觉零变化）；
     仅限卡片内的星标（.fav-btn--page 是标题旁胶囊，另行加高） */
  .tool-card .fav-btn::after {
    content: ''; position: absolute; left: 50%; top: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }

  /* 工具页标题旁的收藏胶囊 / 勾选行：整行加高，点文字即可命中
     （.chk 本身就是 <label>，整行早已可点，这里只需补足高度） */
  .fav-btn--page { min-height: 40px; }
  .chk { min-height: 40px; }
  .chk input { width: 20px; height: 20px; }
}
