/* ============================================================
   polish.css —— 布局精修 + 动效层
   ------------------------------------------------------------
   加载顺序排在 components.css 之后。

   这一层刻意只做「加法」：不重定义任何既有组件的尺寸与配色，
   只补四件事 ——
     ① 原生控件跟随主题（color-scheme）
     ② 栅格按「容器宽度」而非视口自适应（container queries）
     ③ 入场编排与交互反馈（stagger / focus ring / 数值过渡）
     ④ 动效总开关（prefers-reduced-motion）

   这样即使某个组件以后被重写，这一层也不会拖后腿；
   而 ④ 必须写在最前面 —— 它是所有动效的前提条件。
   ============================================================ */

/* ============================================================
   ① 动效总开关
   ------------------------------------------------------------
   系统开了「减少动态效果」时，关掉全部动画与过渡。

   这里用 animation: none 而不是把 duration 改成 0：
   带 animation-fill-mode: both 的入场动画如果只压短时长，
   delay 期间元素仍然停在 opacity: 0，会先闪一下空白再出现。
   直接 none 则元素回到自然状态（可见），一步到位。
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  html { scroll-behavior: auto !important; }
}

/* ============================================================
   ② 原生控件跟随主题
   ------------------------------------------------------------
   深色主题下，<select> 的箭头、<input type="date"> 的日历图标、
   滚动条默认仍按「浅色」渲染，和页面配色打架。
   color-scheme 一行让浏览器用对应的原生配色。 */
:root { color-scheme: light; }
html[data-theme="dark"] { color-scheme: dark; }

/* ============================================================
   ③ 文本折行
   ------------------------------------------------------------
   balance —— 标题不再出现「最后一行只剩一个字」。
   pretty  —— 正文避免把标点、量词甩到下一行。 */
.card-head h3,
.card h4,
.kpi .k,
.title-out {
  text-wrap: balance;
}
.note > div,
.card p,
.kb-list li,
.step-list li {
  text-wrap: pretty;
}

/* ============================================================
   ④ 滚动与锚点
   ------------------------------------------------------------
   顶栏 sticky 高 62px，页内锚点跳过去会被压在它下面。 */
.content [id] { scroll-margin-top: 78px; }

/* ============================================================
   ⑤ 容器查询：栅格跟着「卡片宽度」走
   ------------------------------------------------------------
   原来的 .g4 / .g5 是按视口断点切的。但同一个 .g4，
   在全宽卡片里排 4 列正好，在 cols-2 的窄卡片里就挤成一条。

   container-type 挂在 .card-body 上而不是 .card 上：
   card-body 内部没有 sticky / fixed 后代，不会干扰表头吸顶，
   而它恰恰是所有栅格的直接父级。

   断点刻意取得比 layout.css 的视口断点更窄（520 / 340）——
   容器查询只在「容器比视口还窄」时降列，也就是把卡片塞进
   cols-2 / split 这类窄容器的场景。若两边断点重叠，
   同一区间会出现「视口说 1 列、容器说 2 列」的打架。 */
.card-body { container-type: inline-size; }

