/* ==========================================================================
   info.zzxcd.cn · text.css — 文字处理工具箱（info/text）专属层
   --------------------------------------------------------------------------
   只放**这一个页面**才有的构件：工具主体的输入/结果块、操作按钮网格、读数网格、
   正则测试器、文本对比、Markdown 预览，以及切换栏里「更多」那一格的收尾。

   共用构件一律来自 base.css + shell.css（横梁、切换栏、面板、.btn/.icon-btn/.seg、
   .field/.textarea/.out/.stat/.chip/.list、弹层/帮助/设置/轻提示/页脚），
   本文件**不重声明**它们已有的属性，只做页面专属的补充与组合。

   世界：一张纸（--c-bg）、一色墨（--c-text）、一个强调色（--c-orange）；
   结构线 2px / 3px 实心墨；层级靠零模糊硬位移；零圆角。
   本页把「当前段/当前行」交给实心墨块反白，把「命中/新增」交给辅色 --c-sky。
   ========================================================================== */

/* ============ 1. 切换栏收尾 ============
   「更多」是打开弹层的入口，不是工具格：它不吃等分宽度，图标是实心点阵不是描边。 */
.cat-more .cat-icon svg {
  fill: currentColor;
  stroke: none;
}
@media (hover: hover) {
  .cat-chip:not(.active):hover {
    background: color-mix(in srgb, var(--c-orange) 22%, var(--c-white));
  }
}
@media (max-width: 360px) {
  .cat-name {
    font-size: 0.7rem;
  }
}

/* ============ 2. 工具主体：输入 / 结果块 ============ */
.block {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  min-width: 0;
}
.block + .block {
  margin-top: 0.8rem;
}
.block-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  min-height: 1.7rem;
}
.block-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--c-text-sub);
}
.block-actions {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
}
/* 输入框下的实时读数：等宽、tabular，锚在右下 */
.field-count {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--c-text-sub);
  text-align: right;
}
/* 结果刚落地的机械闪一下（不是呼吸灯，也不改透明度） */
@keyframes out-flash {
  from {
    background: color-mix(in srgb, var(--c-orange) 26%, var(--c-bg));
  }
}
.out.pulse {
  animation: out-flash var(--nb-dur-slow) var(--ease-snap);
}
/* 失败态：左侧一条粗墨边 + 加粗，仍是结果框本身，不另起一个告警卡片 */
.out.error {
  border-left-width: 0.5rem;
  font-weight: 700;
}

/* 工具切换：整张卡片机械地挪一下，表示换了层（入场从已可见出发）
   ⚠️ 类名必须带限定：`.switch` 是 shell.css 的开关组件（2.6rem × 1.5rem + relative），
   卡片上直接挂 `.switch` 会被压成 43×32 的小方块（实测踩过）。 */
@keyframes tool-swap {
  from {
    transform: translateX(0.45rem);
  }
}
.tool-card.tool-swap {
  animation: tool-swap var(--nb-dur-slow) var(--ease-snap);
}

/* ============ 3. 转换操作网格 ============ */
.ops-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.6rem, 1fr));
  gap: 0.45rem;
  margin-bottom: 0.85rem;
}
/* 操作按钮就是 .btn：白面墨字 + 墨线，一屏唯一那个强调色实心块留给「应用到输入 ↓」
   字号比 .btn 小 0.02rem、左右内距小 0.1rem —— 为了 390px 下三列时
   「Unicode 反转义」这类长标签不断成「反转 / 义」两行。 */
.op-btn {
  padding: 0.45rem 0.4rem;
  font-size: 0.74rem;
  line-height: 1.25;
  white-space: normal;
  text-align: center;
  min-height: 2.3rem;
}
.op-btn.active {
  background: var(--c-text);
  color: var(--c-bg);
}

