/* ==========================================================================
   info.zzxcd.cn · shell.css
   --------------------------------------------------------------------------
   信息子域 5 个工具页 markup 里**字面相同**的部分：横梁、工具切换栏、面板、
   按钮/表单/读数/列表这些基本件，以及帮助、设置、轻提示、页脚四个共用面。

   规范来源（必须逐字一致，改一处要三处同步）：
     · docs/DEVELOP.md 2.6  三个共用面：图标按钮 / 玩法说明 / 设置抽屉
     · AGENTS.md 4.1d       共用面的硬约束与色板
     · DESIGN.md            Components 的视觉语言
   各工具自己的界面写 info/assets/<工具>.css，**不要在这里加页面专属类**。
   ========================================================================== */

/* ============ 1. 横梁（页头）============
   不是居中标题堆叠：左边品牌铭牌，中间名称+副标题，右边动作位。 */
.top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.75rem;
  background: var(--c-white);
  border: var(--nb-rule) solid var(--c-text);
  box-shadow: var(--nb-shadow);
}
.brand-icon {
  width: 2.4rem;
  height: 2.4rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-orange);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.brand-icon svg {
  width: 100%;
  height: 100%;
  display: block;
}
.top-title {
  font-family: var(--font);
  font-weight: 800;
  font-size: 1rem;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.top-sub {
  grid-column: 2;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--c-text-sub);
  letter-spacing: 0.02em;
  margin-top: 0.15rem;
  min-width: 0;
}
.top-actions {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
}

/* 图标按钮 = 帮助 / 设置（共用面，见 docs/DEVELOP.md 2.6.1）
   面 = 抬起面白，线 = 2px 墨，影 = 3px 硬位移；悬停落强调色，按下位移 = 投影偏移量 */
.help-btn,
.settings-fab {
  position: static;
  width: 1.9rem;
  height: 1.9rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
  flex: 0 0 auto;
  /* ⚠️ 边框三项都要写全：只写 border-width 会拿到 UA 默认的灰色 outset 边框 */
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  color: var(--c-text);
  box-shadow: var(--nb-shadow-sm);
  transition: transform var(--nb-dur) var(--ease-snap), background var(--nb-dur) var(--ease-snap),
    box-shadow var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap);
}
.help-btn {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05rem;
}
.settings-fab svg {
  width: 1.25em;
  height: 1.25em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: square;
}
.help-btn:hover,
.settings-fab:hover {
  background: var(--c-orange);
  color: var(--nb-on-accent, #fff);
}
.help-btn:active,
.settings-fab:active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--c-text);
}

/* ============ 2. 工具切换栏 ============
   一键换工具 = 换层。当前层用实心墨块反白表达（本世界表达"当前位置"的唯一方式）。 */
.category-bar {
  display: flex;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  box-shadow: var(--nb-shadow);
  overflow: hidden;
}
/* ⚠️ 落在 overflow:hidden 容器里的可聚焦元素，焦点环要**内缩**画：
   base.css 的 3px outline + 2px offset 会被容器裁掉，Tab 过去只剩一条竖线
   （核查代理在切换栏 / 配色色卡 / 渐变卡片上量到过）。 */
.category-bar :focus-visible,
.cat-grid :focus-visible,
.seg :focus-visible {
  outline-offset: -4px;
}
.cat-chip {
  appearance: none;
  border: 0;
  border-right: var(--nb-rule) solid var(--c-text);
  background: transparent;
  color: var(--c-text);
  font-family: var(--font);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.5rem 0.15rem 0.42rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.22rem;
  flex: 1 1 0;
  min-width: 0;
  cursor: pointer;
  transition: background var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap);
}
/* 最后一格（永远是「更多」）右边不画线 —— 容器自己那圈 2px 墨线已经收边了。
   ⚠️ 要用**透明边框**而不是 `border-right: 0`：后者会让这一格比同排其它格窄 2px
   （实测 139 vs 141），五格就不齐了。 */
/* 「更多」格永远在最后一格，**与其它格等宽**：它就是同排的一格，不是另一种控件。
   ⚠️ 不要在这里写 flex: 0 0 auto / min-width 去收窄它 —— 五格就不齐了（实测 139 vs 141）。 */
