/* ==========================================================================
   格物 GRID —— 数据统计页样式 (grid-stats.css)
   --------------------------------------------------------------------------
   只被 public/assets/stats.html 与 user-stats.html 引用。

   这两个页面是独立静态页（不走 Gitea 模板管线，加不了路由），基础样式自理：
     · 主题变量靠 <link> 引 css/theme-grid-auto.css 拿到
     · 页头那条导航栏**不是**自己画的：页面在运行时从真实 Gitea 页面里
       取回服务端渲染的 <nav id="navbar"> 原样注入，并同时取回 index.<hash>.css
       的地址一起加载 —— 所以它的像素与全站任何一页逐字节同源，升级也不会漂。
       详见 CORE_JS 的 installNavbar()。
     · ⚠️ 因此本文件里**只有导航栏相关的那几条**可以提到 Gitea 的类名
       （#navbar / .item / .navbar-menu-open）；我们自己画的东西一律
       gst-* 前缀，不要假设 Gitea 的类名可用。

   加载顺序：index.css（运行时注入，插在本文件之前）→ 本文件。
   本文件在后，所以同特异性时我们赢，可以安全覆写。

   颜色一律走主题变量，只有「语言色」是写死的——那是 GitHub/Gitea 的
   语言色约定（JavaScript 黄、Python 蓝……），跟品牌色无关，也不该跟随主题。

   本文件由 tools/build_stats.py 生成，改内容请改脚本。
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

/* --------------------------------------------------------------------------
   ⚠️ 宿主页兜底：**必须写，且不能删**（2026-09-15 加）
   --------------------------------------------------------------------------
   页头改成「注入真 Gitea 导航栏」之后，Gitea 自己的 index.css 也被引了进来。
   它带着几条**元素级**全局规则，其中这一条会直接毁掉本页排版：

       body { display:flex; flex-direction:column; ... }

   body 变成 flex 容器后，我们的 .gst-wrap 就成了 flex item。而它写着
   `margin: 0 auto` —— 交叉轴上的 auto 外边距会让 flex item **放弃 stretch、
   改为按内容收缩（fit-content）**，`max-width: 1120px` 于是完全不起作用。
   实测：全站页内容列被压到 689px、个人页 404px，两栏栅格塌成一列。
   屏幕上只会觉得「窄了 / 变成一列」，不看盒模型根本归因不到 body 上。

   修法：用 `body.gst`（特异性 0,1,1）压过它的 `body`（0,0,1），**不依赖加载
   顺序**（index.css 先加载、本文件后加载，同特异性也是我们赢，但显式压过更稳）。
   `min-height: 0` 是对它 `html,body{height:100%}` 的回应：本页是长页面，
   不想要「视口高」这个默认高度。

   ⚠️ 只回正**我们真正依赖的**这几条，不要试图把 Gitea 的全局规则整片屏蔽 ——
   导航栏的排版正是靠它们。（我们自绘的组件一律 gst-* 前缀，与 Gitea 无撞车，
   已核：index.css 里 `.gst` / `.gst-wrap` / `.gst-panel` / `.gst-cards` / `.gst-two`
   出现次数均为 0。）
   -------------------------------------------------------------------------- */
body.gst {
  display: block;
  min-height: 0;
  margin: 0;
  background: var(--color-body);
  color: var(--color-text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  font-size: 14px;
  line-height: 1.65;
}

a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }


/* --------------------------------------------------------------------------
   2 · 页头（真导航栏的宿主）
   --------------------------------------------------------------------------
   页头**不在这里画**。骨架里放一个空的 <nav id="navbar">，脚本把 Gitea
   服务端渲染的那份导航栏原样注进去，所以外观与全站一致是构造保证的。

   这里只负责两件事：给它占好高度（注入前后不跳），以及在核心样式表
   到位之前先把裸 HTML 藏起来 —— 否则会闪一下「一串没排版的链接」。
   -------------------------------------------------------------------------- */
#navbar { min-height: 50px; }
#navbar.gst-nav-pending { visibility: hidden; }
/* ⚠️ 必须显式写：index.css 里有 `#navbar{display:flex}`，id 选择器压过
   UA 样式表的 `[hidden]{display:none}`，降级时藏不住。 */
#navbar[hidden] { display: none; }

/* 核心样式表取不到时的兜底导航（极少数情况：接口被墙 / 版本改版）。
   ⚠️ 链接一律用相对路径（../ 与同目录），这样实例挂子路径时也对。 */
.gst-nav-fb {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 50px;
  padding: 0 16px;
  border-bottom: 1px solid var(--color-secondary);
  background: var(--color-nav-bg, var(--color-body));
}
.gst-nav-fb[hidden] { display: none; }
.gst-nav-fb a {
  padding: 6px 12px;
  border-radius: 6px;
  color: var(--color-text);
  font-size: 13px;
}
.gst-nav-fb a:hover { text-decoration: none; background: var(--color-secondary-alpha-10, var(--color-secondary)); }
.gst-nav-fb .gst-nav-fb-home { font-weight: 600; margin-right: 4px; }

