/* 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 聚焦自动放大 */
  /* 显式给底色与字色：不写就落回浏览器默认「白底黑字」，暗色模式下刺眼 */
  background: var(--bg-card);
  color: var(--text-main);
}
.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;
  /* 窄屏（375px 一类手机）下两枚长标签并排会超出屏幕、整页被撑出横向滚动条。
     加 max-width + 允许换行：放得下时与原来完全一致，放不下就自动折成两行。 */
  max-width: 100%; flex-wrap: wrap;
}
.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-text); }
.tab.active {
  border-color: var(--primary);
  /* 文字用 --primary-text 不用 --primary：后者压淡底只有 3.27，14px 正文不达标（2026-10-24） */
  color: var(--primary-text);
  /* 底色先给写死的浅色作老浏览器降级，再紧跟一条 color-mix 让深色主题自动变深。
     原写法写死 #eef2ff → 深色模式下是一小块亮白斑，且对比度只有 2.70 */
  background: #eef2ff;
  background: color-mix(in srgb, var(--primary) 12%, var(--bg-card));
}

/* ---------- 模式卡（带副标的多选项卡：大小写/拼音/繁简/全半角等） ---------- */
/* 与 .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-text); }
.cc-mode.active {
  border-color: var(--primary); background: var(--primary-soft); color: var(--primary-text); font-weight: 600;
}
/* 注：底色保留 --primary-soft(28%) 这个更明显的选中观感，只换文字色。
   --primary(#667eea) 压这个底只有 2.67，--primary-text(#4338ca) 是 5.76（2026-10-24） */
.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; }

/* 税率速算表（个税页专用，2026-10-20）：满格网格 + 区间右对齐会让宽屏下看着零散
   ——区间列 342px 里文字只有一百多，全挤到右边，左侧一blank；预扣率/速算扣除数又各自贴着
   右边缘，三个数字块挨在一起。改成：去竖线只留横线、区间左对齐（起点成一条竖线）、
   数字用等宽字形、表头下边线加粗做层次。
   特异性用 .tax-table.tax-rate（0,3,1）压过 .tax-table td:first-child（0,2,1），不赌加载顺序。 */
.tax-table.tax-rate th, .tax-table.tax-rate td {
  border-left: 0; border-right: 0;
  padding: 11px 14px;
  font-variant-numeric: tabular-nums;
}
.tax-table.tax-rate th { font-weight: 600; border-bottom: 2px solid var(--border); }
.tax-table.tax-rate td:first-child { color: var(--text-muted); }
.tax-table.tax-rate th:nth-child(2), .tax-table.tax-rate td:nth-child(2) { text-align: left; }
/* 桌面/平板：收窄三个短列，把余量让给区间列，避免 342px 的空白 */
@media (min-width: 521px) {
  .tax-table.tax-rate th:first-child, .tax-table.tax-rate td:first-child { width: 12%; }
  .tax-table.tax-rate th:nth-child(3), .tax-table.tax-rate td:nth-child(3) { width: 15%; }
  .tax-table.tax-rate th:nth-child(4), .tax-table.tax-rate td:nth-child(4) { width: 21%; }
}
/* 小屏：字号与内边距收一档，四列才挤得下；短表头禁止拆字（「级数」被拆成「级/数」很难看） */
@media (max-width: 520px) {
  .tax-table.tax-rate th, .tax-table.tax-rate td { padding: 8px 6px; font-size: 12px; }
  .tax-table.tax-rate th { font-size: 11px; white-space: nowrap; }
  .tax-table.tax-rate th:nth-child(2) { white-space: normal; }
}

/* ---------- 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;
  /* 底色 #e8590c → #c2410c（2026-10-24）：白字压前者只有 3.58，后者 5.18，色相不变只压深一档 */
  font-size: .62rem; color: #fff; background: #c2410c;
  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 {
  /* #e8590c 压白卡只有 3.58，改 #c2410c 是 5.18（2026-10-24） */
  display: block; font-size: .66rem; color: #c2410c;
  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; }
}

/* 联盟推广卡：底色是写死的橙色→白渐变（第 200 行），深色主题下变成一块白亮卡，
   而 .aff-text 的深灰字反而被衬得发灰。深色下整卡跟随主题，文字转浅（2026-10-24） */
[data-theme="dark"] .affiliate-card {
  background: linear-gradient(135deg, rgba(247, 103, 7, .14) 0%, var(--bg-card) 65%);
  border-color: rgba(247, 103, 7, .35);
}
[data-theme="dark"] .affiliate-card .aff-text { color: var(--text-main); }
[data-theme="dark"] .affiliate-card .aff-label { color: #ffb77a; }

/* 联盟推广卡：底色是写死的橙色→白渐变（第 200 行），深色主题下变成一块白亮卡，
   而 .aff-text 的深灰字反而被衬得发灰。深色下整卡跟随主题，文字转浅（2026-10-24） */
[data-theme="dark"] .affiliate-card {
  background: linear-gradient(135deg, rgba(247, 103, 7, .14) 0%, var(--bg-card) 65%);
  border-color: rgba(247, 103, 7, .35);
}
[data-theme="dark"] .affiliate-card .aff-text { color: var(--text-main); }
[data-theme="dark"] .affiliate-card .aff-label { color: #ffb77a; }