.cat-more {
  flex: 1 1 0;
}
.cat-chip:last-child {
  border-right: var(--nb-rule) solid transparent;
}
/* 当前工具/层：视觉用实心墨块反白，语义用 aria-current="true"
   （五个信息页统一这一种标记；role="tablist" 那种要配 aria-controls + tabpanel 才成立，
    只有 role 没有 panel 是不完整的，所以没采用） */
.cat-chip.active,
.cat-chip[aria-current='true'],
.cat-chip[aria-selected='true'] {
  background: var(--c-text);
  color: var(--c-bg);
}
.cat-icon {
  display: block;
  width: 1.05rem;
  height: 1.05rem;
  flex: 0 0 auto;
}
.cat-icon svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: square;
}
.cat-name {
  font-size: 0.72rem;
  line-height: 1.1;
  white-space: nowrap;
}

/* 工具网格（弹层里选工具用；分组标题整行） */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(4.6rem, 1fr));
  border-top: var(--nb-rule) solid var(--c-text);
  border-left: var(--nb-rule) solid var(--c-text);
}
.cat-cell {
  appearance: none;
  border: 0;
  border-right: var(--nb-rule) solid var(--c-text);
  border-bottom: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  color: var(--c-text);
  padding: 0.55rem 0.2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  cursor: pointer;
  transition: background var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap);
}
.cat-cell.active {
  background: var(--c-text);
  color: var(--c-bg);
}
.cat-cell-icon {
  display: block;
  width: 1.15rem;
  height: 1.15rem;
}
.cat-cell-icon svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: square;
}
.cat-cell-name {
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.1;
}
.cat-group-head {
  grid-column: 1 / -1;
  padding: 0.4rem 0.6rem 0.3rem;
  background: color-mix(in srgb, var(--c-text) 7%, var(--c-white));
  border-bottom: var(--nb-rule) solid var(--c-text);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--c-text-sub);
}

/* ============ 3. 面板 / 卡片 ============ */
.panel,
.tool-card {
  background: var(--c-white);
  border: var(--nb-rule) solid var(--c-text);
  box-shadow: var(--nb-shadow);
  padding: 0.85rem;
}
/* 卡片抬头：图标 + 名称 + 一条把余下空间吃满的结构线 */
.card-head,
.panel-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.7rem;
}
.card-head-icon {
  display: flex;
  align-items: center;
  color: var(--c-orange);
  flex: 0 0 auto;
}
.card-head-icon svg {
  width: 1.05rem;
  height: 1.05rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: square;
}
.card-head-name,
.panel-title {
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  flex: 0 0 auto;
}
.card-head-line {
  flex: 1 1 auto;
  height: var(--nb-rule);
  background: var(--c-text);
  min-width: 0.5rem;
}
.panel-sub {
  font-size: 0.75rem;
  color: var(--c-text-sub);
  line-height: 1.5;
  margin-top: 0.15rem;
}
.card-hint,
.note {
  font-size: 0.75rem;
  color: var(--c-text-sub);
  line-height: 1.5;
}
.panel-grid {
  display: grid;
  gap: 0.6rem;
}
.row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.row.between {
  justify-content: space-between;
}
.row.end {
  justify-content: flex-end;
}
.stack {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* ============ 4. 按钮 ============ */
.btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0.5rem 0.85rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  color: var(--c-text);
  font-family: var(--font);
  font-size: 0.76rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: var(--nb-shadow-sm);
  transition: transform var(--nb-dur) var(--ease-snap), background var(--nb-dur) var(--ease-snap),
    box-shadow var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap);
}
.btn:hover {
  background: color-mix(in srgb, var(--c-text) 8%, var(--c-white));
}
.btn:active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--c-text);
}
/* 一屏只允许一个强调色实心块（The One Block Rule） */
.btn.primary {
  background: var(--c-orange);
  color: var(--nb-on-accent, #fff);
}
.btn.primary:hover {
  background: color-mix(in srgb, var(--c-text) 12%, var(--c-orange));
}
.btn.small {
  padding: 0.3rem 0.55rem;
  font-size: 0.7rem;
  box-shadow: none;
}
.btn.small:active {
  transform: translate(2px, 2px);
}
.btn.flat {
  box-shadow: none;
}
.btn.flat:active {
  transform: translate(2px, 2px);
  background: var(--c-text);
  color: var(--c-bg);
}
.btn:disabled,
.btn[disabled] {
  opacity: 0.45;
  box-shadow: none;
  cursor: not-allowed;
}
.btn:disabled:active {
  transform: none;
}
.btn-icon {
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
}
.btn-icon svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: square;
}

