/* ==========================================================================
   工具页通用版式与基础控件
   供所有工具页面复用；单个工具若需特殊样式，应放在自己的目录内，
   避免污染此文件造成工具之间互相影响。
   ========================================================================== */

/* ------------------------------------------------------------ 工具头部 */

/* 紧凑基线见 docs/DESIGN.md §5.1 */
.tool-head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--hairline);
}

/* 工具页内容区顶部比首页更紧凑。以选择器作用域生效，
   因此首页 .hero 的主视觉留白不受影响（见 §4.2 / §5.1） */
body[data-tool] .workspace {
  padding-top: var(--sp-6);
}

.tool-head__main {
  min-width: 0;
  flex: 1 1 auto;
}

/* 刻意使用 --fs-h2（20px）而非 --fs-h1（28px）：紧凑基线，见 §5.1 */
.tool-head__title {
  font-size: var(--fs-h2);
  letter-spacing: -0.02em;
}

/* 不设宽度上限，让描述优先在一行内完成（见 §5.1 约定 2） */
.tool-head__desc {
  margin-top: var(--sp-1);
  font-size: var(--fs-sm);
  color: var(--text-body);
}

/* v1.7.26：工具图标从「右端独立一列」改为「标题左侧」。
   原实现把图标推到容器最右（宽屏时距标题 900px 以上），窄栏又因 column-reverse
   翻到标题上方独占一行；作为纯装饰却抢走了视线，两种宽度下都不成立。
   现在它是标题的行首锚点，任何宽度下都成立，也不再需要 1080px 的翻转变体。 */
.tool-head__icon {
  flex: 0 0 auto;
  /* v1.7.27：独立页（tools/*/index.html）里图标仍写在标题之后，靠 order 统一到行首，
     与标签页（tabs.js 渲染，图标本就在前）保持同一版式 */
  order: -1;
  display: grid;
  place-items: center;
  width: var(--sp-10);
  height: var(--sp-10);
  margin-top: -4px; /* 与 20px 标题的光学中线对齐 */
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
}

.tool-head__icon .icon {
  width: 20px;
  height: 20px;
}

/* -------------------------------------------------------------- 面板 */

.panel-grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--sp-5);
  margin-top: var(--sp-3);
  align-items: start;
}

.panel-stack {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

.panel {
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  border-bottom: 1px solid var(--hairline);
  background: var(--bg-inset);
}

.panel__title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  /* v1.7.31：标题是**标识**，不参与压缩。此前两者都是默认 flex-shrink: 1，
     容器一变窄，长 hint（如日历覆盖说明）就把标题挤到只剩一个字宽，
     中文逐字换行后竖排成「中国日 / 历」——与 §5.1 修过的「公式」竖排同源。 */
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: var(--fs-h3);
  font-weight: var(--fw-semibold);
  color: var(--text-strong);
}

.panel__hint {
  /* 压缩全部由 hint 承担：允许收缩到内容宽以下，靠折行消化，右边缘对齐 */
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
  /* v1.7.32：原为 mono。但这里放的是中文句子（「零网络请求 · 零数据上传」
     「工作日 / 休息日按中国日历判定」…），mono 对中文只能回退到系统字体，
     结果是拉丁部分按等宽排、中文按比例排，一句话里两种节奏，还比正文更松散。
     改用正文字体；数字列（日期范围等）靠 tabular-nums 保持对齐。 */
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.panel__body {
  padding: var(--sp-5);
}

.panel__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--hairline);
  background: var(--bg-inset);
}

.panel__foot .panel__spacer {
  flex: 1 1 auto;
}

/* ------------------------------------------------------------ 表单控件 */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.field + .field {
  margin-top: var(--sp-4);
}

.field__label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  /* v1.7.26：允许折行。原实现是 nowrap 的单行 flex：当右侧 .field__hint 较长
     （如《公式计算器》的「变量名只用字母…Enter 记入历史…」）而容器变窄时，
     左侧的标签文字会被压成一字一行（实测 510px 下「公式」竖排）。 */
  flex-wrap: wrap;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-strong);
}

/* 标签文字本身不参与压缩：需要换行时由右侧提示先下去 */
.field__label > :first-child {
  flex: 0 0 auto;
}

.field__hint {
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  color: var(--text-muted);
}

.input,
.textarea,
.select {
  width: 100%;
  padding: 10px var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--text-strong);
  background: var(--bg-base);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  transition: border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.textarea {
  min-height: 260px;
  line-height: var(--lh-loose);
  resize: vertical;
}

