/* @layer ui — 账单、物品与订阅、待领取、最近删除、概览、重复待办（0.2 业务模块）。
 *
 * 与 tracks.css 同一条规则：**这里没有新组件，只有已有角色的新实例。**
 *   · 账单行 / 订阅行 / 凭证行 = 申请行（发丝线分行、悬停浮一层纸），不是卡片
 *   · 一组数字 = 待办面 .tasks-stats 的那种「小标签 + 大数字」，不是仪表盘
 *   · 分段 = .seg / .seg__item，芯片 = 胶囊，按钮 = --radius-sm 实心
 *   · 进度条 = 一条同款轨道（.ledger-budget__track），预算、物品用量共用
 * 所以本文件只写位置与间距，材质一律 var()，深浅两套由令牌自己成立——
 * 没有一条 [data-theme] 覆盖，也就不会漏掉「跟随系统深色」的那一半人。
 * 见 ../../../../docs/product/UI_PATTERNS.md。
 *
 * ================================================================
 * 0.3.3 复核（本人：「所有的页面…太丑了」）：本文件原来有一处成类的错误
 * ================================================================
 * `--hairline` 是**颜色**令牌（`hsl(... / 0.055)`），不是宽度。本文件十处把它当宽度写：
 *   border: var(--hairline) solid var(--border);   → border-width 非法 → 整条简写作废 → **一条边都没有**
 *   height: var(--hairline);                       → height 非法 → auto → 绝对定位的 ::before **0 像素高**
 * 后果不是"细了一点"：账单 / 物品 / 待领取 / 最近删除四个面上，
 * 所有卡片与统计块**没有边**，所有行与行之间的分隔线**看不见**——
 * 整片区域于是变成一堆没有容器的浮字，这就是「太丑了」里最实在的那一部分。
 * 实测：`.ledger-figures > div` 的 border-top-width = 0px；`.ledger-row + .ledger-row::before` 的 height = 0px。
 *
 * 改法按 themes.css 的线三级取值，不是随手挑一个：
 *   · 卡片 / 统计块 / 徽标 = **一个真实物体的边** → `1px solid var(--border)`
 *   · 行与行之间 = **内部分隔**，只是一次明度变化 → `1px` + `background: var(--hairline)`
 * 后者顺带把颜色从 `--border` 降回 `--hairline`，与 tracks.css 的 `.track-row + .track-row::before` 归队：
 * 账单行、凭证行、删除行与申请行是同一个角色，分隔线不该有两种粗细。
 */

/* ---------------- 通用：一组数字、说明、错误 ---------------- */