/* 图标方钮（工具内部的复制/清除/播放等小动作） */
.icon-btn {
  appearance: none;
  width: 1.9rem;
  height: 1.9rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  color: var(--c-text);
  flex: 0 0 auto;
  cursor: pointer;
  transition: background var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap),
    transform var(--nb-dur) var(--ease-snap);
}
.icon-btn svg {
  width: 1.05rem;
  height: 1.05rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: square;
}
.icon-btn:hover {
  background: var(--c-text);
  color: var(--c-bg);
}
.icon-btn:active {
  transform: translate(2px, 2px);
}
.icon-btn.on {
  background: var(--c-text);
  color: var(--c-bg);
}

/* 分段控制：当前段实心墨块反白 */
.seg {
  display: inline-flex;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  overflow: hidden;
}
.seg-btn {
  appearance: none;
  border: 0;
  border-right: var(--nb-rule) solid var(--c-text);
  background: transparent;
  color: var(--c-text);
  font-family: var(--font);
  font-size: 0.72rem;
  font-weight: 700;
  padding: 0.42rem 0.7rem;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap);
}
.seg-btn:last-child {
  border-right: 0;
}
.seg-btn.on,
.seg-btn.active {
  background: var(--c-text);
  color: var(--c-bg);
}

/* ============ 5. 表单 ============ */
.field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}
.field-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--c-text-sub);
}
.input,
.textarea,
.select {
  width: 100%;
  min-width: 0;
  padding: 0.5rem 0.6rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  color: var(--c-text);
  font-family: var(--font);
  font-size: 0.8rem;
  font-weight: 600;
  border-radius: 0;
}
.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  background: var(--c-bg);
  border-color: var(--c-sky);
  box-shadow: var(--nb-shadow-sm);
}
.textarea {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 400;
  line-height: 1.6;
  resize: vertical;
  min-height: 8rem;
}
.select {
  appearance: none;
  padding-right: 1.6rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--c-text) 50%),
    linear-gradient(135deg, var(--c-text) 50%, transparent 50%);
  background-position: calc(100% - 0.9rem) 52%, calc(100% - 0.6rem) 52%;
  background-size: 0.3rem 0.3rem, 0.3rem 0.3rem;
  background-repeat: no-repeat;
}
.toggle {
  appearance: none;
  position: relative;
  width: 2.6rem;
  height: 1.5rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  cursor: pointer;
  flex: 0 0 auto;
}
.toggle::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 1rem;
  height: calc(1.5rem - 8px);
  background: var(--c-text-sub);
  transition: transform var(--nb-dur) var(--ease-snap), background var(--nb-dur) var(--ease-snap);
}
.toggle:checked {
  background: var(--c-orange);
}
.toggle:checked::after {
  transform: translateX(1.05rem);
  background: var(--nb-on-accent, #fff);
}
.input[type='range'] {
  padding: 0;
  border: 0;
  background: none;
  appearance: none;
  height: 1.5rem;
}
.input[type='range']::-webkit-slider-runnable-track {
  height: 0.4rem;
  background: var(--c-white);
  border: var(--nb-rule) solid var(--c-text);
}
.input[type='range']::-webkit-slider-thumb {
  appearance: none;
  width: 1rem;
  height: 1.2rem;
  margin-top: -0.5rem;
  background: var(--c-orange);
  border: var(--nb-rule) solid var(--c-text);
}
.input[type='range']::-moz-range-track {
  height: 0.4rem;
  background: var(--c-white);
  border: var(--nb-rule) solid var(--c-text);
}
.input[type='range']::-moz-range-thumb {
  width: 1rem;
  height: 1.2rem;
  border-radius: 0;
  background: var(--c-orange);
  border: var(--nb-rule) solid var(--c-text);
}

/* ⚠️ 表单开关叫 .toggle 而不是 .switch：旧世界各页有把「切卡动画」的类叫 .switch 的
   （JS 里 card.classList.add('switch')）。同名跨容器会让动画类吃到这里的
   width: 2.6rem，实测把整张卡片压成 43×32、页面全塌 —— 两个页面的施工代理都踩了。
   规则见 AGENTS.md 4.1c 坑 5：通用词类名一律带限定或换语义化名。 */

/* ============ 6. 读数与标记 ============ */
.stat {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.35rem 0.5rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  min-width: 0;
}
.stat-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  /* 0.02em 而不是 0.06em：读数标签常出现在密集网格里（如字数统计 9 列），
     字距一大，「字节数（UTF-8）」这种最长的标签就把格子顶出去 —— 而相邻格是纸面白底，
     溢出的部分被盖住，看着像被裁掉。0.06em 在 11.2px 上约等于每个字多 0.7px × 12 字 ≈ 8px。 */
  letter-spacing: 0.02em;
  color: var(--c-text-sub);
}
.stat-value {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.2;
}
.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.chip,
.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.15rem 0.4rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--c-text);
}
.chip.accent {
  background: var(--c-orange);
  color: var(--nb-on-accent, #fff);
}
.kbd {
  display: inline-block;
  min-width: 1.4rem;
  padding: 0 0.3rem;
  border: 1px solid var(--c-text);
  background: color-mix(in srgb, var(--c-text) 8%, var(--c-white));
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-align: center;
}

/* 等宽输出块（结果、证书、报文都归它） */
.out {
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-bg);
  padding: 0.6rem 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  line-height: 1.6;
  word-break: break-all;
  white-space: pre-wrap;
  min-height: 2.6rem;
  max-height: 22rem;
  overflow: auto;
}
.out:empty::before {
  content: attr(data-empty);
  color: var(--c-text-sub);
}