.textarea--compact {
  min-height: 180px;
}

.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}

.input:disabled,
.textarea:disabled,
.select:disabled {
  color: var(--text-muted);
  background: var(--bg-inset);
  border-style: dashed;
  cursor: not-allowed;
}

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-body);
  cursor: pointer;
}

.checkbox input {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin-top: 3px;
  accent-color: var(--accent);
}

.checkbox input:disabled {
  cursor: not-allowed;
}

/* -------------------------------------------------------------- 按钮 */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 9px var(--sp-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-strong);
  background: var(--bg-surface);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--r-sm);
  transition: background-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.btn .icon {
  width: 15px;
  height: 15px;
}

.btn:hover:not(:disabled) {
  color: var(--text-strong);
  background: var(--bg-inset);
}

.btn:active:not(:disabled) {
  transform: translateY(1px);
}

.btn--primary {
  color: var(--accent-contrast);
  background: var(--accent);
  border-color: var(--accent);
}

.btn--primary:hover:not(:disabled) {
  color: var(--accent-contrast);
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

.btn--ghost {
  color: var(--text-body);
  background: transparent;
  border-color: transparent;
}

.btn--ghost:hover:not(:disabled) {
  background: var(--bg-hover);
}

.btn:disabled {
  /* v1.7.26：禁用态仍需可读（虚线描边 + 内嵌底已足以表达不可用） */
  color: var(--text-muted);
  background: var(--bg-inset);
  border-color: var(--hairline);
  border-style: dashed;
}

/* ------------------------------------------------------------ 提示条 */

.notice {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4);
  margin-top: var(--sp-5);
  background: var(--bg-surface);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--info);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
}

.notice__icon {
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--info);
}

.notice__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-strong);
}

.notice__text {
  margin-top: 2px;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.notice--warn {
  border-left-color: var(--warn);
}

.notice--warn .notice__icon {
  color: var(--warn);
}

.notice--danger {
  border-left-color: var(--danger);
}

.notice--danger .notice__icon {
  color: var(--danger);
}

/* ---------------------------------------------------------- 空状态 */

.empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  padding: var(--sp-8) var(--sp-4);
  text-align: left;
  color: var(--text-muted);
  background: var(--bg-inset);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--r-sm);
}

/* v1.7.12：空状态前置图标 —— 给「空」一个可识别的视觉锚点（图标来自 icons.js，经 ctx.icons 注入） */
.empty__icon {
  display: grid;
  place-items: center;
  color: var(--text-faint);
}

.empty__icon .icon {
  width: 20px;
  height: 20px;
}

.empty__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-body);
}

.empty__text {
  font-size: var(--fs-sm);
}

/* 输出区域 */
.output {
  min-height: 160px;
  padding: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: var(--lh-loose);
  color: var(--text-muted);
  white-space: pre-wrap;
  word-break: break-word;
  background: var(--bg-base);
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
}

/* 统计信息 */
.stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
}

.stat__value {
  font-family: var(--font-mono);
  font-size: var(--fs-h2);
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}

.stat__label {
  /* v1.7.32：这三个字（自然日 / 工作日 / 休息日、行数 / 字符数 / 光标…）全部是中文，
     原先的 mono + uppercase + 0.12em 字距对中文毫无作用，只会把中文字距拉松、
     让人误以为字重不均。改为正文字体 + 近乎零字距，字号回到 12px（要和数值一起被读到）。 */
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
  color: var(--text-muted);
}

/* 快捷键样式 */
kbd {
  padding: 1px 5px;
  font-size: var(--fs-2xs);
  color: var(--text-body);
  background: var(--bg-inset);
  border: 1px solid var(--hairline-strong);
  border-bottom-width: 2px;
  border-radius: var(--r-xs);
}

/* ---------------------------------------------------------- 响应式 */

