/* ===== 配色 token（单一来源，详见 docs/配色规范.md；官网检测基准色 + 项目扩展）===== */
:root {
  /* 品牌主色 */
  --c-primary: #0271a6;        /* 官网基准蓝：按钮/链接/品牌/激活 */
  --c-primary-dark: #015d89;   /* hover/按下 */
  --c-primary-deep: #0a5a99;   /* 品牌深蓝：登录/品牌大色块背景（取自官网，approx） */
  --c-primary-tint: #e7f1f7;   /* 浅蓝底：菜单 hover、行选中 */
  --c-primary-ring: #b3d7ec;   /* 聚焦光圈 */
  --c-entity-hk: #12a4a0;      /* 香港实体色(青)：与北京=主蓝区分，用于实体分账 */

  /* 中性色 */
  --c-bg: #f8f6f7;             /* 官网基准浅灰：页面背景 */
  --c-surface: #ffffff;        /* 官网基准白：卡片/文本框/侧栏/顶栏 */
  --c-border: #e5e7eb;
  --c-border-strong: #d1d5db;

  /* 文本色 */
  --c-text: #1f2937;
  --c-text-secondary: #4b5563;
  --c-text-muted: #9ca3af;
  --c-text-inverse: #ffffff;

  /* 功能/状态色 */
  --c-success: #2e9e5b;  --c-success-bg: #eaf7ef;
  --c-warning: #d9870b;  --c-warning-bg: #fdf4e3;
  --c-danger:  #c0392b;  --c-danger-bg:  #fef2f2;
  --c-info:    var(--c-primary);

  /* 项目扩展：圆角/阴影 */
  --radius-sm: 6px;
  --radius: 10px;
  --radius-pill: 999px;
  --shadow-card: 0 2px 10px rgba(2, 113, 166, .06);
  --shadow-pop:  0 8px 30px rgba(2, 113, 166, .08);

  /* 控件尺寸单源：筛选条 select/button、搜索框等小控件的内边距/字号/圆角只认这几个 token，
     改一处全站同步(定义方在 components.css，页面级 css 引用勿写字面值)。 */
  --control-pad-y: .34rem;
  --control-pad-x: .7rem;
  --control-font: .8rem;
  --control-radius: var(--radius-pill);
  --control-w-search: 220px;

  /* 宽表横滚阈值单源(0907)：共享横滚容器 .t-scroll(components.css)给内表压的 min-width。
     窄于此宽度即出横向滚动条，不再挤压数字列/把中文表头折成残句。取值沿用原库存页
     .inv-table 的 850px(该页九列最挤，四页/清单统一按它)；半宽并排榜(.tops-2col)另有
     例外，见 reports.css。 */
  --table-min-w: 850px;

  /* 吸顶层与画布尺寸单源(0907 全站筛选条吸顶)：顶栏按 --topbar-h 定高，筛选条吸在它正下方
     (components.css .filters，top=--topbar-h)；两者叠起来遮住视口顶部的高度＝--sticky-h，
     锚点跳转的 scroll-margin-top 一律引用它(reports.css #report)，勿再写死像素。
     --filters-h 是筛选条**单行**的钉高(min-height)：窄屏换行会更高，锚点补偿按单行算——
     略保守，跳转后标题只会更靠下、不会被筛选条盖住。尾部 12px＝卡片与筛选条之间留的一口气
     (原 #report 62px 补偿里的那一截)。--content-pad 是通用画布(.content)的左右内边距，
     筛选条靠等量的负外边距铺满同一条宽度，滚过去的卡片与其投影不会从筛选条两侧漏出来。 */
  --topbar-h: 50px;
  --filters-h: 52px;
  --filters-pad-y: .5rem;
  --sticky-h: calc(var(--topbar-h) + var(--filters-h) + 12px);
  --content-pad: 1.5rem;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; color: var(--c-text); background: var(--c-bg);
  font-family: "Inter", -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
  -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.5;
}
a { text-decoration: none; color: inherit; }
button { font-family: inherit; }

/* 登录页样式已独立到 app/static/css/login.css（仅登录页加载）。 */