.ledger-head { margin-bottom: 18px; }
.ledger-head__month {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.ledger-head__month b { font-size: var(--fs-lead); font-weight: 600; }

/* auto-fill 而不是 auto-fit，是这一处的关键。
   auto-fit 会把空轨道**塌掉**并把剩下的宽度分给还在的那几块：于是「本周日程」只有
   场次 / 时长两块时，每块被拉到 305px 去装一个 11px 的标签和一个 16px 的数字，
   而隔壁「待办」四块是 148px、「申请」三块是 200px —— 概览整页除了这些块什么都没有，
   每一段却是一种块宽，看上去就是没有版式。auto-fill 保留空轨道，
   块宽只由容器决定、与这一段恰好有几个数字无关，各段自然对齐成一张网格。
   最小 124px 是照最长的一条量的（`¥10,898.00` 走 --fs-lead 的 tabular-nums），
   在 46em 版心下正好四列——概览里三段都是四个数字，最常见的那一段刚好填满。 */
.ledger-figures {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
  gap: 10px;
}
/* 侧栏那份概览宽度只有 196–292px，124px 的下限会把它压成一列。
   同一个角色允许有不同的**列数**（那是容器决定的），不允许有不同的材质。 */
.side__panel-body .ledger-figures { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; }
.ledger-figures > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  min-width: 0;
}
.ledger-figures small { font-size: var(--fs-micro); color: var(--text-faint); letter-spacing: var(--tracking-caps); }
.ledger-figures b {
  font-size: var(--fs-lead);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.ledger-figures b.is-alert { color: var(--today); }

/* 说明句要有行长上限。46em 版心在 11px 上是每行 56 个汉字，
   远超中文舒适的 30–45；这几句（存储等级、预算不阻止记账、概览不上传）都是要读进去的话，
   不是装饰。34em 折下来约 34 字一行。 */
.ledger-note {
  max-width: 34em;
  font-size: var(--fs-micro);
  line-height: 1.65;
  color: var(--text-faint);
  margin: 8px 0 0;
}
.ledger-errors {
  margin: 10px 0 0;
  padding: 8px 12px;
  list-style: none;
  border: 1px solid var(--danger-line);
  border-radius: var(--radius-sm);
  background: var(--danger-surface);
  color: var(--danger-ink);
  font-size: var(--fs-tiny);
  line-height: 1.7;
}

/* ---------------- 行：账单 / 订阅 / 到期 ---------------- */

.ledger-rows { display: flex; flex-direction: column; }
.ledger-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  border-radius: var(--radius-sm);
}
.ledger-row + .ledger-row::before {
  content: '';
  position: absolute;
  inset-inline: 8px;
  top: 0;
  height: 1px;
  background: var(--hairline);
}
.ledger-row:hover { background: var(--surface); }
.ledger-row__main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.ledger-row__main b { font-weight: 550; overflow-wrap: anywhere; }
.ledger-row__main small { font-size: var(--fs-micro); color: var(--text-faint); line-height: 1.55; }
.ledger-row__amount {
  flex: none;
  font-variant-numeric: tabular-nums;
  font-weight: 560;
}
.ledger-row.is-income .ledger-row__amount { color: var(--success-ink); }
.ledger-row.is-due .ledger-row__amount { color: var(--today); }
.ledger-row__acts { display: flex; gap: 10px; flex: none; }

/* ---- 行尾的次要动作：常态中性，悬停才亮；删除悬停转 --danger ----
   这一条 components.css 早就为侧栏的「全部隐藏」「+ 添加日历」定过了，理由一字不改：
   「低频动作一直染成强调色只会稀释强调色本身」。这里的情况更极端——
   账单一屏六行就是十二个强调色的词，物品一张卡四个，待领取一行三个，
   数下来一屏能有二十多处强调色，于是屏幕上再没有任何东西是"重点"。
   第二件事更要紧：**「删除」和「编辑」原来是同一支笔同一个字号**。
   破坏性动作与普通动作长得一样，是"点错了"的直接原因，也是这几个面最像半成品的地方。
   按 data-act 选而不是加类：这几个渲染分属四个功能模块（其中物品与订阅不在本次分工里），
   命令名是它们之间已有的稳定契约，比再要求四个模块各加一个 class 更不容易漂。 */
.ledger-row__acts .link-btn,
.ledger-budget .link-btn,
.pickup-row__acts .link-btn,
.asset-card__acts .link-btn,
.trash-row .link-btn {
  color: var(--text-muted);
  transition: color var(--dur-fast) var(--ease);
}
.ledger-row__acts .link-btn:hover,
.ledger-budget .link-btn:hover,
.pickup-row__acts .link-btn:hover,
.asset-card__acts .link-btn:hover,
.trash-row .link-btn:hover { color: var(--accent-ink); opacity: 1; }
.ledger-row__acts .link-btn[data-act*='remove']:hover,
.pickup-row__acts .link-btn[data-act*='remove']:hover,
.asset-card__acts .link-btn[data-act*='remove']:hover,
.ledger-budget .link-btn[data-act*='remove']:hover { color: var(--danger); }

/* ---------------- 预算与进度条 ---------------- */

/* 中间那一列原来是 `1fr`：在 46em 版心里进度条被抻到约 300px，
   于是「🚇交通」在最左、「¥268.00 / ¥200.00」和「删除」被顶到 300px 之外的最右，
   一句话被自己的数字拉断成两段——同一行里读不到"谁超了多少"。
   超支时更糟：那 300px 会整条填成 --today，成为全页最响的东西，
   而 themes.css 第五条讲的就是不用高饱和色铺满。
   四列都收成内容宽、整行靠左排：名字、条、数字、删除四件事挨在一起读，
   进度条 168px 已经足够表达比例，也就不再有那块红板。 */