/* ============ 7. 列表 ============ */
.list {
  display: flex;
  flex-direction: column;
  border-top: var(--nb-rule) solid var(--c-text);
}
.list-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.15rem;
  border-bottom: var(--nb-rule) solid var(--c-text);
  min-width: 0;
}
.list-item:last-child {
  border-bottom: 0;
}
.list-empty {
  padding: 1rem 0.2rem;
  text-align: center;
  font-size: 0.75rem;
  color: var(--c-text-sub);
}

/* ============ 8. 底部弹层 ============ */
.sheet {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
}
.sheet.open {
  display: block;
}
.sheet-mask {
  position: absolute;
  inset: 0;
  background: var(--nb-scrim);
}
.sheet-panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* 与内容列同宽居中：铺满 1280 视口时格子会被拉得很散，和页面框架也对不齐 */
  max-width: 46rem;
  margin-inline: auto;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  background: var(--c-white);
  border-top: var(--nb-rule-heavy) solid var(--c-text);
  box-shadow: 0 -6px 0 rgb(10 10 10 / 18%);
  animation: sheet-up var(--nb-dur-slow) var(--ease-out-expo);
}
@keyframes sheet-up {
  from {
    transform: translateY(12%);
  }
}
.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.7rem 0.8rem 0.6rem;
  border-bottom: var(--nb-rule-heavy) solid var(--c-text);
}
.sheet-title {
  font-size: 0.84rem;
  font-weight: 800;
}
.sheet-close {
  appearance: none;
  width: 1.7rem;
  height: 1.7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
}
.sheet-close:active {
  transform: translate(2px, 2px);
}
.sheet-body {
  overflow-y: auto;
  padding: 0.6rem 0.8rem 1rem;
}

/* ============ 9. 玩法说明（帮助）============
   覆层里**流式排布**的卡片，不是居中模态、也不是绝对定位卡片（见 DEVELOP.md 2.6.2） */