/* 通用工具类 */
.ico { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
/* 弹性占位:把后续元素顶到行尾(顶栏、卡片标题栏、侧栏底部行共用一条) */
.spacer { flex: 1; }

/* ========================= 主框架：外壳 ========================= */
.layout { display: flex; min-height: 100vh; }
.sidebar {
  width: 232px; flex: none; background: var(--c-surface); border-right: 1px solid var(--c-border);
  display: flex; flex-direction: column; overflow: hidden; transition: width .2s ease;
  /* 钉在视口内:右侧报表再长,侧栏也只占一屏,底部用户区(头像/折叠钮)始终可见;菜单超高时栏内自滚 */
  position: sticky; top: 0; height: 100vh; height: 100dvh;
}
.sidebar-scroll { flex: 1; overflow-y: auto; padding: 1rem .7rem .4rem; }

.brand { display: flex; align-items: center; gap: 10px; padding: .25rem .5rem 1rem; margin-bottom: .2rem; border-bottom: 1px solid var(--c-border); }
.brand-mark { display: grid; place-items: center; width: 34px; height: 34px; flex: none; border-radius: var(--radius); color: var(--c-text-inverse); background: var(--c-primary); box-shadow: var(--shadow-card); }
.brand-mark svg { width: 18px; height: 18px; stroke-width: 1.8; }
.brand-name { font-size: 14px; font-weight: 700; line-height: 1.25; color: var(--c-primary); white-space: nowrap; }
.brand-name span { display: block; font-size: 11px; font-weight: 500; color: var(--c-text-secondary); }

.menu-group { margin: .9rem 0; }
.menu-group-title { font-size: .7rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--c-text-muted); padding: .3rem .5rem .35rem; }
.menu-item { position: relative; display: flex; align-items: center; gap: 10px; padding: .46rem .55rem; margin: 1px 0; border-radius: var(--radius-sm); font-size: .9rem; color: var(--c-text-secondary); transition: background-color .15s ease, color .15s ease; }
.menu-item .mi-ico { width: 17px; height: 17px; flex: none; color: var(--c-text-muted); transition: color .15s ease; }
.menu-item .mi-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-item:focus-visible { outline: 3px solid var(--c-primary-ring); outline-offset: -2px; }
/* 已建功能:标蓝、可点 */
.menu-item.is-done { color: var(--c-primary); }
.menu-item.is-done .mi-ico { color: var(--c-primary); }
.menu-item.is-done:hover { background: var(--c-primary-tint); }
/* 当前页:底色 + 加粗 + 左侧蓝条(最重;无圆点) */
.menu-item.is-active { background: var(--c-primary-tint); color: var(--c-primary); font-weight: 600; box-shadow: inset 2px 0 0 var(--c-primary); }
.menu-item.is-active .mi-ico { color: var(--c-primary); }
/* 未建功能:如实标灰、不可点(无标签、无圆点) */
.menu-item.is-todo { color: var(--c-text-muted); cursor: default; }
.menu-item.is-todo .mi-ico { color: var(--c-text-muted); }

