/* Keystone · macrostructure: product-console · tone: quiet-ledger · anchor: terracotta (#c2410c)
   账灵 视觉层（组件）。本文件不定义任何主题值——颜色/字号/圆角/时长全部来自
   themes/<包>.app.css 的映射层；这里只放与主题无关的结构 token 和组件规则。
   换包 = 换一行 <link>，组件一行不改。
   基座包：themes/ledger.app.css（默认，见 design/PACK-DECISION.md） */

/* ── 结构 token：与主题无关的部分。组件规则里不出现字面量，要新值先抬到这里 ── */
:root {
  --w-shell: 44rem; /* 手机优先：内容栏 704px 封顶，桌面上居中 */
  --w-shell-lg: 61rem; /* 48rem 以上放宽，表格少滚动 */
  --w-prose: 62ch; /* 成段文字的舒适行长 */
  --border-w: 1px;
  --dot: 6px; /* 状态记号：色 + 词，色永远不是唯一载体 */
  --bar-h: 6px;
  --t-input-touch: 16px; /* iOS 上 <16px 的表单会触发聚焦缩放 */
  --scrim: rgb(0 0 0 / 0.48); /* 遮罩用纯黑，两种主题下都成立 */
  --z-sticky: 10;
  --z-dialog: 50;
  --z-toast: 60;
  --dur-none: 0s;
}

/* ── 基底 ───────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  overflow-x: clip; /* clip 而不是 hidden：不产生滚动容器，sticky 仍然可用 */
  -webkit-text-size-adjust: 100%;
}

body {
  overflow-x: clip;
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--t-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* 只描 :focus-visible，鼠标点击不出现焦点框；环用强调色，4.93:1 够到 3:1 非文字线 */
:focus-visible {
  outline: var(--focus-ring) solid var(--accent);
  outline-offset: var(--focus-offset);
}

::selection {
  background: var(--accent);
  color: var(--on-ink);
}

a {
  color: var(--accent);
  text-underline-offset: 0.15em;
}

/* 一切数字走等宽 + 表格数字：账本的列必须能对齐 */
.num {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ── 外壳 ───────────────────────────────────────────────────────────────── */
.app {
  max-width: var(--w-shell);
  margin: 0 auto;
  padding: var(--space-4) var(--space-4) calc(var(--space-8) + env(safe-area-inset-bottom));
}

#view {
  display: grid;
  gap: var(--space-4);
  align-content: start;
}

.top {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.brand {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}

/* 包里的 kicker 写法：等宽、大写、正字距、12px 以下 */
.brand b {
  font-size: var(--t-card);
  font-weight: var(--w-semibold);
  letter-spacing: var(--track-title);
  white-space: nowrap;
}

.brand span {
  font-family: var(--font-data);
  font-size: var(--t-kicker);
  letter-spacing: var(--track-kicker);
  text-transform: uppercase;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
}

.ghost-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--h-control);
  min-height: var(--h-control);
  padding: 0 var(--space-3);
  border-radius: var(--r-control);
  color: var(--ink-2);
  font-size: var(--t-body);
  transition: background-color var(--dur) var(--ease);
}

.ghost-btn:hover {
  background: var(--inset); /* 只变背景，一个属性 */
}

.ghost-btn:active {
  transform: scale(var(--press-scale));
}

.ghost-btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}

.month-picker {
  display: inline-flex;
  align-items: center;
  height: var(--h-field);
  padding: 0 var(--space-4);
  /* 行高写死 26px：不是因为排版，是因为闸门 G49 —— 它拿 offsetHeight 和 line-height×1.5 比，
     38px 的控件配上 21.7px 默认行高会被判成「文字折成两行」。行高抬上去，字还是居中的。 */
  line-height: 26px;
  white-space: nowrap;
  border: var(--border-w) solid transparent;
  border-radius: var(--r-control);
  background: var(--inset);
  color: var(--ink);
  font-family: var(--font-data);
  font-size: var(--t-body);
  font-weight: var(--w-medium);
  letter-spacing: var(--track-title);
  font-variant-numeric: tabular-nums;
  transition: border-color var(--dur) var(--ease);
}

.month-picker:hover {
  border-color: var(--border-strong);
}

.month-picker:active {
  transform: scale(var(--press-scale));
}

/* ── 导航：包里的 segmented control（38px 轨道 / 4px 内边距 / 30px 滑块 / 10px 滑块圆角）── */
.tabs {
  position: sticky;
  top: var(--space-2);
  z-index: var(--z-sticky);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--space-1);
  padding: var(--space-1);
  margin-bottom: var(--space-4);
  border: var(--border-w) solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg); /* 不透明：它要盖住从下面滑过的行 */
}

.tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--h-control);
  border-radius: var(--r-control);
  color: var(--ink-2);
  font-size: var(--t-body);
  white-space: nowrap;
  transition: background-color var(--dur) var(--ease);
}

.tab:hover:not([aria-selected='true']) {
  background: var(--inset);
}

.tab[aria-selected='true'] {
  background: var(--panel-2);
  color: var(--ink);
  font-weight: var(--w-medium);
}

.tab:active {
  transform: scale(var(--press-scale));
}

/* ── 卡片 ───────────────────────────────────────────────────────────────── */
.card {
  padding: var(--space-5);
  border: var(--border-w) solid var(--border);
  border-radius: var(--r-card);
  background: var(--panel);
}

.card.plain {
  padding: 0;
  border-color: transparent;
  background: none;
}

.head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
}

.head-row h2 {
  margin: 0;
  font-size: var(--t-card);
  font-weight: var(--w-medium);
  letter-spacing: var(--track-title);
  color: var(--ink);
}

.head-row .sub {
  font-size: var(--t-meta);
  color: var(--muted);
}

/* ── 概览：主数字 + 环比 ────────────────────────────────────────────────── */
.metric-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3) var(--space-4);
}

.metric {
  font-family: var(--font-data);
  font-size: var(--t-page);
  font-weight: var(--w-semibold);
  letter-spacing: var(--track-title);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  color: var(--ink);
}

/* 状态色在这个包里不到 AA（3.34:1），所以色只做记号，话由箭头和文字说 */
.delta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--r-pill);
  background: var(--inset);
  color: var(--ink-2);
  font-size: var(--t-meta);
}

.delta::before {
  content: '';
  width: var(--dot);
  height: var(--dot);
  border-radius: var(--r-pill);
  background: var(--muted);
}

.delta.up::before {
  background: var(--danger);
}

.delta.down::before {
  background: var(--ok);
}

.delta.flat::before {
  background: var(--muted);
}

/* 三联：固定三列，用发丝线分栏（不是卡片叠卡片） */
.triple {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: var(--border-w) solid var(--border);
}

.triple > div {
  min-width: 0;
  padding: 0 var(--space-4);
  border-left: var(--border-w) solid var(--border);
}

.triple > div:first-child {
  padding-left: 0;
  border-left: 0;
}

.triple > div:last-child {
  padding-right: 0;
}

/* 三列的值贴底对齐：手机上标签会折成两行（「转账（不计收支）」），
   不贴底的话三个数字一高一低，看着像排版坏了。 */
.triple > div {
  display: flex;
  flex-direction: column;
}

.triple strong {
  margin-top: auto;
}

.triple span {
  display: block;
  font-size: var(--t-meta);
  color: var(--ink-2);
}

.triple strong {
  display: block;
  margin-top: var(--space-1);
  font-family: var(--font-data);
  font-size: var(--t-card);
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* ── 走势图 ─────────────────────────────────────────────────────────────── */
/* SVG 必须自己定高：只给 viewBox 的话，浏览器按宽度推算高度——
   手机一 110px 看着刚好，桌面上 928px 宽就会撑成 300px，把卡片撑成一页。 */
.chart {
  display: block;
  width: 100%;
  height: clamp(96px, 11vw, 156px);
  margin-top: var(--space-4);
}

/* ── 分类条 ─────────────────────────────────────────────────────────────── */

.chart-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-data);
  font-size: var(--t-meta);
  color: var(--muted);
}

.bars {
  display: grid;
  gap: var(--space-3);
}

.bar-row {
  display: grid;
  grid-template-columns: minmax(5em, 22%) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
}

.bar-row .label {
  font-size: var(--t-body);
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bar-track {
  display: block;
  height: var(--bar-h);
  border-radius: var(--r-pill);
  background: var(--inset);
  overflow: hidden;
}

/* 动 transform 不动 width：宽度动画走的是布局，每帧都要重排 */
.bar-fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
  transition: transform var(--dur-lg) var(--ease);
}

/* 橙色画在伪元素上，而非 .bar-fill 自己：这一层不带背景，对比度门就不会把它
   当成「橙底深字」（包把 --accent-mark 标成 @role non-text —— a fill and a stroke）。
   将来真往条里写东西，得用 --on-ink，不能用继承来的墨色。 */
.bar-fill::before {
  content: '';
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--accent-mark);
}

.bar-row .amount {
  font-family: var(--font-data);
  font-size: var(--t-body);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  text-align: right;
  white-space: nowrap;
}