.help-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: none;
  background: var(--nb-scrim);
  align-items: flex-start;
  justify-content: center;
  /* 6.4rem：躲开**在流内**的横梁（app 上内距 1.1rem + 横梁最高 82px ≈ 100px）。
     旧值 3.4rem 是"按钮 fixed 在视口角"时代的算法（0.9rem + 2.4rem = 52.8px），
     按钮搬进横梁后它会横切按钮 —— 核查代理在六页上都量到了。 */
  padding: 6.4rem 1rem 1.5rem;
  overflow-y: auto;
}
.help-overlay.open {
  display: flex;
}
.help-card {
  width: 100%;
  max-width: 26rem;
  background: var(--c-white);
  border: var(--nb-rule-heavy) solid var(--c-text);
  box-shadow: var(--nb-shadow-lg);
  padding: 1rem;
  max-height: 86vh;
  overflow-y: auto;
}
.help-card h2,
.help-card h3 {
  font-size: 0.94rem;
  font-weight: 800;
  margin: 0 0 0.6rem;
  padding-bottom: 0.4rem;
  border-bottom: var(--nb-rule-heavy) solid var(--c-text);
}
.help-card ul {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.help-card li {
  position: relative;
  padding-left: 0.9rem;
  font-size: 0.76rem;
  line-height: 1.6;
  color: var(--c-text-sub);
}
.help-card .dot {
  position: absolute;
  left: 0;
  top: 0.42rem;
  width: 0.42rem;
  height: 0.42rem;
  background: var(--c-orange);
  border: 1px solid var(--c-text);
}
.help-card b {
  color: var(--c-text);
  font-weight: 700;
}
.help-card code {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  padding: 0 0.2rem;
  background: color-mix(in srgb, var(--c-text) 8%, var(--c-white));
}

/* ============ 10. 设置抽屉 ============ */
.settings-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  background: var(--nb-scrim);
  align-items: stretch;
  justify-content: flex-end;
  padding: 0;
}
.settings-overlay.open {
  display: flex;
}
.settings-panel {
  width: 100%;
  max-width: 21rem;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  background: var(--c-white);
  border: var(--nb-rule-heavy) solid var(--c-text);
  box-shadow: var(--nb-shadow-lg);
  padding: 1rem;
  transform: translateX(100%);
}
.settings-overlay.open .settings-panel {
  animation: shell-slide var(--nb-dur-slow) var(--ease-out-expo) forwards;
}
@keyframes shell-slide {
  to {
    transform: translateX(0);
  }
}
.settings-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 0.6rem;
  margin-bottom: 0.8rem;
  border-bottom: var(--nb-rule-heavy) solid var(--c-text);
}
.settings-title {
  font-size: 0.94rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.settings-close {
  appearance: none;
  width: 1.7rem;
  height: 1.7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  color: var(--c-text);
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
}
.settings-close:active {
  transform: translate(2px, 2px);
}
.settings-section {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-bottom: 1rem;
}
.settings-section-title {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-text-sub);
}
.option-row,
.color-picker-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
}
.color-picker-row {
  gap: 0.35rem;
}
/* 尺寸与色板是共用面，三处同值：见 AGENTS.md 4.1d */
.opt-btn {
  appearance: none;
  padding: 0.5rem 0.8rem;
  border: var(--nb-rule) solid var(--c-text);
  background: var(--c-white);
  color: var(--c-text);
  font-family: var(--font);
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--nb-dur) var(--ease-snap), color var(--nb-dur) var(--ease-snap);
}
.opt-btn.active {
  background: var(--c-text);
  color: var(--c-white);
}
.opt-btn:active {
  transform: translate(1px, 1px);
}
.color-label {
  flex: 0 0 auto;
  width: 2.4rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--c-text-sub);
}
.color-dot {
  width: 1.6rem;
  height: 1.6rem;
  display: inline-block;
  border: var(--nb-rule) solid var(--c-text);
  cursor: pointer;
  transition: transform var(--nb-dur) var(--ease-snap);
}
.color-dot:hover {
  transform: translate(-1px, -1px);
  box-shadow: 2px 2px 0 var(--c-text);
}
.color-dot.sel {
  box-shadow: inset 0 0 0 2px var(--c-white), inset 0 0 0 4px var(--c-text);
}
.settings-hint {
  font-size: 0.75rem;
  color: var(--c-text-sub);
  line-height: 1.5;
}