/* 当前页高亮。真导航栏是服务端渲染给「别的页面」的（我们抓的是首页），
   它不知道访客站在统计页上，所以选中态交给样式按页面类去点。
   body 上的 gst-page-* 由骨架写死，一页一个，不会串。 */
body.gst-page-stats #navbar .item[href$="/assets/stats.html"],
body.gst-page-user  #navbar .item[href$="/assets/user-stats.html"] {
  background: var(--color-active);
}


/* --------------------------------------------------------------------------
   3 · 页面骨架
   -------------------------------------------------------------------------- */
.gst-wrap { max-width: 1120px; margin: 0 auto; padding: 30px 24px 72px; }

.gst-head { margin-bottom: 22px; }
.gst-head h1 { margin: 0 0 6px; font-size: 24px; font-weight: 600; letter-spacing: .01em; }
.gst-head p { margin: 0; color: var(--color-text-light-1, var(--color-text)); opacity: .78; font-size: 13px; }

.gst-panel {
  border: 1px solid var(--color-secondary);
  border-radius: 10px;
  background: var(--color-box-body, var(--color-body));
  padding: 18px 20px;
  margin-bottom: 18px;
}

.gst-panel > h2 {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
}

/* 页脚小字。只放「数据截至 …」这类事实，不放统计口径说明，更不放
   「本页只统计公开内容」这种自我声明 —— 那是给审计看的，不是给访客看的。 */
.gst-foot {
  margin: 14px 0 0;
  font-size: 12px;
  opacity: .58;
}


/* --------------------------------------------------------------------------
   5b · 登录门 / 身份条（2026-09-15 加）
   --------------------------------------------------------------------------
   .gst-gate 是未登录时的整块替代（此时页面**不发任何数据请求**）；
   .gst-me 是个人页确认身份后显示的身份条。

   这里刻意没有「隐私声明条」：页面上不写「本页只显示你自己的数据」这类
   自我声明 —— 说不说都不影响安全性（安全性来自「页面里不存在能查到别人的
   代码路径」），而地址栏不带参数、没有换人入口这两件事，用户自己看得见。
   -------------------------------------------------------------------------- */
.gst-gate {
  border: 1px solid var(--color-secondary);
  border-radius: 10px;
  background: var(--color-box-body, var(--color-body));
  padding: 28px 22px;
  text-align: center;
}
.gst-gate b { display: block; font-size: 16px; margin-bottom: 6px; }
.gst-gate p { margin: 0 0 16px; font-size: 13px; opacity: .78; }
.gst-gate-btn {
  display: inline-block;
  padding: 7px 18px;
  border-radius: 6px;
  background: var(--color-primary);
  color: var(--color-primary-contrast, #fff);
  font-size: 13px;
}
.gst-gate-btn:hover { text-decoration: none; opacity: .9; }

.gst-me {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 13px;
  margin: 0 0 18px;
}
.gst-me img { width: 34px; height: 34px; border-radius: 50%; display: block; }
.gst-me b { font-size: 15px; }
.gst-me-tag {
  font-size: 11.5px;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--color-secondary);
  opacity: .82;
}
.gst-me-bio { flex: 1 1 100%; margin: 0; font-size: 12.5px; opacity: .72; }


/* --------------------------------------------------------------------------
   5c · 贡献习惯条（贴在同一块热力图面板的下沿）
   --------------------------------------------------------------------------
   单独一栏会显得空（3 张卡铺满一行、右边留白），所以做成热力图下方的
   三段式统计条：靠分隔线切分，不重复用卡片边框。
   -------------------------------------------------------------------------- */
.gst-habits {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--color-secondary);
}
.gst-habits .gst-card {
  border: 0;
  border-radius: 0;
  background: none;
  padding: 0 0 0 18px;
  border-left: 1px solid var(--color-secondary);
}
.gst-habits .gst-card:first-child { padding-left: 0; border-left: 0; }
.gst-habits .gst-card-v { font-size: 21px; }
.gst-habits > .gst-empty { grid-column: 1 / -1; }


/* --------------------------------------------------------------------------
   4 · 概览数字卡
   -------------------------------------------------------------------------- */
.gst-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}

.gst-card {
  border: 1px solid var(--color-secondary);
  border-radius: 10px;
  background: var(--color-box-body, var(--color-body));
  padding: 14px 16px;
}

.gst-card-k { font-size: 12px; opacity: .72; margin-bottom: 4px; }
.gst-card-v { font-size: 25px; font-weight: 600; line-height: 1.2; letter-spacing: -.01em; }
.gst-card-v small { font-size: 13px; font-weight: 500; opacity: .7; margin-left: 2px; }
.gst-card-s { font-size: 12px; opacity: .66; margin-top: 3px; }


/* --------------------------------------------------------------------------
   5 · 横向条形图（语言分布 / 仓库排行）
   -------------------------------------------------------------------------- */
.gst-hbars { display: flex; flex-direction: column; gap: 11px; }

.gst-hbar { display: block; color: inherit; }
a.gst-hbar:hover { text-decoration: none; }
a.gst-hbar:hover .gst-hbar-label { color: var(--color-primary); }