@media (max-width: 1080px) {
  .panel-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* 标签工作台：同一套折行规则按「栏宽」而非视口宽判定（docs/DESIGN.md §3.5 / §4.4）。
   查询容器为 .pane__view；无匹配容器时（工具独立页）本规则整体不生效，由上面的媒体查询兜底。
   v1.7.26：工具头不再参与折行（图标已在标题左侧，任何宽度下都不需要翻转）。 */
@container pane (max-width: 1080px) {
  .panel-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 720px) {
  /* 与紧凑基线的 20px 同步下调（见 §5.1） */
  .tool-head__title {
    font-size: 18px;
  }

  .panel__body,
  .panel__head,
  .panel__foot {
    padding-left: var(--sp-4);
    padding-right: var(--sp-4);
  }

  .panel__foot .btn {
    flex: 1 1 auto;
  }
}

/* v1.7.31：面板头在窄栏下换行 —— 标题与长 hint 并排时，hint 折成两行会紧贴标题，
   两者挤在同一行且首行几乎无间隙。窄栏改为 hint 独占一行、左对齐，标题单独占首行。
   同一套规则写两遍：标签工作台按栏宽判定（@container），工具独立页无 pane 容器，由媒体查询兜底。 */
@container pane (max-width: 640px) {
  .panel__head {
    flex-wrap: wrap;
  }

  .panel__hint {
    flex-basis: 100%;
    text-align: left;
  }
}

@media (max-width: 640px) {
  .panel__head {
    flex-wrap: wrap;
  }

  .panel__hint {
    flex-basis: 100%;
    text-align: left;
  }
}

/* ---------------------------------------------------------- 右键菜单（v1.7.35）
   与标签栏的 `.tabmenu`（tabs.css）**视觉同源**：同一套令牌、同一套几何
   （min-width 184 / padding --sp-1 / 项高 32 / 圆角 r-md / shadow-3）。
   两者未合并成一个类，是因为 `.tabmenu` 带着「批量关闭待确认态 + aria-expanded 绑触发按钮」
   的耦合，抽取它的回归面远大于收益；视觉一致性靠这里的取值与那边逐一对应来保证，
   改动其中任何一处都必须同步另一处（docs/DESIGN.md §5.3）。 */

.menu {
  position: fixed;
  z-index: 140; /* 高于 .tabmenu(130)：工具内菜单可能盖在标签菜单之上 */
  min-width: 184px;
  max-width: min(320px, calc(100vw - 16px));
  padding: var(--sp-1);
  background: var(--bg-surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-3);
}

.menu[hidden] {
  display: none;
}

.menu__item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  height: 32px;
  padding: 0 var(--sp-3);
  color: var(--text-body);
  font-size: var(--fs-sm);
  text-align: left;
  white-space: nowrap;
  border-radius: var(--r-sm);
}

.menu__item:hover,
.menu__item:focus-visible {
  color: var(--text-strong);
  background: var(--bg-hover);
}

/* 焦点态：菜单里用底色 + 描边双重提示，避免在深色底上只有底色看不出焦点（§7） */
.menu__item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.menu__label {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
}

.menu__shortcut {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

.menu__item[aria-disabled="true"] {
  color: var(--text-muted);
  cursor: default;
}

.menu__item[aria-disabled="true"]:hover {
  color: var(--text-muted);
  background: none;
}

.menu__item--danger {
  color: var(--danger);
}

.menu__item--danger:hover,
.menu__item--danger:focus-visible {
  color: var(--danger);
  background: var(--danger-soft);
}

.menu__sep {
  height: 1px;
  margin: var(--sp-1) 0;
  background: var(--hairline);
}

/* 勾选项（v1.7.38）：菜里有勾选项时，**所有项**统一让出一格勾选位 ——
   只给勾选那一行让位的话，它的文字会比其它项右移一格，看上去像没对齐。
   没有勾选项的菜单（工具条「更多」、标签菜单）不受影响，保持原来的左内边距。 */
.menu--check .menu__item {
  position: relative;
  padding-left: calc(var(--sp-3) + 16px);
}

.menu__check {
  display: none;
}

.menu--check .menu__check {
  display: block;
  position: absolute;
  left: var(--sp-3);
  width: 14px;
  font-size: var(--fs-xs);
  line-height: 1;
  text-align: center;
  color: var(--accent);
}

/* 未勾选时画一个空心方框：不画的话这一项看着和其它动作项一模一样，
   而它偏偏「点了不关菜单」，用户会以为是普通的复制项（v1.7.38）。
   **只画在勾选项上** —— 其它项也有这个占位 span（为了文字对齐），
   若一起画框，整份菜单会变成「五项全是复选框」（实测就是这个效果）。 */
.menu--check .menu__item--check .menu__check:empty::before {
  content: "";
  display: block;
  width: 11px;
  height: 11px;
  margin: 0 auto;
  /* 边框用 --text-muted 而不是 --hairline-strong：后者在暗色底下与菜单底色只差 1.6:1，
     而「这行能勾选」全靠这个框表达 —— 属 WCAG 1.4.11 的非文本对比（需 ≥ 3:1）。 */
  border: 1px solid var(--text-muted);
  border-radius: 2px;
}

.menu__item[aria-checked="true"] .menu__label {
  color: var(--text-strong);
}