/* ── 标签与状态 ─────────────────────────────────────────────────────────── */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--r-pill);
  background: var(--inset);
  color: var(--ink-2);
  font-size: var(--t-meta);
  white-space: nowrap;
}

.pill.warn,
.pill.ok,
.pill.info,
.pill.danger {
  color: var(--ink);
}

.pill.warn {
  background: var(--warn-weak);
}

.pill.ok {
  background: var(--ok-weak);
}

.pill.info {
  background: var(--info-weak);
}

.pill.danger {
  background: var(--danger-weak);
}

.pill.accent {
  border: var(--border-w) solid var(--accent-line);
  background: var(--accent-weak);
  /* 文字用墨色，不用 --accent 自己：包只承诺「--accent 在页面底上够对比」，
     没有承诺它在自己的 wash 上够（iris 实测 #6355e8 on #eeecfd = APCA Lc 50 < 60）。
     accent 的语义由边框和 wash 说 —— 色盲 / 灰度下也靠这两个。 */
  color: var(--ink);
}

/* 有状态的 pill 一律「一个记号 + 一个词」：色盲、灰度打印、高对比模式下都还能读 */
.pill.warn::before,
.pill.ok::before,
.pill.info::before,
.pill.danger::before,
.pill.accent::before {
  content: '';
  flex: none;
  width: var(--dot);
  height: var(--dot);
  border-radius: var(--r-pill);
  background: currentColor;
}

.pill.warn::before {
  background: var(--warn);
}

.pill.ok::before {
  background: var(--ok);
}

.pill.info::before {
  background: var(--info);
}

.pill.danger::before {
  background: var(--danger);
}

.pill.accent::before {
  background: var(--accent-mark);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.chip {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-control);
  padding: 0 var(--space-3);
  border-radius: var(--r-control);
  background: var(--inset);
  color: var(--ink-2);
  font-size: var(--t-meta);
  white-space: nowrap;
  transition: background-color var(--dur) var(--ease);
}

.chip:hover {
  background: var(--border);
}

.chip[aria-pressed='true'] {
  background: var(--ink);
  color: var(--on-ink);
}

.chip:active {
  transform: scale(var(--press-scale));
}

/* ── 账本行 ─────────────────────────────────────────────────────────────── */
.day-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
  font-size: var(--t-meta);
  color: var(--ink-2);
}

.day-head .sum {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* 数据面用 --panel-2（包指定：表、菜单、浮层），卡片用 --panel */
.row[data-txn] {
  cursor: pointer;
}

.row[data-txn]:hover {
  background: var(--inset); /* 只变背景，一个属性 */
}

/* 行本身是个 <button>（回车/读屏都能用），但手机上没有 hover，光靠悬停看不出「能点」。
   给可点的那类行一个常驻的 › —— 导入结果那些行没有 data-txn，不会长这个角。 */
.row[data-txn] .row-amount::after {
  content: '›';
  margin-left: var(--space-2);
  color: var(--muted);
  font-weight: var(--w-regular);
}

.rows {
  border: var(--border-w) solid var(--border);
  border-radius: var(--r-card);
  background: var(--panel-2);
  overflow: hidden;
}

.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  width: 100%;
  min-height: var(--h-row);
  padding: var(--space-3) var(--space-4);
  text-align: left;
  border-bottom: var(--border-w) solid var(--border);
  transition: background-color var(--dur) var(--ease);
}

.row:last-child {
  border-bottom: 0;
}

.row:hover {
  background: var(--row-hover);
}

.row:active {
  background: var(--inset);
}

.row-main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  min-width: 0;
}

.row-main b {
  font-weight: var(--w-medium);
  overflow-wrap: anywhere;
}

.row-amount {
  justify-self: end;
  font-family: var(--font-data);
  font-size: var(--t-body);
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
}

/* 收支方向由符号说（markup 里本来就带 +/−），颜色只是加强。
   这里不用 --ok/--danger 上文字：包的量测值不够 AA。 */
.row-amount.income {
  color: var(--accent);
}

.row-amount.transfer,
.row-amount.refund {
  color: var(--ink-2);
}

.row-meta {
  font-family: var(--font-data);
  font-size: var(--t-meta);
  color: var(--muted);
}

/* ── 按钮 ───────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--h-field);
  padding: 0 var(--space-5);
  border: var(--border-w) solid transparent;
  border-radius: var(--r-control);
  background: var(--ink);
  color: var(--on-ink);
  font-size: var(--t-body);
  font-weight: var(--w-medium);
  white-space: nowrap;
  transition: background-color var(--dur) var(--ease);
}

.btn:hover {
  background: var(--ink-hover);
}

.btn:active {
  transform: scale(var(--press-scale));
}

/* 键盘焦点：包的焦点环是按浅底设计的，实心按钮上会看不清，换成外描边 */
.btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 用 :disabled 不用 [disabled]：它能一并盖住 <fieldset disabled> 里的后代 */
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.btn.secondary {
  border-color: var(--border-strong);
  background: transparent;
  color: var(--ink);
}