.ledger-budget {
  display: grid;
  grid-template-columns: minmax(72px, 132px) minmax(88px, 168px) auto auto;
  justify-content: start;
  align-items: center;
  gap: 10px;
  padding: 8px;
}
.ledger-budget__name {
  font-size: var(--fs-tiny);
  color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ledger-budget__track {
  display: block;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  overflow: hidden;
}
.ledger-budget__fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--accent);
}
.ledger-budget.is-over .ledger-budget__fill { background: var(--today); }
.ledger-budget__value {
  font-size: var(--fs-micro);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ledger-budget.is-over .ledger-budget__value { color: var(--today); }

/* 与 tracks.css 的 .track-empty 同一条：只收行长，不动材质。 */
.ledger-empty { display: flex; flex-direction: column; gap: 8px; max-width: 34em; text-align: left; }
/* 0.3.3：`.ledger-empty__teach` 连同它那句重复的隐私说明一起撤掉（见
   app/features/ledger/render.js 的 dayGroups）。隐私说明只有 `.ledger-note` 一处。 */

/* ---------------- 记一笔撰写卡 ---------------- */

.modal--entry { width: min(560px, 100%); }
.modal--entry .seg { margin-bottom: 14px; }

.ledger-amount { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; }
.ledger-amount__input {
  flex: 1;
  min-width: 0;
  font-variant-numeric: tabular-nums;
}
.ledger-amount__currency { flex: none; width: 88px; }

.ledger-cats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}
.ledger-cat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 4px;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--fs-micro);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.ledger-cat:hover { border-color: var(--border-strong); color: var(--text); }
.ledger-cat.is-active {
  border-color: var(--accent-line);
  color: var(--accent-ink);
  background: var(--accent-soft);
}
.ledger-cat__emoji { font-size: var(--fs-lead); line-height: 1; }
.ledger-cat__more { grid-column: span 4; }

.ledger-switch,
.ledger-voice {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  font-size: var(--fs-tiny);
  color: var(--text-muted);
}
.ledger-voice { flex-wrap: wrap; }
.ledger-voice .ledger-note { margin: 0; flex: 1; min-width: 160px; }
.ledger-voice .is-listening { border-color: var(--accent-line); color: var(--accent-ink); }

/* ---------------- 侧栏：本月账单 ---------------- */

.side-ledger { display: flex; flex-direction: column; gap: 2px; }
.side-ledger__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 5px 6px;
  border: 0;
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-tiny);
  text-align: left;
  cursor: pointer;
}
.side-ledger__row:hover { background: var(--surface-hover); color: var(--text); }
.side-ledger__row b { font-variant-numeric: tabular-nums; color: var(--text); font-weight: 560; }

/* ---------------- 物品与订阅 ---------------- */