/* ============ 4. 读数网格（字数统计） ============ */
.stats-grid {
  display: grid;
  /* 7rem 是「字节数（UTF-8）」这条最长的读数标签倒推出来的：0.7rem(11.2px) + 0.06em 字距下
     它要 ~95px（390px 视口按 16.64px 根字号算是 ~98px），加格内 0.8rem 内距 → 列宽 ≥7rem。
     曾写 5.6rem：那是 .stat-label 还是 0.58rem 时代的数据，字号一抬成 0.7rem
     就在桌面 9 列时溢出 18px、被右邻格的纸面白底盖住（核查代理量出 sw=95/cw=77）。 */
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
  gap: 0.45rem;
}
.stats-grid .stat {
  justify-content: center;
  min-height: 3.2rem;
  padding-inline: 0.4rem;
}
/* 允许在最坏情况下折行：字体还没加载完时（回退字体更宽）这条标签会宽 ~8px，
   而相邻格是纸面白底 —— 溢出会被盖住，看着像被裁。折行难看，但比"缺半个字"好。
   keep-all：中文不逐字断行，于是断点落在「字节数 (UTF-8)」的空格处
   （默认会断成「字节数 (UTF-」+「8)」，难看）。 */
.stats-grid .stat-label {
  word-break: keep-all;
  overflow-wrap: break-word;   /* 中文不逐字断行；万不得已才在词内断（实测断点落在「UTF-」后） */
}

/* ============ 5. 正则测试器 ============ */
.regex-pattern-row {
  display: flex;
  align-items: stretch;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}
.pattern-input {
  flex: 1 1 auto;
  font-family: var(--font-mono);
}
.flag-toggles {
  display: inline-flex;
  flex: 0 0 auto;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  overflow: hidden;
}
.flag-btn {
  appearance: none;
  width: 2.2rem;
  border: 0;
  border-right: var(--nb-rule) solid var(--c-text);
  background: transparent;
  color: var(--c-text);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap);
}
.flag-btn:last-child {
  border-right: 0;
}
.flag-btn.active {
  background: var(--c-text);
  color: var(--c-bg);
}
.match-badge {
  margin-bottom: 0.5rem;
}
.regex-preview {
  max-height: 18rem;
}
/* 命中：辅色是这套配色里的「命中/新增」信号色，前景固定墨色保证任何辅色下都可读 */
.regex-preview mark {
  background: var(--c-sky);
  color: #0a0a0a;
  font-weight: 700;
}
.regex-error {
  color: var(--c-text-sub);
}
.match-list {
  margin-top: 0.6rem;
}
.match-item {
  flex-wrap: wrap;
  align-items: baseline;
}
.mi-index {
  flex: 0 0 auto;
}
.mi-val {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-mono);
  font-weight: 700;
  word-break: break-all;
}
.mi-at {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--c-text-sub);
}
.mi-groups {
  flex: 1 0 100%;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--c-text-sub);
  word-break: break-all;
}
.mi-groups b {
  color: var(--c-text);
  font-weight: 700;
}