/* ============ 11. 轻提示 + 页脚 ============ */
.toast {
  position: fixed;
  left: 50%;
  bottom: 1.4rem;
  transform: translate(-50%, 1.4rem);
  z-index: 200;
  max-width: 88vw;
  padding: 0.5rem 0.8rem;
  background: var(--c-text);
  color: var(--c-bg);
  border: var(--nb-rule) solid var(--c-text);
  box-shadow: var(--nb-shadow-sm);
  font-size: 0.76rem;
  font-weight: 700;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--nb-dur) var(--ease-snap), transform var(--nb-dur) var(--ease-snap);
}
.toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

.footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin-top: 1.4rem;
  padding: 0 0.2rem 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--c-text-sub);
}
.footer a {
  color: var(--c-text-sub);
  text-decoration: none;
}
.footer a:hover {
  color: var(--c-orange);
}
.footer-sep {
  opacity: 0.5;
}

/* ============ 12. 布局节奏 ============ */
/* 工具页通用：横梁 → 切换栏 → 工具主体 */
.app > * + * {
  margin-top: 0.8rem;
}
.split {
  display: grid;
  gap: 0.8rem;
}
@media (min-width: 768px) {
  .split.two {
    grid-template-columns: 1fr 1fr;
  }
  .split.side {
    grid-template-columns: minmax(0, 1fr) 18rem;
    align-items: start;
  }
}

@media (max-width: 400px) {
  .top-sub {
    white-space: normal;
  }
}

/* 触控目标：粗指针（手指）下把**动作位**放大到可点面积。
   ⚠️ 只放大动作位；抽屉里的 .opt-btn / .color-dot 基准值本身就是可点尺寸，
   不要在断点里再重写一遍（见 AGENTS.md 4.1d）。 */
@media (pointer: coarse) {
  .help-btn,
  .settings-fab {
    width: 2.5rem;
    height: 2.5rem;
  }
  .icon-btn,
  .sheet-close,
  .settings-close {
    width: 2.25rem;
    height: 2.25rem;
  }
  .cat-chip {
    padding: 0.62rem 0.15rem 0.52rem;
  }
  .btn {
    padding: 0.6rem 0.9rem;
  }
}

/* 骨架屏 / 载入态：机械的条纹推进，不是呼吸灯 */
.loading {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.72rem;
  color: var(--c-text-sub);
}
.loading::after {
  content: '';
  width: 0.8rem;
  height: 0.8rem;
  border: var(--nb-rule) solid var(--c-text-sub);
  border-top-color: transparent;
  animation: spin 700ms steps(8, end) infinite;
}
@keyframes spin {
  to {
    transform: rotate(1turn);
  }
}

/* ---------------------------------------------------------------
   令牌桥接：子域首页 assets/home.css 用短名（--rule/--sheet/--ink…），
   而本域 base.css 用长名（--nb-* 结构令牌 / --c-* 主题令牌）。
   少了这一段，home.css 里所有 var() 都解析成空 → 首页**整页掉样式**
   （只剩光秃秃的文字，图标方块/描边/硬投影全没有）。
   ⚠️ life/study 的 shell.css 末尾同样有这一段，三域必须一致。
   本文件是纯 LF（游戏/信息两域的 assets 都是纯 LF），追加时别混进 CRLF。
   --------------------------------------------------------------- */
:root {
  --paper: var(--c-bg);
  --sheet: var(--c-white);
  --ink: var(--c-text);
  --ink-soft: var(--c-text-sub);
  --accent: var(--c-orange);
  --on-accent: #ffffff;
  --rule: var(--nb-rule) solid var(--c-text);
  --shadow: var(--nb-shadow);
  --shadow-sm: var(--nb-shadow-sm);
  --shadow-lg: var(--nb-shadow-lg);
  --dur: var(--nb-dur);
  --ease: var(--ease-snap);
}