.gst-hbar-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 4px;
  font-size: 13px;
}

.gst-hbar-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gst-hbar-value { margin-left: auto; font-variant-numeric: tabular-nums; opacity: .78; font-size: 12px; }

.gst-hbar-track {
  height: 7px;
  border-radius: 4px;
  background: var(--color-secondary-alpha-40, var(--color-secondary));
  overflow: hidden;
}

.gst-hbar-fill { height: 100%; border-radius: 4px; background: var(--color-primary); }


/* --------------------------------------------------------------------------
   6 · 纵向柱状图（时间线）
   -------------------------------------------------------------------------- */
.gst-cols {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 160px;
  padding-top: 4px;
}

.gst-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }

.gst-col-bar {
  width: 100%;
  min-height: 2px;
  border-radius: 3px 3px 0 0;
  background: var(--color-primary);
  transition: opacity .12s ease;
}
.gst-col:hover .gst-col-bar { opacity: .72; }

.gst-col-v {
  font-size: 10px;
  text-align: center;
  opacity: .7;
  font-variant-numeric: tabular-nums;
  height: 14px;
}

.gst-col-l {
  font-size: 10px;
  text-align: center;
  opacity: .62;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* --------------------------------------------------------------------------
   7 · 环形图（语言占比）
   -------------------------------------------------------------------------- */
.gst-donut { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; }
.gst-donut-svg { width: 168px; height: 168px; flex: 0 0 auto; }
.gst-donut-total { font-size: 22px; font-weight: 600; fill: var(--color-text); }
.gst-donut-cap { font-size: 10px; fill: var(--color-text); opacity: .66; }

.gst-legend { flex: 1 1 220px; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.gst-legend-item { display: flex; align-items: center; gap: 8px; font-size: 13px; min-width: 0; }
.gst-legend-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.gst-legend-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gst-legend-value { margin-left: auto; flex: 0 0 auto; font-size: 12px; opacity: .76; font-variant-numeric: tabular-nums; }


/* --------------------------------------------------------------------------
   8 · 贡献热力图
   --------------------------------------------------------------------------
   和站点自带的那个热力图（user/heatmap）保持同一套观感：圆角小块、
   空格子用极淡的品牌色。变量兜底的理由见 grid-custom.css 第 7 节，
   这里再写一遍是因为统计页是独立静态页，不加载 grid-custom.css。
   -------------------------------------------------------------------------- */
.gst-heat {
  --color-secondary-alpha-60: #d0d7de99;
  --color-secondary-alpha-60: color-mix(in srgb, var(--color-primary) 14%, transparent);
  overflow-x: auto;
  padding-bottom: 2px;
}

.gst-heat-svg { width: 100%; height: auto; display: block; }
.gst-heat-day { rx: 2.5px; ry: 2.5px; }
.gst-heat text { fill: var(--color-text); opacity: .66; font-size: 9px; }
.gst-heat-legend { display: flex; align-items: center; justify-content: flex-end; gap: 6px; font-size: 11px; opacity: .76; margin-top: 8px; }


/* --------------------------------------------------------------------------
   9 · 状态与杂项
   -------------------------------------------------------------------------- */
.gst-empty, .gst-err {
  padding: 22px 16px;
  text-align: center;
  font-size: 13px;
  border-radius: 8px;
  opacity: .76;
}

.gst-err {
  border: 1px solid var(--color-secondary);
  background: var(--color-secondary-alpha-10, transparent);
  opacity: 1;
}

.gst-err b { color: var(--color-red, #d1242f); }

.gst-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.gst-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid var(--color-secondary);
  border-radius: 999px;
  font-size: 12px;
}
.gst-tag i { font-style: normal; font-variant-numeric: tabular-nums; opacity: .76; }

.gst-skeleton { color: transparent; }
.gst-skeleton .gst-card-v, .gst-skeleton .gst-hbar-track {
  background: var(--color-secondary-alpha-20, var(--color-secondary));
  border-radius: 5px;
}

/* 双栏。auto-fit + minmax(300px,1fr)：宽屏两栏、窄屏自动落成一栏，
   不用写断点；空轨道会被折叠，所以只有 2 个子面板时不会各占 1/3。 */
.gst-two { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 18px; }
.gst-two > .gst-panel { margin-bottom: 0; }


@media (max-width: 720px) {
  .gst-wrap { padding: 20px 14px 56px; }
  .gst-head h1 { font-size: 20px; }
  .gst-cards { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .gst-card-v { font-size: 21px; }
  .gst-cols { height: 128px; gap: 3px; }
  .gst-col-l { display: none; }
  .gst-donut-svg { width: 140px; height: 140px; }
  /* 三段式统计条在窄屏落成一列，横分隔线换成竖的会挤，索性只留间距 */
  .gst-habits { grid-template-columns: 1fr; gap: 12px; }
  .gst-habits .gst-card { padding-left: 0; border-left: 0; }
  .gst-habits .gst-card-v { font-size: 19px; }
}
