/* ==========================================================================
   parts-ui.css —— 通用部件皮肤（胶囊切换 / 工具条 / 空态 / 徽标 / 购买条 / 网格）
   --------------------------------------------------------------------------
   【铁律】这是通用件的皮肤。卡片专属样式在 parts-card.css，页面专属样式留在页面里。
   【铁律】所有颜色只走 --part-* 令牌，禁止硬编码。
   【依赖】必须先加载 parts-tokens.css
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 基础归一（只影响 .part-scope 内的元素，不污染主题原有样式）
   -------------------------------------------------------------------------- */
.part-scope{background:var(--part-page-bg);color:var(--part-text);font-family:var(--part-font)}
.part-scope *,
.part-scope *::before,
.part-scope *::after{box-sizing:border-box}
.part-scope a{color:inherit;text-decoration:none}
.part-scope img{display:block;max-width:100%}
.part-scope button{font:inherit;color:inherit;cursor:pointer}
.part-scope h1,.part-scope h2,.part-scope h3,.part-scope h4{margin:0;line-height:1.3}
.part-scope :focus-visible{outline:2px solid var(--part-accent);outline-offset:2px}
body:not(.night) .part-scope :focus-visible{outline-color:#101014}

/* --------------------------------------------------------------------------
   2. 区块与网格
   -------------------------------------------------------------------------- */
.part-zone{padding:26px var(--part-gutter) 0;max-width:1560px;margin:0 auto}
/*
 * 【2026-10-06】这里原本有一条 `.part-artstation--list .part-zone{...}` 覆盖 ——
 * 那是上一版图集列表页被塞进主题 1200px 容器时的补偿。
 * 现在图集列表页回到自己的通栏容器（.art-page），补偿规则随之改到
 * assets/css/parts-artstation.css 的 `.art-page .part-zone`，本文件不再插手。
 */
.part-zone-head{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:14px}
.part-zone-head h2{font-size:clamp(19px,2.2vw,27px);font-weight:900;letter-spacing:-.3px;color:var(--part-text)}
.part-zone-head small{display:block;font-size:11px;font-weight:600;letter-spacing:2.4px;color:var(--part-text3);margin-top:5px}
.part-zone-tools{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.part-rule{flex:1 1 60px;height:1px;background:var(--part-line);min-width:20px}

/* 等宽正方形网格：列数由 parts/grid.php 按屏宽算好写进 --part-cols */
.part-grid{display:grid;gap:var(--part-grid-gap);
  grid-template-columns:repeat(var(--part-cols,4),1fr)}
/* R54：行数裁剪时被 hidden 的卡不占格子（服务端供料多于实际显示，
   JS 按真实列数×行数隐藏多余卡，见 parts/grid.php 与 parts-grid.js） */
.part-grid>[hidden]{display:none}
/* type='card' 网格：卡片不是正方形（形态 A/B/C 各有固定几何），
   列宽门槛整体放宽一档，否则宽卡在窄列里会被挤变形 */
.part-grid--card{--part-grid-min:260px}

/* --------------------------------------------------------------------------
   2b. 图集网格卡（.gcard）—— parts/gallery-card.php 的皮肤
   --------------------------------------------------------------------------
   视觉语言：图片铺满正方形（1:1），静态只显示图；
   悬停 / 键盘聚焦时底部浮出标题 + 作者 + 浏览下载。
   【可访问性】浮出层靠 .gcard:hover 与 .gcard:focus-within 两条路显形，
   键盘用户 Tab 到卡片也能看到同样的信息，不靠 hover 独占。
   ========================================================================== */
.gcard{position:relative;display:block;min-width:0;aspect-ratio:1/1;
  border-radius:var(--part-r-md);overflow:hidden;background:var(--part-card);
  border:1px solid var(--part-line);transition:box-shadow .3s,border-color .3s,transform .3s}
/* R41：图集卡高度跟随 timthumb_height（用户拍板：正方形作废）。
   容器内联了 --part-thumb-h（grid 部件传出）时，直接子卡 .gcard 用固定高度，
   否则回落上一条 aspect-ratio:1/1。作用域限定 .part-grid 直接子项，
   不误伤详情页 "更多作品" 小网格（它不是 .part-grid 的直接子卡）。 */
.part-grid[style*="--part-thumb-h"]>.gcard{
  aspect-ratio:auto;
  height:var(--part-thumb-h);
}
.gcard:hover{border-color:var(--part-line2);box-shadow:var(--part-sh-hov);transform:translateY(-2px)}
.gcard-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  overflow:hidden;color:transparent;transition:transform .55s;
  /* R68 弱网骨架：图片加载前给 shimmer 底，避免图集列表弱网时整卡空白
     （480px 高只有一片浅底，视觉像"一条线"）。图片加载成功后自身盖住背景，
     版面无位移、无闪烁。 */
  background:linear-gradient(100deg,var(--part-card) 38%,color-mix(in srgb,var(--part-text) 9%,var(--part-card)) 50%,var(--part-card) 62%);
  background-size:200% 100%;
  animation:part-gcard-shimmer 1.4s ease-in-out infinite;
}
@keyframes part-gcard-shimmer{
  0%{background-position:130% 0}
  100%{background-position:-30% 0}
}
/* 【2026-10-07 健壮性 · 图裂兜底】图片加载失败时，浏览器会把 <img> 的 alt
   文字**当作元素内容**渲染出来。alt 可能是整条超长标题（样例里就有一条走外链、
   站点访问不到），直接摊在卡片上很难看。
   试过只加 overflow:hidden —— **没用**：文字本来就包在卡片尺寸内，没有溢出可剪
   （实测 scrollHeight == clientHeight == 186，截图里照样能看见）。所以改成
   color:transparent 让这段文字不显形；卡片的底色由 .gcard 的 background 提供，
   于是"图裂 = 一张干净的空卡"，形状尺寸与正常卡完全一致。
   【会不会丢信息】不会：完整标题仍在 <a> 的 aria-label 上，读屏照读；
   鼠标悬浮时 .gcard-body 里的标题也照常浮出。 */
.gcard:hover .gcard-img{transform:scale(1.06)}

/* 底部常显薄遮罩：给左下角的作者名托底。
   图片可能是全白的，没有这层，白字就看不见了。
   数值刻意比 hover 遮罩淡很多，保证常态还是一面干净的图墙。
   【2026-10-09 精简】原来是每卡一个空 <div class="gcard-scrim">，
   现在改成 .gcard::before —— 画出来的东西一样，DOM 少一层。 */
.gcard::before{content:'';position:absolute;left:0;right:0;bottom:0;height:42%;z-index:1;
  background:linear-gradient(0deg,var(--part-media-scrim-soft) 0%,transparent 100%);
  pointer-events:none}

/* 右上角价态角标：与已确认样机一致 —— 免费作品不出角标（见 gallery-card.php 的说明）
   【2026-10-09 精简】原来外面还套一层空 <div class="gcard-bd"> 只为了定位。
   定位样式直接给到 .gcard 的直接子项 .part-badges 上，那层壳就不需要了。 */
.gcard>.part-badges{position:absolute;top:9px;right:9px;z-index:4;display:flex;gap:5px;
  align-items:flex-start;pointer-events:none}

/* 作者角标：**常态可见**（与已确认的样机一致 —— 样机里作者名一直挂在左下角）。
   注意与 hover 浮出层里的作者不是一回事：浮出层只出标题与统计，作者只在这里出一次，
   避免同一张卡上作者名出现两遍。 */
.gcard-au{position:absolute;left:9px;bottom:9px;z-index:3;
  display:flex;align-items:center;gap:6px;max-width:calc(100% - 18px)}
/* 【R51 头像修复】作者角标从"渐变圆点占位"升级为**作者真实头像**。
   有头像（gallery-card.php 输出 .gcard-au__avatar > get_avatar()）时：
     · 显示头像 img（20px 正圆 + 描边，与原来的圆点同尺寸同视觉位置）
     · 隐藏 ::before 渐变圆点（头像 img 本身就是 flex 首项，gap:6px 照旧）
   无头像（作者存在但 get_avatar 兜底仍失败的极少数）→ 回退原渐变圆点。
   【无头像回退】用 :has() 判断：.gcard-au 里没有 .gcard-au__avatar 才画圆点。
   该选择器在现代浏览器（2023+）全部可用；老浏览器无 :has 时圆点与头像
   同时显示的概率极低（get_avatar 恒有兜底图），可忽略。
   【2026-10-07 用户反馈「头像尺寸不对」】原 15px 偏小，提到 --part-au-dot=20px。
   形状正圆 + object-fit:cover 兜底，防止被 flex 压成椭圆。 */
.gcard-au:not(:has(.gcard-au__avatar))::before{content:'';width:var(--part-au-dot);height:var(--part-au-dot);border-radius:50%;flex:none;
  background:linear-gradient(120deg,var(--part-accent),var(--part-promo));
  box-shadow:0 0 0 1.5px var(--part-media-scrim-soft)}
.gcard-au__avatar{display:inline-flex;flex:none;line-height:0}
.gcard-au__avatar img{width:var(--part-au-dot);height:var(--part-au-dot);border-radius:50%;object-fit:cover;
  box-shadow:0 0 0 1.5px var(--part-media-scrim-soft);display:block}
.gcard-au__name{font-size:11.5px;font-weight:600;color:var(--part-on-media);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  text-shadow:0 1px 3px var(--part-media-scrim)}

/* hover 浮出层：底渐变 + 标题 + 统计
   【2026-10-09 精简】hover 底渐变原是空 <div class="gcard-mask">，改成 .gcard::after。
   ::after 是 .gcard 的最后一个"子项"，但层级靠 z-index 说话（2），
   标题层 .gcard-body 是 3，所以压序和原来完全一致。 */
.gcard::after{content:'';position:absolute;inset:0;z-index:2;opacity:0;transition:opacity .3s;
  /* D-7：hover 底渐变加强 —— 底部平台 22%~46% 保持 0.82 强压暗（白字对纯白照片
     对比 ≈4.56），更高处平滑退到透明。只影响 hover 态，静态图墙观感不变。 */
  background:linear-gradient(0deg,var(--part-media-scrim) 0%,var(--part-media-scrim-strong) 22%,var(--part-media-scrim-strong) 46%,var(--part-media-scrim-mid) 64%,transparent 82%)}
.gcard-body{position:absolute;left:0;right:0;bottom:0;z-index:3;
  padding:12px 13px 30px;min-width:0;
  opacity:0;transform:translateY(8px);transition:opacity .3s,transform .3s}
.gcard-title{font-size:13px;font-weight:800;line-height:1.45;color:var(--part-on-media);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 浮出层压在深色遮罩上，所以文字/数字一律用「反白」语义 */
.gcard-meta{display:flex;align-items:center;flex-wrap:wrap;gap:9px;margin-top:7px;
  font-size:11.5px;color:var(--part-on-media-dim);font-variant-numeric:tabular-nums}
.gcard-meta>span{display:inline-flex;align-items:center;gap:3px;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gcard-meta .icon{font-size:12px;line-height:1;flex:none}
/* 作者名可收缩（长昵称不挤掉统计），统计数字不收缩 */
.gcard-author{flex:0 1 auto;max-width:52%}
.gcard-stat{flex:0 0 auto;color:var(--part-on-media-dim)}
.gcard-stat b{font-weight:600;color:var(--part-on-media)}
.gcard:hover::after,
.gcard:focus-within::after{opacity:1}
.gcard:hover .gcard-body,
.gcard:focus-within .gcard-body{opacity:1;transform:translateY(0)}
/* hover 时作者角标让位：标题会盖到左下角，两个叠一起会糊成一团 */
.gcard:hover .gcard-au{opacity:0;transition:opacity .2s}
/* 触屏没有 hover：浮出层常驻，否则标题永远看不到。
   【修正】这里曾经把作者角标一并 display:none，理由是「避免重复」——但重复是不成立的：
   浮出层里只有标题和浏览/下载，**没有作者**，角标一藏，手机上这张卡就完全没有作者信息了。
   现在保留角标，并保留 .gcard-body 底部的 30px 内边距给它让位（两者不会叠在一起）。
   注意：桌面浏览器即使窗口很窄也不会命中这条（媒体特性看的是设备有没有悬停能力）。 */
@media (hover:none){
  .gcard::after{opacity:1}
  .gcard-body{opacity:1;transform:translateY(0)} /* 不覆盖 padding-bottom，留给作者角标 */
  .gcard:hover{transform:none}
}
@media (prefers-reduced-motion: reduce){
  .gcard,.gcard-img,.gcard::after,.gcard-body{transition:none}
  .gcard:hover{transform:none}
  .gcard:hover .gcard-img{transform:none}
  /* R68：弱网骨架 shimmer 动画关闭（静态条保留） */
  .gcard-img{animation:none}
}

/* 窄屏：卡片最小宽度降到 --part-grid-min-xs(104px)，列数随之变多、每张卡更小
   （实测 1440→6列219px、500→4列106px、375→3列105px）。
   但作者角标与标题字号是**固定 px**，在小卡上占比失衡：105px 卡里一个15px 圆点
   已经是卡宽的 14%，标题 13px 两行也几乎占满。所以窄屏按卡宽同档收一档。 */
@media (max-width:760px){
  .gcard-au::before{width:var(--part-au-dot-xs);height:var(--part-au-dot-xs)}
  .gcard-au__avatar img{width:var(--part-au-dot-xs);height:var(--part-au-dot-xs)}
  .gcard-title{font-size:12px;line-height:1.4}
  .gcard-body{padding:10px 10px 28px}
}
@media (max-width:480px){
  .gcard-au__name{font-size:11px}
  .gcard-meta{font-size:11px;gap:7px}
}

/* --------------------------------------------------------------------------
   3. 胶囊切换（art-pill-tabs）—— 原 .art-pill-tabs / .art-pill-tab 抽到这里
   -------------------------------------------------------------------------- */
.part-pill-tabs{display:inline-flex;gap:2px;padding:3px;border-radius:var(--part-r-pill);
  background:var(--part-card);border:1px solid var(--part-line)}
/* 胶囊切换标签：与 .part-tool-chip / .part-badge 同一套文字排布（inline-flex 垂直居中）。
   【2026-10-07 统一】此前漏写 display，文字按行高顶盒子上沿（对比右组 chip 是居中的），
   用户肉眼可见「前三个偏上」。补齐 display:inline-flex;align-items:center;line-height:1
   —— 与 chip/badge 完全一致。只改文字排布，30px 高度 / padding / 圆角 / 选中态都不动。 */
.part-pill-tab{height:30px;padding:0 16px;border:0;border-radius:calc(var(--part-r-pill) - 4px);
  background:transparent;color:var(--part-text2);font-size:13px;font-weight:700;white-space:nowrap;
  display:inline-flex;align-items:center;line-height:1;transition:.2s}
.part-pill-tab:hover{color:var(--part-accent-text)}
/* 选中的标签用「深色填充」，不是强调色。
   【为什么】已确认的样机 p-list.html：.tabs button.on{background:var(--text);color:var(--card)}。
   同一个标题行里，「只看 VIP」才是强调色实心（它表示"正在筛"），
   两个都用橙色会分不清哪个是"当前在看什么"、哪个是"正在筛选"。 */
.part-pill-tab.is-active{background:var(--part-text);color:var(--part-card)}
/* R57（Q-31）：分类 Tab（data-key^="gal_"/"res_"）弱化成描边款，与实心排序 Tab 区分。
   【语义】分类 Tab=「我在看哪个区」，排序 Tab=「怎么排」，两者视觉必须能分辨。
   用 inset box-shadow 描边而非 border —— 不撑高度，30px 盒模型不变。 */
.part-pill-tab[data-key^="gal_"],.part-pill-tab[data-key^="res_"]{
  box-shadow:inset 0 0 0 1px var(--part-line2);background:transparent;color:var(--part-text2)}
.part-pill-tab[data-key^="gal_"].is-active,.part-pill-tab[data-key^="res_"].is-active{
  box-shadow:inset 0 0 0 1px var(--part-accent);color:var(--part-accent-text);background:transparent}

/* 工具 chip
   【2026-10-07 第五批 · 与 .part-pill-tab 归为同一视觉家族】
     用户拍板方案 A：两类控件语义不同、**不合并**，但要看起来像一家人。
     本次只做「视觉语言统一」，逐项对齐了 4 处（取值一律用令牌，不写死）：
       ① font-size   12.5px → 13px   （原先 tab 13 / chip 12.5，同一行里字号差半号）
       ② line-height 补 1            （原先 tab 有、chip 无；chip 的文字 ink box
                                       比盒中心高 0.375px，tab 是 0 —— 同一行两种基线）
       ③ white-space 补 nowrap       （tab 有、chip 无；长文案「进入图集频道 →」有换行风险）
       ④ 选中态语义保持分离（见下），本轮不合并
     height(30) / radius / font-weight(700) / transition(.2s) / border(1px) 原本就一致，不动。 */
.part-tool-chip{height:30px;padding:0 14px;border-radius:var(--part-r-pill);
  border:1px solid var(--part-line2);background:var(--part-card);color:var(--part-text2);
  font-size:13px;font-weight:700;display:inline-flex;align-items:center;gap:6px;
  line-height:1;white-space:nowrap;transition:.2s}
.part-tool-chip:hover{border-color:var(--part-accent);color:var(--part-accent-text)}
.part-tool-chip.is-active{background:var(--part-text);border-color:var(--part-text);color:var(--part-card)}

/* --------------------------------------------------------------------------
   4. 徽标（插件联动：付费 / VIP / 免费 / 拼团 / 推广）
      【铁律】角标的盒型只有这一份，任何页面不准自画
   -------------------------------------------------------------------------- */
/* 【2026-10-06 对齐主题】圆角从「药丸 11px」改成「主题角标的小方角 2px」。
   主题的 .vip-tag / .free-tag / .tuan-tag 全部是 border-radius:2px ——
   图集页的徽标属于同一类「价态标记」，圆角语言必须一致，
   否则同一个站里两处角标一个圆一个方，一眼就看出是两套。
   【为什么不跟 --theme-radius】主题自己这几个角标写的是固定 2px、
   没走 --theme-radius；这里跟主题的实际取值保持一致，不另立一套。 */
.part-badge{display:inline-flex;align-items:center;height:22px;padding:0 8px;
  border-radius:2px;font-size:11px;font-weight:800;letter-spacing:.3px;
  color:var(--part-on-accent);background:var(--part-accent);white-space:nowrap;line-height:1}
.part-badge--vip{background:linear-gradient(100deg,var(--part-vip-1),var(--part-vip-2));color:var(--part-vip-ink)}
.part-badge--free{background:var(--part-free);color:var(--part-on-accent)}
/* 价格徽标（卡片角标用）：强调色底，与形态 C 的价格竖排同一档位语言 */
.part-badge--price{background:var(--part-accent);color:var(--part-on-accent);
  font-family:var(--part-font-num);font-weight:900;letter-spacing:-.2px}
.part-badge--tuan{background:var(--part-tuan);color:var(--part-on-accent)}
.part-badge--promo{background:var(--part-promo);color:var(--part-on-accent)}
.part-badge--lg{height:26px;padding:0 11px;border-radius:3px;font-size:12px}

.part-price{font-family:var(--part-font-num);font-weight:900;color:var(--part-accent);
  letter-spacing:-.5px;line-height:1.05;white-space:nowrap}
.part-price small{font-size:.62em;font-weight:700}
.part-free-text{color:var(--part-free-text);font-weight:800;white-space:nowrap}
.part-vip-text{color:var(--part-vip-2);font-weight:800;white-space:nowrap}

/* --------------------------------------------------------------------------
   5. 按钮
   -------------------------------------------------------------------------- */
/* 【2026-10-06 移除】.part-btn 系列已删除：按钮改用**主题原生**的 .btn
   （见 static/css/base.css 的 .btn{background:var(--theme-color);…}），
   全站按钮从此只有一套皮肤。涉及 parts/buy-bar.php（登录/升级）与
   parts/author-block.php（关注/全部作品/推广赚佣）。不要加回来。 */

/*
 * 次级按钮 .btn--ghost —— 主题 .btn 的「描边款」补充（2026-10-06 新增）
 *
 * 【为什么需要它】主题的 .btn 只有一种实心样式，`.btn-*` 变体一个都没有。
 *   于是详情页右栏里「立即购买 / 登录 / 全部作品 / 推广赚佣」全是实心橙色，
 *   视觉权重一样高，主行动（购买）被淹掉（用户复核时指出"有点显眼"）。
 *
 * 【怎么做的】不改主题的 .btn，只在部件层补一个自己的修饰类。
 *   双类写法 `.btn.btn--ghost` 把优先级抬到 (0,2,0)，压过主题的 `.btn`(0,1,0)，
 *   因此不需要 !important。
 *
 * 【为什么用 inset 阴影而不是 border 画边】
 *   主题的 .btn 写的是 border:none。我们若加 1px 实体边框，按钮会比实心款
 *   高 2px、宽 2px —— 一旦两种按钮并排（将来可能），高度就对不齐了。
 *   inset 阴影不占盒模型尺寸，两种按钮尺寸完全一致，这是"零布局副作用"的画法。
 *
 * 【用在哪】次要动作：作者块的「全部作品 / 推广赚佣」。
 *   主行动（购买、登录/升级）继续用实心 .btn，两者形成清晰层级。
 * 【何时不要用】区块里只有一种动作时别用 —— 全站唯一的按钮就该是实心的。
 */
.btn.btn--ghost{
  background:transparent;
  color:var(--part-text2);
  box-shadow:inset 0 0 0 1px var(--part-line2);
}
.btn.btn--ghost:hover{
  /* 主题给 .btn:hover 写了 opacity:.9；描边按钮不需要变淡，这里还原 */
  opacity:1;
  background:transparent;
  box-shadow:inset 0 0 0 1px var(--part-accent);
  color:var(--part-accent-text);
}

/* --------------------------------------------------------------------------
   6. 购买条（插件联动）
      【铁律】只做「框 + 徽标 + 价格 + 按钮外观」。
            按钮点击后必须跳插件自己的购买入口，禁止在本部件内自建支付流程。
   -------------------------------------------------------------------------- */
.part-buybar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:12px 14px;border:1px solid var(--part-line);border-radius:var(--part-r-md);
  background:var(--part-panel)}
.part-buybar__note{font-size:12px;color:var(--part-text3)}
.part-buybar__actions{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}
.part-buybar__memo{width:100%;font-size:11.5px;line-height:1.75;color:var(--part-text3);
  border-top:1px solid var(--part-line);padding-top:9px}
.part-buybar__memo b{color:var(--part-text2)}

/* --------------------------------------------------------------------------
   7. 空态 / 加载态
   -------------------------------------------------------------------------- */
/* 【2026-10-06 移除】.part-empty 系列已删除：空态改用主题原生 .content-none
   （结构见 parts/empty-state.php，样式在 static/css/base.css）。不要加回来。 */
.content-none__sub{font-size:13px;margin-top:6px}

.part-loading{display:flex;align-items:center;justify-content:center;gap:10px;
  padding:34px 20px;color:var(--part-text3);font-size:13px}
.part-loading__dot{width:8px;height:8px;border-radius:50%;background:var(--part-accent);
  animation:part-spin 1s ease-in-out infinite}
.part-loading__dot:nth-child(2){animation-delay:.15s}
.part-loading__dot:nth-child(3){animation-delay:.3s}
@keyframes part-spin{0%,100%{opacity:.25;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}
@media (prefers-reduced-motion: reduce){
  .part-loading__dot{animation:none;opacity:.5}
}

/* --------------------------------------------------------------------------
   8. 翻页
   --------------------------------------------------------------------------
   【2026-10-06 本节清空】原来这里是 .part-pager 系列的自建皮肤。
   现在 parts/pager.php 改为输出**主题原生**的 `.pagination > ul > li` 结构，
   样式由 static/css/base.css 第 730-744 行提供（与全站其它列表页同一份）。
   自建皮肤已删除，**不要加回来** —— 否则图集页的翻页又会和全站不一致。
   -------------------------------------------------------------------------- */
.pagination-note{margin-top:8px;color:#999}

/* --------------------------------------------------------------------------
   9. 说明块
   -------------------------------------------------------------------------- */
.part-note{font-size:12.5px;line-height:1.8;color:var(--part-text2);
  background:var(--part-panel);border:1px solid var(--part-line);
  border-left:3px solid var(--part-accent);border-radius:8px;padding:11px 14px}
.part-note b{color:var(--part-text)}
.part-note--warn{border-left-color:var(--part-vip-2)}

/* 顶部来源说明条：标明这块是照搬主题还是新设计 */
.part-srcbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:9px 16px;background:var(--part-panel);border-bottom:1px solid var(--part-line);
  font-size:12px;color:var(--part-text2)}
.part-srcbar__tag{display:inline-flex;align-items:center;height:22px;padding:0 9px;
  border-radius:5px;font-size:11px;font-weight:800}
/* Q-06：三态语义色收口进 parts-tokens.css（--part-ok/new/hot-*），暗态随令牌切换 */
.part-srcbar__tag--keep{background:var(--part-ok-bg);color:var(--part-ok-fg);border:1px solid var(--part-ok-bd)}
.part-srcbar__tag--new{background:var(--part-new-bg);color:var(--part-new-fg);border:1px solid var(--part-new-bd)}
.part-srcbar__tag--plug{background:var(--part-hot-bg);color:var(--part-hot-fg);border:1px solid var(--part-hot-bd)}

/* --------------------------------------------------------------------------
   10. 断点
   -------------------------------------------------------------------------- */
@media (max-width:760px){
  .part-zone{padding-left:14px;padding-right:14px}
  .part-pager{padding-top:24px}
}

/* ==========================================================================
   11. 区块页头（部件：parts/page-head.php）
   --------------------------------------------------------------------------
   【来源】assets/css/homepage5.css 的 .part-head-row（1:1 抄，未改数值），
           把原 `.wrap ` 前缀去掉 —— 部件层的作用域是 .part-scope，
           页面外壳负责挂 .part-scope，本文件不重复挂。
   【本节只新增类】.part-head-row / .part-head-tools / .part-head-main
           以及 .part-tool-chip.is-accent（只加后缀态，不改 .part-tool-chip 本身定义）。
   ========================================================================== */
/* align-items:center —— 与样机 .head{display:flex;align-items:center} 对齐
   （题头、切换胶囊、工具三者在同一条中线上） */
.part-scope .part-head-row{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:0 0 2px;margin-bottom:16px}
/* 【2026-10-09】把 h1 也纳入：图集列表页的频道大标题现在是 <h1>
   （分类存档页的主标题，全页唯一；见 page-head 部件 level 参数说明）。
   不写进来，那一行的字号/字重会直接掉回浏览器默认，大标题变小变细。 */
.part-scope .part-head-row h1,
.part-scope .part-head-row h2,.part-scope .part-head-row h3{font-size:clamp(19px,2.2vw,27px);font-weight:900;letter-spacing:-.3px;line-height:1.2;color:var(--part-text)}
.part-scope .part-head-row small{display:block;font-size:11px;font-weight:600;letter-spacing:2.4px;color:var(--part-text3);margin-top:5px}
/* R49/R52：标题的统计文字（page-head 的 meta 参数）—— 与 subtitle 区分：
   常规字重/字距的小字，用于「共 N 个图集」这类统计，不上 GALLERY 大写风格。
   R52：图集列表页把大标题与筛选工具条合并成一条综合行后，meta 在默认形态
   （.part-head-main 内）也输出，所以选择器放开到两种形态都覆盖。 */
.part-scope .part-head-row .part-head-meta,
.part-scope .part-head-row--title .part-head-meta{display:inline-block;font-size:12px;font-weight:600;letter-spacing:.2px;color:var(--part-text3);margin-left:10px;vertical-align:baseline}
.part-scope .part-head-tools{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* 标题组：把 h2 + small 收成一个纵向块，flex 才能正确 align-items:flex-end */
.part-scope .part-head-main{min-width:0}
/* 强调态工具 chip：调用方传 accent=true 时**实心强调色**。
   【为什么是实心不是描边】已确认的样机 mock-base.css:134
   `.chip.on{background:var(--accent);border-color:var(--accent);color:#fff}` ——
   「只看 VIP」是这一行里唯一表示"正在生效的筛选"的东西，必须比标签更抢眼。 */
/* R66：底色原 --part-accent（亮 = 紫灰 #867a9a）+ 珍珠白字，仅 3.79:1 不达；
   改用 --part-text / --part-card 这对**明暗自适应**组合（与 .is-active 同款）：
   亮色 = 深紫灰底 + 珍珠白字 7.0:1、暗色 = 浅底 + 深字 12:1，双态达标。
   在 .part-head-tools 里仍由 parts-rococo 的金渐变覆盖（那是"生效筛选"的强调款）。 */
.part-scope .part-tool-chip.is-accent{background:var(--part-text);
  border-color:var(--part-text);color:var(--part-card)}
.part-scope .part-tool-chip.is-accent:hover{filter:brightness(.94)}

@media (max-width:760px){
  .part-scope .part-head-row{gap:10px;margin-bottom:12px}
  .part-scope .part-head-tools{margin-left:0;width:100%}
  .part-scope .part-rule{flex-basis:0;min-width:0}  /* 窄屏换行后分隔线不再撑宽度 */
}

/* --------------------------------------------------------------------------
   11b. 眉标（区块小标题）
   --------------------------------------------------------------------------
   【干什么用】「数据」「TAGS」「更多来自 X 的作品」这类每块顶部的一行小字。
   【为什么放库层】详情页右栏和页面上都由它，页面自己再定义一套一模一样的东西
   会造成「改了一处另一处没变」。放这里两处共用一个类。
   【数值来源】样机 p-detail.html 的 `.blk .bt{font-size:11px;font-weight:800;
   letter-spacing:1.4px;color:var(--text3)}`，逐条照搬，未改数值。
   -------------------------------------------------------------------------- */
.part-scope .part-eyebrow{
  margin:0 0 9px;
  font-size:11px;
  font-weight:800;
  letter-spacing:1.4px;
  color:var(--part-text3);
}

/* ==========================================================================
   12. 分类切换条（部件：parts/channel-bar.php）
   --------------------------------------------------------------------------
   【来源】assets/css/homepage5.css 的 .cat-strip + design-system.css §8 胶囊形态。
   【与 page-head 的分工】这里可横滚、数量多、带圆形小图与计数；page-head 不可横滚。
   【本节只新增类】.part-catbar / .part-catbar__item / __ic / __name / __num
   ========================================================================== */
.part-scope .part-catbar{display:flex;align-items:center;gap:10px;
  overflow-x:auto;padding-bottom:6px;
  scrollbar-width:none;-ms-overflow-style:none;      /* 隐藏滚动条，滚动条本身是噪音 */
  scroll-snap-type:x proximity}                      /* proximity 而非 mandatory：横滑条不该硬卡位 */
.part-scope .part-catbar::-webkit-scrollbar{display:none}

.part-scope .part-catbar__item{display:inline-flex;align-items:center;gap:9px;flex:0 0 auto;
  height:46px;padding:0 18px;border-radius:var(--part-r-md);
  background:var(--part-card);border:1px solid var(--part-line);
  font-size:13.5px;font-weight:600;color:var(--part-text2);
  scroll-snap-align:start;transition:border-color .22s,color .22s,box-shadow .22s}
.part-scope .part-catbar__item:hover{border-color:var(--part-accent);color:var(--part-text);box-shadow:var(--part-sh)}

/* 圆形小图 26px：有 thumb 图时显示图，无图时显示分类名首字（--c 缺省回落到强调色） */
.part-scope .part-catbar__ic{width:26px;height:26px;border-radius:50%;flex:none;
  display:grid;place-items:center;overflow:hidden;
  font-style:normal;font-size:12.5px;font-weight:700;
  color:var(--part-on-accent);background:var(--c,var(--part-accent))}
.part-scope .part-catbar__ic img{width:100%;height:100%;object-fit:cover}

.part-scope .part-catbar__name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.part-scope .part-catbar__num{font-size:11px;font-weight:500;color:var(--part-text3);
  font-variant-numeric:tabular-nums;white-space:nowrap}

.part-scope .part-catbar__item.is-active{background:var(--part-accent);border-color:var(--part-accent);color:var(--part-on-accent)}
.part-scope .part-catbar__item.is-active .part-catbar__num{color:var(--part-on-accent);opacity:.82}
/* 选中态的小图压一层白色内描边，避免白图压在强调色底上看不出边界 */
.part-scope .part-catbar__item.is-active .part-catbar__ic{box-shadow:0 0 0 1px rgba(255,255,255,.5) inset}

@media (max-width:760px){
  .part-scope .part-catbar{gap:8px}
  .part-scope .part-catbar__item{height:42px;padding:0 14px;font-size:12.5px}
  .part-scope .part-catbar__ic{width:22px;height:22px;font-size:11.5px}
}

/* ==========================================================================
   13. 精选轮播（部件：parts/hero-row.php）
   --------------------------------------------------------------------------
   【来源】assets/css/homepage5.css 的 .art-top-row / .art-tr-* / .art-hero-nav，
           1:1 抄，未改一个数值，只把原 `.wrap ` 前缀换成 `.part-scope `。

   【★ 全项目唯一允许写死色的地方就在本节】
       .art-tr-grad / .art-tr-tag / .art-tr-title / .art-tr-desc / .art-hero-nav
       这些是「压在照片上的渐变遮罩 + 白字 + 悬浮控件」。
       照片亮度不可控（可能是一张纯白婚纱照），用 var(--part-text) 会在亮图上变成
       白底白字，完全看不见。所以这里必须固定深底 + 白字，与主题明暗无关。
       除此之外本节的背景 / 边框 / 卡片底色全部走 var(--part-*) 令牌。
   ========================================================================== */
.part-scope .art-top-row{position:relative;margin:0 0 6px}
.part-scope .art-top-row-track{display:flex;gap:14px;overflow-x:auto;padding-bottom:8px;
  scrollbar-width:none;scroll-snap-type:x mandatory}
.part-scope .art-top-row-track::-webkit-scrollbar{display:none}
.part-scope .art-tr-card{position:relative;flex:0 0 auto;width:min(62vw,520px);
  aspect-ratio:16/5.4;border-radius:12px;overflow:hidden;
  background:var(--part-card);scroll-snap-align:start;border:1px solid var(--part-line)}
.part-scope .art-tr-card img{width:100%;height:100%;object-fit:cover;transition:transform .6s}
.part-scope .art-tr-card:hover img{transform:scale(1.05)}

/* 无图兜底：parts/hero-row.php 在没有特色图时输出这个纯色块，不输出 broken image。
   底色走 --part-line 令牌（明暗自动跟随），不写死色。 */
.part-scope .art-tr-ph{display:block;width:100%;height:100%;background:var(--part-line)}

/* ↓ 以下为压在照片上的固定深底 + 白字（唯一允许写死色的区） */
/* 【2026-10-09 精简】原 .art-tr-grad 是每张运营卡里的一个空 div，
   只画一层左深右浅的渐变（给左边的白色标题托底）。纯装饰 → 改由
   .art-tr-card::before 承担；::before 是 .art-tr-card 的第一个"子项"，
   而文字层 .art-tr-tag / .art-tr-info 都是 absolute 且排在它后面，
   压序与原来完全一致。 */
.part-scope .art-tr-card::before{content:'';position:absolute;inset:0;
  /* D-7：双层 scrim —— 底部上压 + 左侧右压，文字区（左下 tag/title/desc）
     对任意明暗照片都达标；高/右渐次退让。原单层 90deg 换为双渐变。 */
  background:
    linear-gradient(0deg,rgba(8,8,12,.9) 0%,rgba(8,8,12,.62) 45%,rgba(8,8,12,.18) 78%,transparent 100%),
    linear-gradient(90deg,rgba(8,8,12,.82) 0%,rgba(8,8,12,.35) 60%,transparent 100%)}
.part-scope .art-tr-tag{position:absolute;top:12px;left:14px;font-size:11px;font-weight:700;
  color:#ffd7a8;background:rgba(0,0,0,.35);border:1px solid rgba(255,255,255,.18);
  padding:4px 10px;border-radius:20px}
.part-scope .art-tr-info{position:absolute;left:14px;bottom:12px;right:40%}
.part-scope .art-tr-title{font-size:16px;font-weight:800;color:#fff}
/* D-7：desc 由深灰（--part-text2）改浅（--part-on-media-dim，72% 白）。
   R65 时改深是给「浅底占位块」可读，但那场景文字压在照片上；
   现在底部 scrim 已把文字区统一压暗，浅字在明暗照片与占位块上全达标。 */
.part-scope .art-tr-desc{font-size:11.5px;color:var(--part-on-media-dim);margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.part-scope .art-hero-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:6;
  width:40px;height:40px;border:1px solid rgba(255,255,255,.28);
  background:rgba(13,13,16,.58);color:#fff;border-radius:50%;font-size:19px;
  display:grid;place-items:center;cursor:pointer;opacity:0;transition:.25s;
  backdrop-filter:blur(6px);box-shadow:0 6px 18px rgba(0,0,0,.3)}
.part-scope .art-top-row:hover .art-hero-nav,
.part-scope .art-hero-nav:focus-visible{opacity:1}
.part-scope .art-hero-nav:hover{background:rgba(13,13,16,.85)}
.part-scope .art-hero-nav.prev{left:10px}
.part-scope .art-hero-nav.next{right:10px}

/* 到边禁用：assets/js/parts-hero.js 滚到两端时加 disabled。
   必须用 !important —— 上面 .art-top-row:hover 那条规则的优先级同样高且更靠后。 */
.part-scope .art-hero-nav[disabled]{opacity:0!important;pointer-events:none}

/* 单卡（服务端只在 >=2 张时才输出按钮）时不让卡片孤零零缩在左边 */
.part-scope .art-top-row.is-single .art-tr-card{width:100%}

@media (hover:none),(max-width:760px){
  .part-scope .art-hero-nav{opacity:1;width:34px;height:34px;font-size:16px}
  .part-scope .art-hero-nav[disabled]{opacity:0!important}
}

@media (max-width:760px){
  .part-scope .art-tr-card{width:min(86vw,520px)}
  .part-scope .art-tr-title{font-size:14.5px}
  .part-scope .art-tr-info{right:44%}
  .part-scope .art-tr-tag{top:10px;left:12px}
}

@media (max-width:480px){
  .part-scope .art-tr-title{font-size:13.5px}
  .part-scope .art-tr-desc{font-size:11px}
  .part-scope .art-tr-info{right:40%;bottom:10px}
}

/* 尊重系统的「减少动态效果」设置：关掉图片缩放与平滑滚动 */
@media (prefers-reduced-motion:reduce){
  .part-scope .art-top-row-track{scroll-behavior:auto}
  .part-scope .art-tr-card:hover img{transform:none}
}

/* ==========================================================================
   13. 更多作品小图网格（部件：parts/more-by.php）
   --------------------------------------------------------------------------
   【来源】样机 p-detail.html 的 MORE BY 区块：
     `grid-template-columns:repeat(4,1fr);gap:7px` + 方形小图 + 悬停出标题。
   【为什么是独立部件而不是复用 .gcard】.gcard 是列表页方形图墙的卡，
   带价态角标、作者角标、悬浮浮层；塞进 392px 宽的右栏每行 4 个会挤成一团。
   这一块只需要「裸图 + 悬停标题」。
   ========================================================================== */
.part-scope .part-more__grid{
  display:grid;
  grid-template-columns:repeat(var(--part-more-cols,4),1fr);
  gap:7px;
}

/* 2026-10-11 用户拍板（样机 p-detail-r35.html:166）：
   同类作品宽屏 1×4，只有手机降到 2×2。
   【为什么要这一条】右栏在宽屏下恒为 392px，4 列已经挤到每格 82px；
   到了手机右栏变成整屏宽（~390px），还按 4 列排的话每格仍只有 ~90px，
   比宽屏还小 —— 手机上反而更看不清。所以按屏宽断，而不是按容器宽度断：
   手机上格子变大反而给 2 列，每格 ~190px，认得出画面。 */
@media (max-width:560px){
  .part-scope .part-more__grid{grid-template-columns:repeat(2,1fr)}
}

.part-scope .part-more__a{
  position:relative;
  display:block;
  aspect-ratio:1/1;
  overflow:hidden;
  border:1px solid var(--part-line);
  border-radius:var(--part-r-sm);
  background:var(--part-line);
}

.part-scope .part-more__a img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  transition:transform .3s;
}
.part-scope .part-more__a:hover img{transform:scale(1.06)}

/* 悬停标题：压在图片底部，用媒体浮层令牌（只在图片上用的那组） */
.part-scope .part-more__a::after{
  content:attr(data-t);
  position:absolute;
  inset:auto 0 0 0;
  padding:14px 6px 5px;
  font-size:10.5px;
  line-height:1.3;
  color:var(--part-on-media);
  background:linear-gradient(180deg,transparent,var(--part-media-scrim));
  opacity:0;
  transition:opacity .2s;
}
.part-scope .part-more__a:hover::after{opacity:1}

/* 触屏没有悬停：标题常驻，否则手机上永远看不到作品名 */
@media (hover:none){
  .part-scope .part-more__a::after{opacity:1}
}

@media (prefers-reduced-motion:reduce){
  .part-scope .part-more__a:hover img{transform:none}
}

/* ==========================================================================
   13b. 继续阅读 / 上一篇·下一篇（部件：parts/post-nav.php）
   --------------------------------------------------------------------------
   对应样机 p-detail-r35.html 的 `.rec .pair`。值与样机逐条对齐，
   颜色按规矩换成 --part-* 令牌（样机里的 --line / --text2 / --text3 /
   --accent-text 在主题里分别是 --part-line / --part-text2 / --part-text3 /
   --part-accent-text），圆角同样走令牌，不写字面量。
   ========================================================================== */
.part-scope .part-postnav__pair{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:10px;
}
.part-scope .part-postnav__pair > a{
  display:block;
  min-width:0;
}

/* 图盒恒为 2:1：样机 p-detail-r35.html:146 的 aspect-ratio:2/1 */
.part-scope .part-postnav__ph{
  position:relative;
  display:block;
  aspect-ratio:2/1;
  overflow:hidden;
  border-radius:var(--part-r-md);
  background:var(--part-line);
}
.part-scope .part-postnav__ph img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  transition:transform .45s cubic-bezier(.22,1,.36,1);
}

/* 标题行：左右箭头分列标题两侧、都指向各自外侧 */
.part-scope .part-postnav__lb{
  display:flex;
  align-items:flex-start;
  gap:5px;
  margin-top:8px;
  min-width:0;
}
.part-scope .part-postnav__lb .icon{
  flex:none;
  font-size:12px;
  color:var(--part-text3);
  margin-top:3px;
  transition:color .2s;
}

/* ★ 标题只显示 1 行，超出省略（2026-10-11 用户拍板）
   【为什么必须是 1 行、而不是可换行的 2 行】左右两张卡在同一条 grid 线上，
   谁先换行谁就把整行撑高、另一张被顶出一条空白。锁 1 行 + overflow:hidden
   才能保证两卡恒等高，右栏长度不受文章标题长短影响。 */
.part-scope .part-postnav__tx{
  min-width:0;
  font-size:12.5px;
  font-weight:700;
  line-height:1.45;
  color:var(--part-text2);
  display:-webkit-box;
  -webkit-line-clamp:1;
  -webkit-box-orient:vertical;
  overflow:hidden;
  transition:color .2s;
}

.part-scope .part-postnav__pair > a:hover .part-postnav__ph img{transform:scale(1.05)}
.part-scope .part-postnav__pair > a:hover .part-postnav__tx,
.part-scope .part-postnav__pair > a:hover .part-postnav__lb .icon{color:var(--part-accent-text)}

/* 只有一个邻居时替补的那一格：撑住列宽，不出边框 */
.part-scope .part-postnav__gap{display:block}

@media (prefers-reduced-motion:reduce){
  .part-scope .part-postnav__pair > a:hover .part-postnav__ph img{transform:none}
}

/* ==========================================================================
   表情互动条（已删除，2026-10-07）
   --------------------------------------------------------------------------
   原 parts/reaction-bar.php（样机 .emo）连同本节样式一起删除：
   数据是造数、点击没有任何 JS 接，属「假数据 + 假按钮」。
   不要恢复 —— 真要做表情互动，先补落库与接口。
   ========================================================================== */

/* ==========================================================================
   使用软件（parts/software-list.php）
   --------------------------------------------------------------------------
   对应样机 p-detail.html:118-120 的 .sw。
   样机是纯文字胶囊；用户 2026-10-06 定改成「主题图标 + 名字」，
   图标取自 static/css/iconfont.css（icon-adobe / icon-aff / icon-sketchup /
   icon-photo / icon-tool）。
   ========================================================================== */
.part-scope .art-sw{
  display:flex;
  gap:6px;
  flex-wrap:wrap;
}
.part-scope .art-sw__it{
  display:inline-flex;
  align-items:center;
  gap:5px;
  padding:5px 10px;
  border-radius:var(--part-r-sm);
  background:var(--part-card);
  border:1px solid var(--part-line);
  font-size:11.5px;
  line-height:1.2;
  color:var(--part-text2);
}
.part-scope .art-sw__it .icon{
  font-size:13px;
  line-height:1;
}
.part-scope .art-sw__t{
  white-space:nowrap;
}

/* ==========================================================================
   R25 语义骨架：视觉隐藏工具类
   用于补「页面缺 h1」「标题跳级缺中间层」时插入的语义标题。
   【为什么不是 display:none / visibility:hidden】那两种写法搜索引擎和读屏软件
   同样读不到，等于没补。这里的写法是行业通用的 screen-reader-text：元素仍在
   DOM 与无障碍树里，只是被裁到 1×1 且不可见。
   【注意】本文件只在部件层页面加载（见 inc/parts-loader.php）；经典模板页
   （category / all / 首页模板一~四 等）不走部件层，那些模板里同名规则由模板
   自带的内联 <style> 提供，规则与本条逐字一致。
   ========================================================================== */
.mbt-sr-only{
  position:absolute;
  width:1px;
  height:1px;
  padding:0;
  margin:-1px;
  overflow:hidden;
  clip:rect(0,0,0,0);
  white-space:nowrap;
  border:0;
}

/* ==========================================================================
   R67：窄屏（≤760px 手机）所有部件网格统一 2 列，卡更宽更清晰。
   --------------------------------------------------------------------------
   · 与 parts-grid.js 的 isPhone() 断点必须一致（改一边就要改另一边）。
   · 特异性 .part-scope .part-grid（0,2,0）> 基础规则 .part-grid（0,1,0）
     （见本文件第 39–41 行等宽网格），且位于同文件更后位置，无需 !important。
   · 作用：无 JS 兜底 + 首帧不闪 —— 服务端初值 --part-cols 在手机上可能
     是 3，被这条规则压成 2；JS 校准（parts-grid.js R67）也写 2，两端一致。
   ========================================================================== */
@media (max-width:760px){
  .part-scope .part-grid{grid-template-columns:repeat(2,1fr)}
}