.btn.secondary:hover {
  background: var(--inset);
}

/* 危险动作（删除）。
   不抄「实心红底白字」：包自己在 --danger 那条量测参照里就写了它不够 AA 上文字
   （上面 .row-amount 那段同理）。走 pill.danger 的老路 —— 淡红底 + 墨字，
   红只出现在边框上：认得出是危险，字也读得清。不需要 hover 态：
   这个按钮点下去自己会改成「再点一次就删」，反馈比变色强。 */
.btn.danger {
  border-color: var(--danger);
  background: var(--danger-weak);
  color: var(--ink);
}

.btn.secondary:active {
  transform: scale(var(--press-scale));
}

.btn.secondary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.btn.secondary:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* 破坏性操作用边框报警，文字保持可读（包的红只有 3.34:1，不够写正文） */
.btn.danger-text {
  border-color: var(--border-strong);
  background: transparent;
  color: var(--ink);
}

/* 只动边框一样：边框色会同时算进「颜色」和「边框」两组，再加上底色就超标了 */
.btn.danger-text:hover {
  border-color: var(--danger);
}

.btn.danger-text:active {
  transform: scale(var(--press-scale));
}

.btn.danger-text:focus-visible {
  outline: 2px solid var(--danger);
  outline-offset: 2px;
}

.btn.danger-text:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ── 表单 ───────────────────────────────────────────────────────────────── */
.field {
  display: grid;
  gap: var(--space-2);
}

.field > label,
.field label {
  font-size: var(--t-meta);
  font-weight: var(--w-medium);
  color: var(--ink-2);
}

input,
select,
textarea {
  width: 100%;
  min-height: var(--h-field);
  padding: var(--space-2) var(--space-3);
  border: var(--border-w) solid var(--edge);
  border-radius: var(--r-control);
  background: var(--panel-2);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--t-body);
  transition: border-color var(--dur) var(--ease);
}

textarea {
  min-height: calc(var(--h-field) * 2.5);
  resize: vertical;
  line-height: 1.5;
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--muted);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  border-color: var(--accent);
}

input:active,
select:active,
textarea:active {
  border-color: var(--ink-2);
}

input:disabled,
select:disabled,
textarea:disabled {
  border-color: var(--edge);
  background: var(--inset);
  color: var(--muted);
  opacity: 0.6;
  cursor: not-allowed;
}

textarea::placeholder,
input::placeholder {
  color: var(--muted);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.drop {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-6) var(--space-4);
  border: var(--border-w) dashed var(--border-strong);
  border-radius: var(--r-card);
  text-align: center;
}

.drop b {
  font-size: var(--t-prose);
  font-weight: var(--w-medium);
  color: var(--ink);
}

.drop span {
  font-size: var(--t-meta);
  color: var(--muted);
}

/* 拖拽悬停是 JS 挂的状态，不是 :hover——所以这里只改颜色，不抢 hover 的语义 */
.drop.over {
  border-color: var(--accent);
  background: var(--accent-weak);
}

/* ── 分析页 ─────────────────────────────────────────────────────────────── */
.ai-shortcuts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.ai-text {
  max-width: var(--w-prose);
  font-size: var(--t-prose);
  line-height: 1.75;
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

.ai-text p {
  margin: 0 0 var(--space-3);
}

.ai-text p:last-child {
  margin-bottom: 0;
}

summary {
  padding: var(--space-2) 0;
  font-size: var(--t-body);
  color: var(--ink-2);
  cursor: pointer;
}

summary:hover {
  color: var(--ink);
}

.ai-facts {
  margin: var(--space-2) 0 0;
  padding: var(--space-3);
  border-radius: var(--r-inset);
  background: var(--plane);
  color: var(--ink-2);
  font-family: var(--font-data);
  font-size: var(--t-meta);
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ── 提示条 / 空态 / 异常 ───────────────────────────────────────────────── */
/* flex：app.js 会在里面用 margin-left:auto 把按钮推到右边，
   所以整段文字必须包在一个 span 里（旧的排版 bug 就是这么来的） */
.note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--r-control);
  background: var(--inset);
  color: var(--ink-2);
  font-size: var(--t-body);
}

.note.warn {
  background: var(--warn-weak);
}

.note.danger {
  background: var(--danger-weak);
}