@container (max-width: 520px) {
  .card-body .g4,
  .card-body .g5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container (max-width: 340px) {
  .card-body .g2,
  .card-body .g3,
  .card-body .g4,
  .card-body .g5 { grid-template-columns: 1fr; }
}

/* ============================================================
   ⑥ :has() 条件布局
   ============================================================ */

/* 表格为空时，别留一个孤零零的表头 */
table.data:has(.empty) thead { display: none; }

/* 卡片头同时有标题和操作按钮时，提示文字要肯让位，
   否则按钮会被挤出可视区 */
.card-head:has(.actions) .hint { flex-shrink: 1; min-width: 0; }

/* ============================================================
   ⑦ 入场编排
   ------------------------------------------------------------
   切页时卡片依次上浮，间距 30ms、单张 300ms。
   30ms 这个档距是权衡过的：最慢的一张也在 210 + 300 = 510ms 内落位，
   切页不至于要等；再密就看不出「依次」了。
   ============================================================ */
@keyframes polishCardIn {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

.panel.on > .card,
.panel.on > .grid,
.panel.on > .note,
.panel.on > .cols-2 {
  animation: polishCardIn .3s cubic-bezier(.22, 1, .36, 1) both;
}
.panel.on > *:nth-child(2) { animation-delay: 30ms; }
.panel.on > *:nth-child(3) { animation-delay: 60ms; }
.panel.on > *:nth-child(4) { animation-delay: 90ms; }
.panel.on > *:nth-child(5) { animation-delay: 120ms; }
.panel.on > *:nth-child(6) { animation-delay: 150ms; }
.panel.on > *:nth-child(7) { animation-delay: 180ms; }
.panel.on > *:nth-child(n+8) { animation-delay: 210ms; }

/* 空状态也淡进来，别硬邦邦地弹出来 */
.empty { animation: polishCardIn .3s ease both; }

/* ============================================================
   ⑧ 交互反馈
   ============================================================ */

/* 表格行 hover：颜色渐变过去，而不是瞬变 */
table.data tbody td { transition: background-color .16s ease; }

/* 输入框聚焦：光晕从 0 扩到 3px，有个「点亮」的动作 */
@keyframes polishFocusRing {
  from { box-shadow: 0 0 0 0 var(--accent-soft); }
}
input:focus,
select:focus,
textarea:focus {
  animation: polishFocusRing .24s cubic-bezier(.22, 1, .36, 1);
}

/* 主题切换时表面色平滑过渡，不要整页闪一下。
   注意：.chip 不在列表里 —— 它自己的 .13s 更轻快，别拖慢。 */
.card, .sidebar, .topbar, .kpi, .note, .badge,
table.data th, table.data td, .role-legend, .acc,
.cal-row, .formula, .title-out, .nav-row {
  transition: background-color .22s ease, border-color .22s ease, color .22s ease;
}

/* 正在编辑哪一行？整行跟着亮一下 —— 12 列的表里这个提示很有用 */
table.data tbody tr:focus-within td { background: var(--accent-soft); }

/* 删除按钮 hover 轻微放大，比单纯变色更「可点」 */
.del { transition: background-color .12s, color .12s, transform .12s; }
.del:hover { transform: scale(1.12); }
.del:active { transform: scale(.9); }

/* 标签 / 分段控件按下时的回弹（.chip 自带 transition: all，无需重复声明） */
.chip:active { transform: scale(.95); }
.seg button { transition: background-color .13s, color .13s, box-shadow .13s, transform .1s; }
.seg button:active { transform: scale(.94); }

/* 侧边栏当前项的指示条：带一点回弹 */
.nav-item::before { transition: height .2s cubic-bezier(.22, 1, .36, 1); }

/* ============================================================
   ⑨ 图表与进度条
   ============================================================ */

/* 条形图从左侧长出来，方向即「多少」 */
@keyframes polishBarGrow {
  from { transform: scaleX(0); }
}
.bars-track i {
  transform-origin: left center;
  animation: polishBarGrow .52s cubic-bezier(.22, 1, .36, 1) both;
}

/* 流量档位切换：比原来的 .18s 更有弹性 */
.tier i { transition: opacity .22s ease, transform .22s cubic-bezier(.22, 1, .36, 1); }

/* 进度条：换成更长的回弹曲线 */
.bar i { transition: width .4s cubic-bezier(.22, 1, .36, 1); }

/* ============================================================
   ⑩ 移动端导航吸附
   ------------------------------------------------------------
   窄屏侧边栏变成横向滚动条。加上 scroll-snap，
   滑到一半松手会自动对齐到某一项；隐藏滚动条，但保留滑动。 */
@media (max-width: 1000px) {
  .nav {
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav-item { scroll-snap-align: start; }
}