.sidebar-foot { border-top: 1px solid var(--c-border); padding: .7rem .7rem .8rem; }
.foot-row { display: flex; align-items: center; gap: 8px; }
.foot-user { display: flex; align-items: center; gap: 8px; min-width: 0; }
.foot-user .name { font-size: .8rem; font-weight: 600; color: var(--c-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.collapse-btn { display: grid; place-items: center; width: 30px; height: 30px; flex: none; border: 1px solid var(--c-border); border-radius: var(--radius-sm); color: var(--c-text-secondary); background: var(--c-surface); cursor: pointer; transition: color .15s ease, border-color .15s ease, background-color .15s ease; }
.collapse-btn:hover { color: var(--c-primary); border-color: var(--c-primary-ring); background: var(--c-primary-tint); }
.collapse-btn:focus-visible { outline: 3px solid var(--c-primary-ring); outline-offset: 2px; }
.collapse-btn svg { width: 16px; height: 16px; }
.avatar { display: grid; place-items: center; width: 30px; height: 30px; flex: none; border-radius: 50%; font-size: .74rem; font-weight: 700; color: var(--c-text-inverse); background: var(--c-primary-deep); }

/* 折叠态 */
.layout.is-collapsed .sidebar { width: 64px; }
.layout.is-collapsed .brand-name,
.layout.is-collapsed .menu-group-title,
.layout.is-collapsed .mi-label,
.layout.is-collapsed .foot-user .name { display: none; }
.layout.is-collapsed .menu-group-title { text-align: center; padding: .3rem 0; }
.layout.is-collapsed .menu-item { justify-content: center; padding: .46rem 0; }
.layout.is-collapsed .brand { justify-content: center; }
.layout.is-collapsed .foot-row { flex-direction: column-reverse; gap: 8px; }

/* ========================= 图层层级(z-index 单源) =========================
   自上而下：顶栏 > 筛选条 > 内容。新增浮层先在此登记再写值，勿散落到页面级 css。
     60   .modal-mask  上传中心确认弹窗(uploads.css，position:fixed，盖全站)
     20   .topbar      顶栏(sticky top:0)，恒在最上；筛选条从它下面走过
     15   .filters     筛选条(components.css，sticky top:--topbar-h)，盖住滚过去的正文
     auto 内容层        .report / .hero / .donut / .nest-table 等一律不设 z-index
   注意：甜甜圈 .donut 是 position:relative(z-index:auto)、在 DOM 里排在筛选条之后，
   筛选条若不显式给层级就会被它盖过去——这正是 .filters 必须带 z-index 的原因。
   原生 <select> 下拉与 title 气泡由浏览器画在顶层，不受本表约束。
   侧栏 .sidebar 也是 sticky，但与主区左右分列、永不重叠，故不参与本表(保持 z-index:auto)。 */

/* 主区 + 顶栏 */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
/* min-height 与 --topbar-h 是同一件事:筛选条吸顶靠它对齐(top:var(--topbar-h))，改高度只改 token */
.topbar { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: .9rem; min-height: var(--topbar-h); background: var(--c-surface); border-bottom: 1px solid var(--c-border); padding: .6rem 1.4rem; }
.topbar form { margin: 0; }
.crumbs { display: flex; align-items: center; gap: 8px; font-size: .95rem; color: var(--c-text); }
.crumbs .cb-ico { display: grid; place-items: center; width: 28px; height: 28px; flex: none; border-radius: var(--radius-sm); color: var(--c-primary); background: var(--c-primary-tint); }
.crumbs .cb-ico svg { width: 16px; height: 16px; }
.crumbs .cur { color: var(--c-text); font-weight: 600; }
.top-divider { width: 1px; height: 24px; background: var(--c-border); }
.top-user { display: flex; align-items: center; gap: 9px; }
.top-user .uname { font-size: .86rem; color: var(--c-text); font-weight: 500; }
.top-link { color: var(--c-primary); font-size: .85rem; font-weight: 500; }
.top-link:hover { color: var(--c-primary-dark); text-decoration: underline; text-underline-offset: 3px; }
.top-link:focus-visible { outline: 3px solid var(--c-primary-ring); outline-offset: 2px; border-radius: var(--radius-sm); }
.logout { background: none; border: 0; cursor: pointer; padding: 0; }
.content { padding: var(--content-pad); max-width: 1680px; } /* 通用画布(全站报表共用):0813 验收放宽,嵌套/多列表行内更从容 */

/* ========================= 通用组件 ========================= */
.section-title { display: flex; align-items: center; gap: 14px; margin: 1.9rem 0 .9rem; }
.section-title h2 { margin: 0; font-size: 1rem; font-weight: 650; color: var(--c-text); white-space: nowrap; }
.section-title .line { flex: 1; height: 1px; background: var(--c-border); }

.card { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius); padding: 1.25rem 1.4rem; box-shadow: var(--shadow-card); }
.card h1 { font-size: 1.2rem; margin: 0 0 .6rem; }
.card p { margin: .3rem 0; color: var(--c-text-secondary); }
.card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 1rem; }
.card-head .ch-ico { display: grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: var(--radius-sm); color: var(--c-primary); background: var(--c-primary-tint); }
.card-head .ch-ico svg { width: 18px; height: 18px; }
.card-head h3 { margin: 0; font-size: .96rem; font-weight: 650; }
.card-head .ch-sub { font-size: .76rem; color: var(--c-text-secondary); margin-top: 1px; }
.muted { color: var(--c-text-muted); font-size: .88rem; }

/* ========================= 响应式 ========================= */
@media (max-width: 1080px) {
  .content { max-width: none; }
}
@media (max-width: 760px) {
  .sidebar { width: 64px; }
  .brand-name, .menu-group-title, .mi-label, .foot-user .name { display: none; }
  .menu-group-title { text-align: center; padding: .3rem 0; }
  .menu-item { justify-content: center; padding: .46rem 0; }
  .brand { justify-content: center; }
  .foot-row { flex-direction: column-reverse; gap: 8px; }
  .top-user .uname { display: none; }
  .content { --content-pad: 1rem; }  /* 改 token 而非 padding:筛选条的负外边距同步收窄 */
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