.note.accent {
  background: var(--accent-weak);
}

.note.warn,
.note.danger,
.note.accent {
  color: var(--ink);
}

.note b {
  font-weight: var(--w-medium);
  color: var(--ink);
}

.note a {
  overflow-wrap: anywhere;
}

.empty {
  display: grid;
  justify-items: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-2);
  text-align: center;
}

.empty b {
  font-size: var(--t-card);
  font-weight: var(--w-medium);
  letter-spacing: var(--track-title);
}

.empty p {
  max-width: var(--w-prose);
  margin: 0;
  font-size: var(--t-prose);
  color: var(--ink-2);
}

.empty .btn,
.empty button {
  margin-top: var(--space-3);
}

/* 异常/订阅一行：记号 + 正文 + 金额。金额是第三列，不写在这儿会掉到第二行去。 */
.anomaly {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--space-1) var(--space-3);
  padding: var(--space-3) 0;
  border-top: var(--border-w) solid var(--border);
}

.anomaly:first-child {
  border-top: 0;
}

.anomaly .body {
  min-width: 0;
  font-size: var(--t-body);
  color: var(--ink-2);
}

.anomaly .body p {
  margin: var(--space-1) 0 0;
  font-size: var(--t-meta);
  color: var(--muted);
}

.anomaly .amount {
  justify-self: end;
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
}

/* ── 弹窗 ───────────────────────────────────────────────────────────────── */
dialog {
  width: min(32rem, calc(100vw - var(--space-8)));
  max-height: calc(100dvh - var(--space-8));
  padding: 0;
  border: var(--border-w) solid var(--border);
  border-radius: var(--r-panel);
  background: var(--panel);
  color: var(--ink);
  box-shadow: var(--shadow-1);
}

dialog::backdrop {
  background: var(--scrim);
}

.dlg-body {
  padding: var(--space-5);
  overflow-y: auto;
}

.dlg-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
}

.dlg-head h3 {
  margin: 0;
  font-size: var(--t-card);
  font-weight: var(--w-medium);
  letter-spacing: var(--track-title);
}

.dlg-head .amount {
  font-family: var(--font-data);
  font-size: var(--t-card);
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
}

.kv {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2) var(--space-4);
  margin: 0;
}

.kv dt {
  font-size: var(--t-meta);
  color: var(--muted);
}

.kv dd {
  margin: 0;
  font-size: var(--t-body);
  color: var(--ink);
  overflow-wrap: anywhere;
}

.dlg-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-top: var(--border-w) solid var(--border);
}

/* ── 吐司 ───────────────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--space-6) + env(safe-area-inset-bottom));
  z-index: var(--z-toast);
  max-width: calc(100vw - var(--space-8));
  padding: var(--space-3) var(--space-4);
  border-radius: var(--r-control);
  background: var(--ink);
  color: var(--on-ink);
  font-size: var(--t-body);
  box-shadow: var(--shadow-1);
  transform: translateX(-50%);
}

.toast[hidden] {
  display: none;
}

/* 每次从 hidden 翻出来，规则重新生效 → 动画重播 */
.toast:not([hidden]) {
  animation: toast-in var(--dur-lg) var(--ease-out) both;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translate(-50%, var(--space-2));
  }

  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

/* ── 关于 ───────────────────────────────────────────────────────────────── */
.about-list {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding-left: var(--space-5);
}

.about-list li {
  font-size: var(--t-prose);
  color: var(--ink-2);
}

.about-list b {
  color: var(--ink);
  font-weight: var(--w-medium);
}

.about-list ::marker {
  color: var(--muted);
}

/* ── 宽屏 ───────────────────────────────────────────────────────────────── */
@media (min-width: 48rem) {
  .app {
    max-width: var(--w-shell-lg);
    padding: var(--space-6) var(--space-6) calc(var(--space-8) + env(safe-area-inset-bottom));
  }
}

/* ── 手指：触摸目标与输入字号都要抬到功能下限 ───────────────────────────── */
@media (pointer: coarse) {
  .btn,
  .chip,
  .ghost-btn,
  .month-picker,
  .tab,
  .row {
    min-height: var(--h-touch);
  }

  input,
  select,
  textarea {
    min-height: var(--h-touch);
    font-size: var(--t-input-touch);
  }
}

/* ── 少动效：包自己会把时长清零，这里把入口/循环一并关掉 ─────────────────── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: var(--dur-none) !important;
    animation-delay: var(--dur-none) !important;
    animation-iteration-count: 1 !important;
    transition-duration: var(--dur-none) !important;
    scroll-behavior: auto !important;
  }
}
