/* 管理后台样式。零依赖，不引入任何前端框架。 */

:root {
  --primary: #e93b3d;
  --primary-dark: #c92a2f;
  --primary-soft: #fdecec;
  --bg: #f5f6f8;
  --card: #ffffff;
  --border: #e5e7eb;
  --border-soft: #eef0f3;
  --text: #1f2329;
  --text-mid: #4b5563;
  --muted: #8a8f99;
  --ok: #2fb344;
  --warn: #f0a020;
  --danger: #e03131;
  /* 左侧导航宽度。只有这一处定义，窄屏时在文件底部覆盖 */
  --sidebar-w: 200px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  font-size: 14px;
  line-height: 1.6;
}

a { color: var(--primary); }

/* ---------------- 登录页 ---------------- */

.login { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.login__box { width: 100%; max-width: 360px; background: var(--card); border-radius: 12px; padding: 36px 32px; box-shadow: 0 4px 24px rgba(0,0,0,.06); }
.login__logo { width: 48px; height: 48px; border-radius: 12px; background: var(--primary); color: #fff; font-size: 24px; display: flex; align-items: center; justify-content: center; margin-bottom: 20px; }
.login h1 { font-size: 20px; margin: 0 0 6px; }
.login__hint { color: var(--muted); font-size: 13px; margin: 0 0 24px; }

/* ---------------- 左侧导航 ---------------- */

/* 固定宽度放在变量里：窄屏时只改这一处，侧栏和右侧内容的左边距一起跟着变 */
.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--sidebar-w);
  background: var(--card);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  z-index: 50;
}