/* ============ 6. 文本对比 ============ */
.diff-row .textarea {
  min-height: 6rem;
}
/* 一屏唯一的主按钮：整幅强调色实心块 */
.diff-btn {
  width: 100%;
  margin: 0.15rem 0 0;
  padding: 0.55rem 0.85rem;
}
.diff-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.7rem;
  padding: 0.45rem 0.6rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--c-text-sub);
}
.diff-summary b {
  color: var(--c-text);
  font-weight: 800;
}
.diff-view {
  margin-top: 0.6rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-bg);
  max-height: 24rem;
  overflow: auto;
}
.diff-line {
  display: grid;
  grid-template-columns: 1.1rem 2.2rem minmax(0, 1fr);
  align-items: start;
  padding: 0.12rem 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.55;
}
.diff-mark {
  font-weight: 700;
  color: var(--c-text-sub);
}
.diff-num {
  padding-right: 0.4rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--c-text-sub);
}
.diff-text {
  min-width: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* 新增 = 抬起面 + 辅色纵标；删除 = 纸面 + 墨色纵标 + 删除线；相同 = 次级墨 */
.diff-line.add {
  background: var(--c-white);
  box-shadow: inset 0.25rem 0 0 var(--c-text);
  font-weight: 700;
}
.diff-line.del {
  background: var(--c-bg);
  box-shadow: inset 0.25rem 0 0 var(--c-text);
  color: var(--c-text-sub);
  text-decoration: line-through;
}
.diff-line.eq {
  color: var(--c-text-sub);
}

/* ============ 7. Markdown 预览 ============ */
.md-toggle {
  margin-bottom: 0.75rem;
}
.md-preview {
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  padding: 0.8rem;
  max-height: 34rem;
  overflow: auto;
}
.md-empty {
  color: var(--c-text-sub);
}
.markdown-body {
  font-size: 0.82rem;
  line-height: 1.7;
  overflow-wrap: anywhere;
}
.markdown-body > * + * {
  margin-top: 0.7rem;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4 {
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.25;
}
.markdown-body h1 {
  font-size: 1.25rem;
  padding-bottom: 0.3rem;
  border-bottom: var(--nb-rule-heavy) solid var(--c-text);
}
.markdown-body h2 {
  font-size: 1.06rem;
  padding-bottom: 0.25rem;
  border-bottom: var(--nb-rule) solid var(--c-text);
}
.markdown-body h3 {
  font-size: 0.94rem;
}
.markdown-body h4 {
  font-size: 0.86rem;
  color: var(--c-text-sub);
}
/* base.css 把 ul/ol 的 list-style 复位了，预览里要还回来 */
.markdown-body ul,
.markdown-body ol {
  padding-left: 1.2rem;
}
.markdown-body ul {
  list-style: square;
}
.markdown-body ol {
  list-style: decimal;
}
.markdown-body li {
  margin-top: 0.2rem;
}
.markdown-body code {
  padding: 0 0.25rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  background: color-mix(in srgb, var(--c-text) 8%, var(--c-white));
}
.markdown-body pre {
  padding: 0.6rem 0.7rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-bg);
  overflow: auto;
}
.markdown-body pre code {
  padding: 0;
  background: none;
}
.markdown-body blockquote {
  padding-left: 0.7rem;
  border-left: var(--nb-rule-heavy) solid var(--c-text);
  color: var(--c-text-sub);
}
.markdown-body hr {
  height: var(--nb-rule-heavy);
  border: 0;
  background: var(--c-text);
  margin: 1rem 0;
}
.markdown-body a {
  color: var(--c-orange);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.markdown-body table {
  width: 100%;
  border: var(--nb-rule) solid var(--c-text);
}
.markdown-body th,
.markdown-body td {
  padding: 0.3rem 0.45rem;
  border: 1px solid var(--c-text);
  text-align: left;
}
.markdown-body th {
  background: color-mix(in srgb, var(--c-text) 8%, var(--c-white));
  font-weight: 700;
}
/* LaTeX 公式是站外黑色描边图（codecogs）：所有主题下都必须垫一张亮面，否则暗色下不可见 */
.latex-inline {
  display: inline-block;
  max-width: 100%;
  padding: 0.05rem 0.15rem;
  background: #ffffff;
  vertical-align: middle;
}
.latex-block {
  text-align: center;
}
.latex-block img {
  display: inline-block;
  max-width: 100%;
  padding: 0.2rem 0.3rem;
  background: #ffffff;
}

/* ============ 8. 弹层里的分组网格 ============
   分组头是 .cat-grid 里 grid-column:1/-1 的整行元素（shell.css 已定义），
   这里只把上下两组之间的双线并成一条。 */
.sheet-body .cat-grid + .cat-grid {
  border-top: 0;
}

/* ============ 9. 窄屏 ============ */
@media (max-width: 400px) {
  .ops-grid {
    grid-template-columns: repeat(auto-fill, minmax(5.4rem, 1fr));
  }
  .stats-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .flag-btn {
    width: 2rem;
  }
  .diff-line {
    grid-template-columns: 0.9rem 1.7rem minmax(0, 1fr);
    font-size: 0.72rem;
  }
}