.assets .seg { margin-bottom: 16px; }
.asset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.asset-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  min-width: 0;
}
.asset-card.is-retired { color: var(--text-muted); }
.asset-card__head { display: flex; flex-direction: column; gap: 6px; }
.asset-card__head b { font-weight: 600; overflow-wrap: anywhere; }
.asset-card__badges { display: flex; flex-wrap: wrap; gap: 6px; }
.asset-badge {
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  font-size: var(--fs-micro);
  color: var(--text-faint);
}
.asset-card__metrics {
  margin: 0;
  font-size: var(--fs-tiny);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.asset-card__note { margin: 0; font-size: var(--fs-micro); color: var(--text-faint); }
.asset-card__acts { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------------- 待领取 ---------------- */

.pickups-panel { display: flex; flex-direction: column; gap: 4px; }
.pickup-rows { display: flex; flex-direction: column; }
.pickup-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 6px;
  border-radius: var(--radius-xs);
}
.pickup-row + .pickup-row::before {
  content: '';
  position: absolute;
  inset-inline: 6px;
  top: 0;
  height: 1px;
  background: var(--hairline);
}
.pickup-row:hover { background: var(--surface-hover); }
.pickup-row.is-pinned { background: var(--accent-soft); }
.pickup-row.is-done { color: var(--text-faint); }
.pickup-row__main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
/* 行标题只有一种字号。这一处原来钉死 --fs-tiny，于是「待领取」弹窗里的
   「取件 · 顺丰 · 6-3-2081」比同一枚弹窗尺寸下的账单行、删除行小一档——
   同一个角色的第二种长相。字号交给上下文：弹窗里随 --fs-body，
   侧栏那份密集列表仍旧收到 --fs-tiny（下面一条）。 */
.pickup-row__main b { font-weight: 550; overflow-wrap: anywhere; }
.pickup-row__main small { font-size: var(--fs-micro); color: var(--text-faint); }
.side__panel-body .pickup-row__main b { font-size: var(--fs-tiny); }
.pickup-row__acts { display: flex; gap: 8px; flex: none; }
.pickup-note { max-width: 34em; margin: 6px 0 0; font-size: var(--fs-micro); line-height: 1.6; color: var(--text-faint); }
.pickup-compose { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pickup-compose .input[type='text'] { flex: 1; min-width: 160px; }
.pickup-compose select { flex: none; width: 108px; }

/* ---------------- 最近删除 ---------------- */

.trash-rows { display: flex; flex-direction: column; }
.trash-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 6px;
  /* 账单行、凭证行、申请行都在悬停时浮一层纸，只有这里没有——同一个角色缺了一半。
     圆角跟着 .pickup-row 走（它们同在弹窗里，是同一档密度的行）。 */
  border-radius: var(--radius-xs);
  transition: background var(--dur-fast) var(--ease);
}
.trash-row:hover { background: var(--surface-hover); }
.trash-row + .trash-row::before {
  content: '';
  position: absolute;
  inset-inline: 6px;
  top: 0;
  height: 1px;
  background: var(--hairline);
}
.trash-row__kind {
  flex: none;
  min-width: 44px;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  font-size: var(--fs-micro);
  color: var(--text-faint);
  text-align: center;
}
.trash-row__main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.trash-row__main b { font-weight: 550; overflow-wrap: anywhere; }
.trash-row__main small { font-size: var(--fs-micro); color: var(--text-faint); }
/* 行尾那一格里可能是一枚**动作**（恢复），也可能是一句**状态**（无法恢复）。
   原来两者同位、同字号、同一支强调色笔，于是"已过保留期"读起来像另一枚按钮，
   点下去却什么都不发生。位置相同是对的（本来就是同一格），长相必须分开：
   动作走上面那条行尾动作规则（--text-muted，悬停转强调色），
   状态退一级到 --text-faint 并且不给任何悬停反馈——没有反馈本身就是"这不是按钮"。 */
.trash-row__note { flex: none; font-size: var(--fs-micro); color: var(--text-faint); cursor: default; }

/* ---------------- 概览 ---------------- */

.overview { display: flex; flex-direction: column; gap: 18px; }
.overview__block { display: flex; flex-direction: column; gap: 8px; }
.overview__block h3 {
  margin: 0;
  font-size: var(--fs-micro);
  font-weight: 620;
  letter-spacing: var(--tracking-caps);
  color: var(--text-faint);
}
.side__panel-body .overview { gap: 12px; }

/* ---------------- 重复待办 ---------------- */

.repeat-weekdays { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
/* 预览条按内容宽，不铺满。铺满时它是弹窗里最大的一块淡强调色，
   而里面往往只有「↻ 每周 一 · 下次 2026-09-14」十几个字——
   色块的面积应当跟着信息量走，不跟着容器走。
   （只在真的排出规则时才画这一条，见 features/task-repeat/index.js。） */
.repeat-preview {
  display: inline-block;
  max-width: 100%;
  margin: 12px 0 0;
  padding: 8px 12px;
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: var(--fs-tiny);
}