.sidebar__brand {
  font-weight: 600;
  font-size: 15px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* flex:1 + overflow-y —— 菜单项再多年也不会把底部的退出登录挤出屏幕 */
.sidebar__nav { flex: 1; overflow-y: auto; padding: 8px 0; }

.sidebar__nav a {
  display: block;
  padding: 11px 20px;
  font-size: 14px;
  color: var(--text-mid);
  text-decoration: none;
  border-left: 3px solid transparent;
  white-space: nowrap;
}

.sidebar__nav a:hover { background: #fafbfc; color: var(--text); }

/* 选中项：左侧红条 + 浅红底，扫一眼就知道在哪个页面 */
.sidebar__nav a.on {
  color: var(--primary);
  background: var(--primary-soft);
  border-left-color: var(--primary);
  font-weight: 600;
}

.sidebar__foot {
  padding: 14px 20px;
  border-top: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
  color: var(--muted);
}

.sidebar__user { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------- 布局 ---------------- */

/* 给固定定位的侧栏让出位置 */
.main { margin-left: var(--sidebar-w); padding: 20px; }
.card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; margin-bottom: 16px; }
.card__head { padding: 14px 16px; border-bottom: 1px solid var(--border-soft); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.card__title { font-weight: 600; }
.card__body { padding: 16px; }
.toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ---------------- 按钮 ---------------- */

.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 1px solid var(--border); background: var(--card); color: var(--text); border-radius: 6px; padding: 7px 14px; font-size: 14px; cursor: pointer; font-family: inherit; white-space: nowrap; text-decoration: none; }
.btn:hover { background: #fafbfc; border-color: #d5d9e0; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn--primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn--primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }
.btn--danger { color: var(--danger); border-color: #f3c9c9; }
.btn--danger:hover { background: #fff5f5; }
.btn--sm { padding: 4px 10px; font-size: 13px; }
.btn--link { border: none; background: none; color: var(--primary); padding: 2px 4px; cursor: pointer; font-family: inherit; font-size: 13px; text-decoration: none; }
.btn--link:hover { text-decoration: underline; }

/* ---------------- 表单 ---------------- */

.field { margin-bottom: 16px; }
.field > label { display: block; font-size: 13px; color: var(--text-mid); margin-bottom: 6px; }
.field__req::after { content: ' *'; color: var(--danger); }
.field__hint { font-size: 12px; color: var(--muted); margin-top: 5px; line-height: 1.6; }

/* ★ 这个类型列表要跟着用到的 type 走。
   商品表单的「视频链接」用的是 type="url"，曾经因为这里没列 url，
   它一条样式都匹配不上，退回浏览器默认样子——又窄又矮、没边框，
   在一堆整齐的表单里像个没做完的东西。
   新加 input 时如果用了别的 type（email / search / tel…），记得也加进来。 */
input[type=text], input[type=password], input[type=number], input[type=date],
input[type=url], input[type=email], input[type=search], input[type=tel],
select, textarea {
  width: 100%; border: 1px solid var(--border); border-radius: 6px; padding: 7px 10px;
  font-size: 14px; font-family: inherit; color: var(--text); background: var(--card);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
textarea { resize: vertical; min-height: 90px; line-height: 1.6; }

/* 设置页两个表单的输入框不要撑满整张卡片。
 * 内容都很短（店铺名最多 20 字、密码十几位），铺满一行会让标签和输入值
 * 离得老远，扫一眼对不上。用 max-width 而不是 width，窄屏仍会退回 100%。 */
form.form--narrow input { max-width: 320px; }

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 16px; }
@media (max-width: 720px) { .grid2, .grid3 { grid-template-columns: 1fr; } }

/* ---------------- 表格 ---------------- */

.table-wrap { overflow-x: auto; }
table.list { width: 100%; border-collapse: collapse; font-size: 14px; }
table.list th { text-align: left; padding: 10px 12px; font-weight: 600; font-size: 13px; color: var(--text-mid); background: #fafbfc; border-bottom: 1px solid var(--border); white-space: nowrap; }

/* ★ 表头和数据行**都**不折行。
 *
 * 原来只有 th 设了 nowrap、td 没设，于是表头一行排开、数据却被挤成两行：
 * 「2026-09-20 15:30」断成两截、「¥168.00」上下分离，行高还参差不齐。
 * 表格是拿来横向扫的，折行会让人看串行。
 *
 * 宽度不够时由外面那层 .table-wrap 横向滚动解决（它本来就设了 overflow-x:auto），
 * 而不是把内容压成两行。
 *
 * 真正会很长、必须收着的列（商品标题最多 60 字）由 .cell-title 限宽截断，
 * 见下面的定义 —— 不限的话它一个人就能把整张表撑到屏幕外。 */
table.list td { padding: 10px 12px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; white-space: nowrap; }
table.list tr:last-child td { border-bottom: none; }
table.list tr:hover td { background: #fcfcfd; }

/* ★ 数字列右对齐。
 *
 * 必须写成 `table.list th.num` 这种带表格前缀的形式，不能只写 `.num`。
 *
 * 原因是 CSS 优先级：
 *     table.list th   → (0,1,2)  1 个类 + 2 个标签
 *     .num            → (0,1,0)  只有 1 个类
 *   上面那条更高，所以 `<th class="num">` 里的 text-align:right **会被压掉**，
 *   表头被强制左对齐；而数据行是 `<td class="num">`，td 没设过 text-align，
 *   右对齐正常生效。
 *
 * 结果：数字列的表头靠左、数字靠右 —— 整列看起来就是"表头和内容错位"。
 * 全站的后台表格都中了这一条。
 *
 * 下面那条通用的 .num 保留给表格以外的用法（目前都在表格里，留着防以后踩）。
 */
.num { text-align: right; font-variant-numeric: tabular-nums; }

table.list th.num,
table.list td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* 订单列表：把「金额」和「状态」两列拉开一点。
 *
 * 金额右对齐、状态左对齐，两列挨着时中间只有各自 12px 的内边距（合计 24px），
 * 数字和状态标签几乎贴住，横向扫这一行时容易把两者看成一体的。
 *
 * ★ 只加**状态列左侧**的内边距，不动金额列。
 *
 *   如果改金额列的右内边距，右对齐的数字会往左退，反而压缩它和「收货人」的间距，
 *   等于把问题挪到隔壁列去了。只把状态列往右推，两边的距离只增不减。
 *
 * ★ 表头和数据行用的是**同一个类**（col-status）。
 *   只给一边加的话，这一列的列宽只在表头或只在数据行变大，两边就错位了。
 *   改动这一列不影响其它列 —— 列宽由同一张表的表头和数据共同决定。 */
table.list .col-status { padding-left: 40px; }

/* ★ 列宽按内容分配，不要平均摊开。
 *
 *   表格是 width:100% + 自动布局，浏览器会把多余宽度**平均分给每一列**，
 *   于是「折扣」这种只放三个字的列也被撑到一百多像素 —— 又空又难看，
 *   真正需要宽度的「商品」列反而不够用。
 *
 *   下面让**第一列**吸收全部剩余宽度（width:100% 在表格里就是「把这列撑开」），
 *   其余各列收缩到刚好放下内容。数据行都是 nowrap，所以「刚好放下」＝不折行。
 *
 *   少数表格的第一列不是主文本列（比如订单表第一列是等宽字体的订单号），
 *   在那里用 .table-grow-2 指明「该撑开的是第二列」。 */
table.list th:first-child,
table.list td:first-child { width: 100%; }

table.list th.table-grow-2:first-child,
table.list td.table-grow-2:first-child { width: auto; }

table.list th.table-grow-2:nth-child(2),
table.list td.table-grow-2:nth-child(2) { width: 100%; }

/* ★ 首列「按内容宽显示，谁都不撑」。
 *
 *   给首列是短字段、且其余列也都是定长内容的表用（会员的用户名、会员等级的
 *   等级名）——这类表没有哪一列真正需要额外宽度，撑开任何一列都只是空白。
 *   和上面的 table-grow-2 是一对：那个是「换一列来撑」，这个是「谁都不撑」。
 *
 *   width:1% 是自动布局表格里「收缩到内容宽度」的标准写法。表格各列都是
 *   nowrap，所以列宽＝文字自然宽度，过长的再由 .cell-title 的 max-width 兜底。
 *
 *   ⚠️ th 和 td 必须**同时**挂。首列默认吸收余量是 th:first-child 和
 *      td:first-child **两条独立**规则，只挂 th 的话，td 那条照样把列撑开，
 *      现象是「表头窄了、数据行还是宽的」。 */
table.list th.col-fit,
table.list td.col-fit { width: 1%; }

/* ★ 首列固定宽度（会员等级的等级名 / 分类的名称 / 商品的商品）。
 *
 *   这几列同样是短字段，不该吸收表格余量；但也不适合用 col-fit 收得刚好
 *   贴住文字——留一点余量，长短不一的名字之间视觉更稳。数值按各列典型内容估的，
 *   内容真的更长时浏览器仍会自动放宽（width 在自动布局里是建议值，不是硬限制）。
 *
 *   ⚠️ 同 col-fit：th 和 td 必须**同时**挂，只挂 th 的话 td:first-child 的
 *      width:100% 照样把列撑开。 */
/* ★ 必须大于内容的自然宽度（≈168px），否则这条 width 是无效的。
 *
 *   默认等级那一行是「4 字名字 + 新会员默认标签」，而 table.list td 是 nowrap，
 *   折不了行，该行的最小宽度就被锁死在 ≈168px（名字≈58 + 标签≈82 + 内边距 24）。
 *   设成 130px / 143px 时都低于这个下限，被内容顶回去，看起来「改了没反应」。
 *   185px = 168 × 1.1，222px = 185 × 1.2。以后要调小也得注意别低于 168。 */
table.list th.col-level-name,
table.list td.col-level-name { width: 222px; }

table.list th.col-cat-name,
table.list td.col-cat-name { width: 180px; }

/* 336 × 1.2 —— 商品列要更宽一些，缩略图右边留出更多给标题和副标题 */
table.list th.col-goods,
table.list td.col-goods { width: 403px; }

/* ★ 窄表：列少、内容短的表格不强行撑满容器。
 *
 *   撑满的后果是短列被拉到几百像素 —— 「日期」「订单数」「营业额」
 *   每列都是十几个字以内的内容，铺满一行后数字和表头离得老远，
 *   横向扫的时候眼睛要跨过大片空白才能对上。
 *
 *   这类表改成按内容收窄（width:auto），右边留白反而是清楚的。
 *   用在：统计页的每日趋势表这类只有几列数字的表上。
 *
 *   ★ 为什么还要单独写 :first-child —— 上面那条全局规则让第一列吸收剩余宽度，
 *     对宽表是对的，对窄表就成了「日期列被撑到几百像素」。
 *     这两条优先级相同，靠写在后面覆盖；显式写 :first-child 是为了更高优先级，
 *     避免以后调整顺序时又变回去。 */
table.list.table--compact { width: auto; }

table.list.table--compact th:first-child,
table.list.table--compact td:first-child { width: auto; }

/* 日期列贴合内容，不吸收表格多出来的宽度。
 *
 * width:1% 是自动布局表格里「收缩到内容宽度」的标准写法；因为 table.list 的
 * th/td 都是 white-space:nowrap，列宽就等于 "2026-09-21" 的自然宽度（约 96px）。
 *
 * 背景：给统计页设了 70% 宽之后，表格比内容宽，多出来的空间被各列分掉，
 * 日期列首当其冲被撑得很宽。这条把它按回内容宽度，余量让给右边的数字列。
 *
 * ⚠️ 和上面那条 :first-child 优先级打平（都是 0,3,2），同样靠源码顺序取胜，
 *    必须留在这条之后，否则会被它的 width:auto 顶掉。
 *    也不要图省事去改 .mono —— 那个类订单页和会员页也在用。 */
table.list.table--compact th.col-date,
table.list.table--compact td.col-date { width: 1%; }

/* 统计页的三张表（每日趋势 / TOP 10 / 订单状态分布）统一按 70% 宽显示，右侧留白。
 *
 * ⚠️ 必须写在 .table--compact 之后。两者的选择器优先级完全相同（都是 0,0,2,1），
 *    分不出胜负，只靠源码顺序决定谁生效——写到前面会被它的 width:auto 顶掉，
 *    现象是「改了没反应」，而且不带报错，很难查。 */
table.list.table--w70 { width: 70%; }
.thumb { width: 44px; height: 44px; border-radius: 6px; object-fit: cover; background: #f2f4f7; display: block; }
/* 商品标题这类「可能很长」的文本：限宽 + 单行截断。
   商品名最长允许 60 个字，配合上面的 td 不折行，不限宽的话
   这一列能一路撑到屏幕外，整张表跟着横向滚动，别的列全看不见了。
   ⚠️ 限宽只对 <div class="cell-title"> 生效；
      直接写成 <td class="cell-title"> 时，自动布局的表格会忽略 max-width。 */
.cell-title { font-weight: 500; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cell-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.mono { font-family: Menlo, Consolas, monospace; font-size: 12px; }

/* 微信 openid 有 28 个字符，表格里放不下会造成整行被撑宽。
   截断显示，完整值放在 title 上（悬停可见）——
   顾客报「我的会员没了」时要靠这个值定位到具体是哪个人 */
.cell-openid { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------- 标签 ---------------- */

.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 12px; background: #f2f4f7; color: var(--text-mid); white-space: nowrap; }
.tag--ok { background: #eefaf0; color: #1f7a30; }
.tag--warn { background: #fff8e6; color: #8a6116; }
.tag--danger { background: #fdecec; color: var(--primary-dark); }
.tag--info { background: #eef4ff; color: #2c5aa0; }
.tag--muted { background: #f2f4f7; color: var(--muted); }

/* ---------------- 概览卡片 ---------------- */

/* ★ 下限 176px 是为了「统计区间（北京时间）」这个标签不折行，别再调回 160。
 *
 *   那个标签是 10 个全角字符 × 13px = 130px，而 .stat 左右内边距共 32px，
 *   所以格子至少要 162px 才放得下。原来的 160px 下限正好卡在临界点上：
 *   容器宽接近轨道间距整数倍时格子恰好等于 160px，内容区只剩 128px，
 *   差 2px 就折成两行——所以它表现为「有时折有时不折」，视口稍变就复现。
 *   176px 留 14px 余量，比 160 只多 16px，仪表盘那 6 个短标签不受影响。 */
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 14px; margin-bottom: 20px; }
.stat { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 16px; text-decoration: none; color: inherit; display: block; transition: border-color .12s, box-shadow .12s; }
.stat:hover { border-color: #d5d9e0; box-shadow: 0 2px 8px rgba(0,0,0,.04); }
.stat__num { font-size: 26px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; }
.stat__num--primary { color: var(--primary); }
/* nowrap 是第二道保险：缩到 176px 下限后标签本来就放得下了，加这个是为了
   以后换字体、改文案把标签撑宽时**只溢出、不折行**（折行会让四张卡片高度不齐）。
   当前最长的是「统计区间（北京时间）」130px，格子内容区 ≥144px，不会溢出。 */
.stat__label { font-size: 13px; color: var(--muted); margin-top: 2px; white-space: nowrap; }

/* ---------------- 提示条 ---------------- */

.banner { padding: 10px 14px; border-radius: 6px; font-size: 13px; margin-bottom: 16px; line-height: 1.7; }
.banner--ok { background: #eefaf0; color: #1f7a30; }
.banner--warn { background: #fff8e6; color: #8a6116; }
.banner--err { background: #fdecec; color: var(--primary-dark); }

/* ---------------- 弹窗 ---------------- */

.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,.45); display: none; align-items: flex-start; justify-content: center; padding: 40px 16px; z-index: 100; overflow-y: auto; }
.modal-mask.on { display: flex; }
.modal { background: var(--card); border-radius: 10px; width: 100%; max-width: 640px; box-shadow: 0 12px 40px rgba(0,0,0,.18); }
.modal--wide { max-width: 920px; }
.modal__head { padding: 16px 20px; border-bottom: 1px solid var(--border-soft); display: flex; align-items: center; justify-content: space-between; }
.modal__title { font-weight: 600; font-size: 16px; }
.modal__close { border: none; background: none; font-size: 22px; line-height: 1; color: var(--muted); cursor: pointer; padding: 4px 8px; font-family: inherit; }
.modal__body { padding: 20px; }
/* flex-wrap：订单详情的底部按钮最多有五个（关闭 / 无需发货 / 发货 / 标记退款 / 删除），
   窄屏下不换行会撑破弹窗。换行只是难看一点，撑破就没法点了 */
.modal__foot { padding: 14px 20px; border-top: 1px solid var(--border-soft); display: flex; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }

/* ---------------- 其它 ---------------- */

.empty { padding: 48px 16px; text-align: center; color: var(--muted); }
.page-loading { padding: 40px; text-align: center; color: var(--muted); }

.pager { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 14px; font-size: 13px; color: var(--text-mid); }
.pager nav { display: flex; gap: 4px; }
.pager a, .pager span { padding: 4px 10px; border: 1px solid var(--border); border-radius: 4px; text-decoration: none; color: var(--text-mid); }
.pager .on { background: var(--primary); border-color: var(--primary); color: #fff; }

/* 商品列表分页：只给真正的页码和翻页按钮加边框，避免 Laravel 默认分页的
   多层 span 被通用规则重复描边。 */
.pager--split {
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
  padding: 14px 16px;
}
.pager .pager__summary {
  padding: 0;
  border: 0;
  color: var(--muted);
  white-space: nowrap;
}
.pager .pager__summary span { padding: 0; border: 0; color: inherit; }
.pager .pager__links {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 6px;
  margin-left: auto;
}
.pager .pager__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 32px;
  padding: 0 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
  color: var(--text-mid);
  line-height: 1;
  text-decoration: none;
  transition: border-color .15s, color .15s, background .15s;
}
.pager .pager__link:not(.is-current):not(.is-disabled):hover {
  border-color: var(--primary);
  background: var(--primary-soft);
  color: var(--primary);
}
.pager .pager__link.is-current {
  border-color: var(--primary);
  background: var(--primary);
  color: #fff;
  font-weight: 600;
}
.pager .pager__link.is-disabled {
  border-color: var(--border-soft);
  background: #f8f9fb;
  color: #b4bac4;
  cursor: not-allowed;
}
.pager .pager__ellipsis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 32px;
  padding: 0;
  border: 0;
  color: var(--muted);
}

@media (max-width: 640px) {
  .pager--split { justify-content: center; }
  .pager__summary { width: 100%; text-align: center; }
  .pager .pager__links { justify-content: center; margin-left: 0; }
}

/* ---------------- 规格编辑器 ---------------- */

.spec-dim { border: 1px solid var(--border); border-radius: 6px; padding: 12px; margin-bottom: 10px; }
.spec-dim__head { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.spec-dim__head input { max-width: 200px; }
.spec-vals { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.spec-val { display: inline-flex; align-items: center; gap: 6px; background: #f2f4f7; border-radius: 6px; padding: 4px 6px 4px 10px; font-size: 13px; }
.spec-val button { border: none; background: none; cursor: pointer; color: var(--muted); font-size: 15px; line-height: 1; padding: 0 4px; font-family: inherit; }
.spec-val button:hover { color: var(--danger); }
.sku-table input[type=number] { width: 110px; }

/* ---------------- 图片上传 ---------------- */

.imgs { display: flex; flex-wrap: wrap; gap: 10px; }
.img-item { position: relative; width: 88px; height: 88px; border-radius: 6px; overflow: hidden; border: 1px solid var(--border); background: #f2f4f7; }
.img-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.img-item__del { position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; border-radius: 50%; border: none; background: rgba(0,0,0,.55); color: #fff; font-size: 13px; line-height: 1; cursor: pointer; font-family: inherit; }
.img-item__badge { position: absolute; left: 0; bottom: 0; right: 0; background: rgba(0,0,0,.5); color: #fff; font-size: 10px; text-align: center; line-height: 16px; }
.img-add { width: 88px; height: 88px; border: 1px dashed #c9ced6; border-radius: 6px; background: #fafbfc; color: var(--muted); font-size: 12px; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; font-family: inherit; }
.img-add:hover { border-color: var(--primary); color: var(--primary); }
.img-add span { font-size: 20px; line-height: 1; }

/* 缩略图可点开大图。蒙层只在悬停时出现，动画不做也要能看懂：
   光标本身就是放大镜（zoom-in），这是最直接的暗示 */
.img-item { cursor: zoom-in; }
.img-item__hint { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, .38); color: #fff; font-size: 12px; letter-spacing: 1px; opacity: 0; transition: opacity .12s; z-index: 1;
  /* 蒙层只负责好看，绝不吃掉点击 —— 点击要落到整个 .img-item 上 */
  pointer-events: none; }
.img-item:hover .img-item__hint { opacity: 1; }

/* 删除按钮和「封面」角标要压在蒙层上面，否则悬停时会被一起压暗 */
.img-item__del { z-index: 3; }
.img-item__badge { z-index: 2; }

/* 正在上传的占位：优先显示本地选的那张图，上面盖一层「上传中…」。
   位子先占住，人就不会以为没点上而重复点 */
.img-item--loading { cursor: default; }
.img-item--loading img { opacity: .4; }
.img-item__mask { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, .35); color: #fff; font-size: 12px; z-index: 2; }

/* 大图预览。棋盘格底：透明底一眼能看出来 —— 透明被压成黑白底是
   上传环节最隐蔽的一种「变了样」，白底上根本看不出来 */
.img-preview { display: flex; align-items: center; justify-content: center; padding: 10px; border: 1px solid var(--border); border-radius: 6px; background-color: #fff;
  background-image: linear-gradient(45deg, #eceff3 25%, transparent 25%), linear-gradient(-45deg, #eceff3 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #eceff3 75%), linear-gradient(-45deg, transparent 75%, #eceff3 75%);
  background-size: 16px 16px; background-position: 0 0, 0 8px, 8px -8px, -8px 0; }
.img-preview img { max-width: 100%; max-height: 58vh; display: block; }
.img-preview__meta { margin-top: 12px; font-size: 12px; color: var(--muted); line-height: 1.9; }
.img-preview__url { word-break: break-all; }

/* ---------------- 轮播图 ---------------- */

.banner-thumb { width: 150px; height: 72px; border-radius: 6px; object-fit: cover; background: #f2f4f7; display: block; }
.banner-pick { display: flex; gap: 14px; align-items: flex-start; }
.banner-pick__img { width: 240px; height: 115px; border-radius: 6px; object-fit: cover; background: #f2f4f7; border: 1px solid var(--border); display: block; }
.banner-pick__side { display: flex; flex-direction: column; gap: 6px; }

/* ---------------- 统计 ---------------- */

.stat-range { display: flex; gap: 6px; flex-wrap: wrap; }
.stat-range a { padding: 5px 12px; border: 1px solid var(--border); border-radius: 6px; font-size: 13px; text-decoration: none; color: var(--text-mid); background: var(--card); }
.stat-range a:hover { border-color: #d5d9e0; }
.stat-range a.on { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }

/* 统计一律用表格呈现（不用图表）。
   基础样式里 table.list 只有横线，列一多就容易看串行，
   所以统计页的表格加网格线，行列都能对着读。 */
table.list--grid th,
table.list--grid td { border: 1px solid var(--border); }

/* 抵消基础样式里「最后一行不要下边框」那条——网格表要闭合 */
table.list--grid tr:last-child td { border-bottom: 1px solid var(--border); }

/* 表头底色压深一点，和数据行分开 */
table.list--grid thead th { background: #f4f6f8; }

/* 合计行：加粗 + 上边线加厚，一眼看出是汇总 */
table.list--grid tfoot td { background: #fafbfc; font-weight: 600; border-top: 2px solid var(--border); }

/* 「这一行全是 0」的日子/状态压暗一点，一眼能跳过 */
table.list tr.row--zero td { color: var(--muted); }

@media (max-width: 720px) {
  /* 窄屏把侧栏收窄，不然右侧内容区就没剩多少了 */
  :root { --sidebar-w: 132px; }
  .sidebar__brand { padding: 14px 12px; font-size: 14px; }
  .sidebar__nav a { padding: 10px 12px; font-size: 13px; }
  .sidebar__foot { flex-direction: column; align-items: flex-start; gap: 8px; padding: 12px; }
  .main { padding: 14px; }

  .banner-pick { flex-direction: column; }
  .banner-pick__img { width: 100%; height: auto; aspect-ratio: 25 / 12; }
}
