/* ============================================================
   有牛 — 作品集
   跟前台共用一套材料（墨线 + 硬阴影 + 10px 圆角），
   但卡片比文章卡片更「实物」一点：作品是要被看的，封面得占住版面。

   视频和音频靠**形状**区分，不只靠颜色：
   视频是三角（播放），音频是波形（竖条）。
   配色也不同（视频走干草黄、音频走草叶绿），但色盲的人靠形状也能分出来 ——
   只差颜色的话，这层区分对一部分人等于不存在。
   ============================================================ */

/* ---------- 首页的横向轨道 ---------- */
.works__rail{
  /* 轨道要出血到屏幕边缘（卡片滑到边上会被切），但「静止时」卡片必须跟区块标题对齐。
     标题在 .wrap 里，视口一宽 .wrap 就有居中留白，所以左侧留白要把这一份算上：
         左留白 = max(gutter, (视口 - maxw) / 2 + gutter)
     max() 兜住视口比 --maxw 窄的情况（那时算出负数）。
     这里的 100% 是轨道包含块的宽度（= .sec 的内容盒 = 视口宽），
     跟 .wrap 算居中留白用的是同一个数。 */
  --rail-pad: max(var(--gutter), calc((100% - var(--maxw)) / 2 + var(--gutter)));
  overflow-x:auto;
  overflow-y:hidden;
  /* 留白放在**容器 padding** 里，不放进轨道内容 —— 这不是风格选择，是「必然性」：
     容器 padding 不属于可滚动内容，所以 scrollLeft=0 时卡片自然就落在左留白结束处，
     对齐不依赖任何额外条件。
     曾经把留白放进轨道内容、再靠 scroll-padding 去校正吸附点，那是个脆弱的依赖：
     一旦 scroll-padding 没被认，浏览器会把轨道吸到「内容里最后一个能吸的位置」，
     1600 宽下实测 scrollLeft 从 0 跳到 306px、卡片一路贴到屏幕最左边 —— 就是那张截图。 */
  padding:6px var(--rail-pad) 22px;
  /* **不要 scroll-snap**（mandatory 试过、proximity 也试过，都撤了）：
     只要轨道上有吸附，浏览器在「布局一稳定」就会主动把滚动位置挪到吸附点上，
     而吸附点算在哪里取决于 scroll-padding 解不解析得对 —— 等于把「静止时是否对齐」
     押在一句可能不被认的声明上。proximity 也不安全，实测它照样会在加载后挪一次。
     现在纯粹靠容器留白：任何浏览器、任何版本，静止位置只可能是 scrollLeft=0。
     代价是手动滑完松手不会自动停在卡片边界 —— 用「一定对齐」换的，值。 */
  -webkit-overflow-scrolling:touch;
  /* 滚动条本身不好看，但**不能藏掉** —— 藏了就没人知道右边还有东西。
     留一条细的，同时靠卡片被切断来暗示可滑。 */
  scrollbar-width:thin;
}
/* 颜色跟全站那根走（见 site.css 的「滚动条」一节），只把高度压到 8px：
   这条轨道是横的、紧贴卡片下沿，用全站的 15px 会吃掉卡片一截。
   代价是得把全站那圈 4px 乳白描边收掉 —— 8px 的槽扣掉两侧 4px 什么都不剩。
   这里不需要那圈描边：轨道外面就是牛乳白页底，不会撞上深绿。 */
.works__rail::-webkit-scrollbar{ height:8px; }
.works__rail::-webkit-scrollbar-thumb{
  background:var(--sb);
  border:0;
  border-radius:var(--r-pill);
}
.works__rail::-webkit-scrollbar-thumb:hover{ background:var(--sb-hover); }
.works__track{
  display:flex; gap:20px;
  /* padding:0 不能省：ul 自带 padding-inline-start:40px，
     留着卡片会整体右移 40px，对齐就差这一点（容器留白方案下才会露出来）。 */
  margin:0; padding:0; list-style:none;
  /* 宽度必须 max-content：默认是包含块的 100%，这时自身的 padding-right 落在盒内、
     构不成溢出，右边那段留白等于没加。 */
  width:max-content;
  /* 右侧再补一段：容器 padding-right 在内容溢出时不被算进滚动区，
     滚到底末卡会贴到屏幕右边。这里的 100% 基准是轨道的内容盒（已被容器 padding 吃掉一圈），
     所以算出来比左留白小 —— 够用就行，目的是滚到底不贴边，不是跟左边绝对对称。 */
  padding-right: var(--rail-pad);
  /* 轨道内容至少要占满一屏，卡片少时才不会挤在左边一小撮 */
  min-width:100%;
}

/* ---------- 卡片 ---------- */
.work{
  flex:0 0 clamp(232px, 26vw, 316px);
}
/* /works 页是网格，卡片宽度交给网格决定 */
.works__grid .work{ flex:none; }

.work__link{
  display:block; color:inherit; text-decoration:none;
}
.work__cover{
  position:relative; aspect-ratio:16/9; overflow:hidden;
  background:var(--hay-30);
  border:var(--line) solid var(--ink);
  border-radius:var(--r-sticker);
  box-shadow:3px 3px 0 var(--ink);
  transition:transform .18s var(--ease), box-shadow .18s var(--ease);
}
.work__link:hover .work__cover,
.work__link:focus-visible .work__cover{
  transform:translate(-2px,-2px);
  box-shadow:6px 6px 0 var(--ink);
}
.work__cover img{ width:100%; height:100%; object-fit:cover; display:block; }

/* 没有封面图时的占位：一块配色底 + 一个类型图形，
   比灰方块有交代得多 —— 一眼能看出这条是视频还是音频。 */
.work__ph{
  position:absolute; inset:0;
  display:grid; place-items:center;
}
.work__ph--audio{ background:var(--leaf-14); }
.work__ph--video{ background:var(--hay-30); }
.work__ph svg{ width:42%; height:auto; }
/* 视频那个三角按**高度**定尺，不按宽度：占位区是 16:9 的扁条，
   按宽度给的尺寸在竖直方向会顶到边，三角一放大会变回「按钮」的样子。
   高度给 34%，它在扁条里就只是一枚记号。 */
.work__ph--video svg{ width:auto; height:34%; }

.work__kind{
  position:absolute; left:10px; top:10px;
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 10px 5px;
  background:var(--milk);
  border:var(--hair) solid var(--ink); border-radius:var(--r-pill);
  font-size:.72rem; letter-spacing:.06em; line-height:1;
}
.work__kind i{ display:inline-block; width:0; height:0; }
/* 视频：实心三角 */
.work__kind--video i{
  border-left:7px solid var(--ink);
  border-top:4.5px solid transparent;
  border-bottom:4.5px solid transparent;
}
/* 音频：三根高低不同的竖条 */
.work__kind--audio i{
  width:11px; height:9px;
  background:
    linear-gradient(var(--ink),var(--ink)) 0 3px/2.5px 6px no-repeat,
    linear-gradient(var(--ink),var(--ink)) 4px 0/2.5px 9px no-repeat,
    linear-gradient(var(--ink),var(--ink)) 8px 4px/2.5px 5px no-repeat;
}

.work__dur{
  position:absolute; right:10px; bottom:10px;
  padding:3px 9px 4px;
  background:var(--ink); color:var(--milk);
  border-radius:var(--r-pill);
  font-size:.72rem; line-height:1;
  font-variant-numeric:tabular-nums;
}

.work__title{
  margin:14px 0 0;
  font-family:var(--font-display);
  font-size:1.06rem; font-weight:900; line-height:1.45;
  letter-spacing:-.01em;
}
.work__meta{
  margin:7px 0 0;
  font-size:var(--step-meta); color:var(--ink-60);
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
.work__meta em{ font-style:normal; }
/* 平台名（B站 / 网易云…）用小胶囊，跟日期区分开 */
.work__plat{
  padding:2px 8px 3px;
  border:var(--hair) solid var(--ink); border-radius:var(--r-pill);
  font-size:.7rem;
}
.work__excerpt{
  margin:9px 0 0; font-size:.9rem; line-height:1.75; color:var(--ink-60);
}

/* ---------- /works 独立页 ---------- */
.worksHead{ padding-bottom:26px; }
.worksHead h1{ margin:0 0 12px; }
.worksHead__note{ margin:0; max-width:52ch; color:var(--ink-60); line-height:1.85; }

.worksPick{ display:flex; gap:10px; flex-wrap:wrap; margin:20px 0 30px; }
.worksPick a{
  display:inline-flex; align-items:center; gap:8px;
  padding:8px 16px 9px;
  background:var(--milk); color:inherit; text-decoration:none;
  border:var(--hair) solid var(--ink); border-radius:var(--r-pill);
  font-size:.86rem;
}
.worksPick a[aria-current="true"]{ background:var(--ink); color:var(--milk); }
.worksPick span{ font-variant-numeric:tabular-nums; opacity:.62; }

.works__grid{
  display:grid; gap:38px 26px;
  grid-template-columns:repeat(2, minmax(0,1fr));
  margin:0; padding:0; list-style:none;
}
@media (max-width:760px){ .works__grid{ grid-template-columns:1fr; gap:30px; } }

.worksEmpty{
  padding:56px 0 40px; text-align:center; color:var(--ink-60);
}

/* 锚点跳过来时把那一件提一下，不然用户不知道跳到哪了 */
.work:target .work__cover,
.work.is-focused .work__cover{
  box-shadow:6px 6px 0 var(--ink);
  outline:3px solid var(--leaf); outline-offset:3px;
}

/* ---------- 音频播放器 ---------- */
.wplay{
  display:flex; align-items:center; gap:14px;
  margin-top:16px; padding:11px 14px 12px;
  background:var(--milk);
  border:var(--hair) solid var(--ink); border-radius:var(--r-sticker);
}
.wplay__btn{
  flex:none; width:40px; height:40px;
  display:grid; place-items:center;
  background:var(--leaf); color:var(--ink);
  border:var(--line) solid var(--ink); border-radius:50%;
  cursor:pointer;
  transition:transform .14s var(--ease), box-shadow .14s var(--ease);
  box-shadow:2px 2px 0 var(--ink);
}
.wplay__btn:hover{ transform:translate(-1px,-1px); box-shadow:3px 3px 0 var(--ink); }
.wplay__btn svg{ width:15px; height:15px; }
.wplay__btn .wplay__pause{ display:none; }
.wplay.is-playing .wplay__play{ display:none; }
.wplay.is-playing .wplay__pause{ display:block; }

.wplay__bar{
  position:relative; flex:1; height:26px;
  display:flex; align-items:center;
  cursor:pointer;
}
.wplay__bar::before{
  content:''; position:absolute; left:0; right:0; height:3px;
  background:color-mix(in srgb, var(--ink) 22%, var(--milk));
  border-radius:var(--r-pill);
}
.wplay__fill{
  position:absolute; left:0; height:3px; width:0;
  background:var(--ink); border-radius:var(--r-pill);
}
.wplay__knob{
  position:absolute; left:0; width:13px; height:13px; margin-left:-6.5px;
  background:var(--milk);
  border:var(--hair) solid var(--ink); border-radius:50%;
  transition:transform .12s var(--ease);
}
.wplay__bar:hover .wplay__knob{ transform:scale(1.14); }
.wplay__time{
  flex:none; font-size:.78rem; color:var(--ink-60);
  font-variant-numeric:tabular-nums; letter-spacing:.02em;
}
/* 播不动（文件丢了、格式不支持）时把原因写在控件下面，别只是一直转 */
.wplay__err{ margin:8px 0 0; font-size:var(--step-meta); color:var(--live); }

/* ---------- 正文折叠 ----------
   列表页要的是「一眼扫完有哪几件」，所以正文默认合着。
   这里就不放 summaries 之外的新东西了：沿用站里那套胶囊 + 墨线，
   让人一眼看出这是个能点的开关。 */
.work__more{ margin-top:14px; }
.work__more > summary{
  display:inline-flex; align-items:center; gap:9px;
  padding:7px 15px 8px;
  background:var(--milk);
  border:var(--hair) solid var(--ink); border-radius:var(--r-pill);
  font-size:var(--step-meta); line-height:1; color:var(--ink);
  cursor:pointer;
  /* 浏览器自带的三角（WebKit 的 ::-webkit-details-marker / 标准 list-style）
     两处都得去掉，只去掉一处的话会变成两个箭头并列 */
  list-style:none;
  transition:background .18s var(--ease), transform .18s var(--ease);
}
.work__more > summary::-webkit-details-marker{ display:none; }
.work__more > summary:hover{ background:var(--hay-30); }
.work__more > summary:focus-visible{
  outline:2.5px solid var(--pasture); outline-offset:2px;
}
.work__more[open] > summary{ background:var(--hay); }

/* 小箭头：合着朝右、展开转朝下。旋转比换图标省一个请求，
   而且状态切换是连续的，看得出「刚才点的是这里」 */
.work__more > summary::after{
  content:''; width:6px; height:6px;
  border-right:2px solid var(--ink);
  border-bottom:2px solid var(--ink);
  transform:rotate(-45deg);
  transition:transform .22s var(--ease);
}
.work__more[open] > summary::after{ transform:rotate(45deg); }

/* 展开出来的正文：抄 .prose，但按卡片宽度收一档 ——
   .prose 是给通栏文章写的（1.075rem / 2.05），放进两列网格里横竖都太壮。 */
.work__body{
  margin-top:14px;
  padding:18px 20px 8px;
  background:color-mix(in srgb, var(--hay) 8%, var(--milk));
  border:var(--hair) solid color-mix(in srgb, var(--ink) 20%, var(--milk));
  border-radius:var(--r-sticker);
  font-size:.94rem;
  line-height:1.9;
}
.work__body > * + *{ margin-top:1.1em; }
/* .prose 里的标题是给长文分层用的（带下划线装饰、有大留白），
   在这儿只会把卡片顶歪，压回正文的亲戚就行 */
.work__body h2,
.work__body h3{
  font-family:var(--font-display); font-weight:900;
  margin-top:1.4em; padding-top:0;
  font-size:1.02rem; line-height:1.6;
}
.work__body h2::after{ display:none; }
.work__body p:first-child,
.work__body h2:first-child,
.work__body h3:first-child{ margin-top:0; }

/* 视频：点了才加载 iframe ---------- */
.wfig{
  position:relative; aspect-ratio:16/9;
  border:var(--line) solid var(--ink); border-radius:var(--r-sticker);
  overflow:hidden; background:var(--ink);
}
.wfig iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; }
/* 视频卡的封面是**铺在按钮底下**的（按钮要盖住整块封面才点得到），
   所以按钮是 absolute。可这样一来 videoWrap 里就没有在流的子元素了，
   高度会塌成 0 —— 封面还在，只是被压成一条线，看起来像「封面没渲染」。
   所以高度得由 videoWrap 自己撑出来，比例跟封面一致。

   ⚠️ 别指望里面的 .work__cover 把父容器撑开：封面本身是 absolute 的，
   它撑不动任何人。这一条踩过，症状是视频卡只剩一个孤零零的播放圆钮。 */
.work__videoWrap{ position:relative; aspect-ratio:16/9; }
.work__play .work__cover{ position:absolute; inset:0; }
/* 封面上的那个大播放按钮：视频要「点一下才开始」，不能一进页面
   就把 B站/腾讯的播放器全加载一遍（那样首屏会拖死，还会带上对方的追踪） */
.work__play{
  position:absolute; inset:0;
  display:grid; place-items:center;
  gap:0; width:100%;
  background:transparent; border:0; cursor:pointer;
  padding:0;
}
/* ⚠️ 圆钮和它的图标必须挂在**专门的类**上，不能写成 `.work__play span` /
   `.work__play svg`。封面是塞在这个按钮里面的，封面里恰好也有 span（类型胶囊、
   时长角标）和 svg（没有封面图时的占位图形）—— 用标签选就会把它们一起抓走：
   角标被撑成 66px 白圆、白字白底看不见，占位图被压成 22px。

   这个 bug 已经犯过一次，症状是「视频卡右下角多出一个空的白圆钮」。 */
.work__playIco{
  /* position+z-index 这一对不能省：封面 .work__cover 是 absolute，
     而**定位元素一定盖在静态内容上面**，跟谁写在前面无关。
     少了这两行，圆钮会被封面整块埋掉 —— 页面上看不到它，点也点不着，
     但 DOM 里什么都对，特别难查。 */
  position:relative; z-index:1;
  display:grid; place-items:center;
  width:66px; height:66px;
  background:var(--milk);
  border:var(--line) solid var(--ink); border-radius:50%;
  box-shadow:3px 3px 0 var(--ink);
  transition:transform .16s var(--ease), box-shadow .16s var(--ease);
}
.work__playIco svg{ width:22px; height:22px; margin-left:4px; }
.work__play:hover .work__playIco{ transform:translate(-2px,-2px); box-shadow:5px 5px 0 var(--ink); }

/* 视频卡没封面时，占位图形要收掉：底下那个大播放钮已经是「这里是视频」的最强信号，
   再叠一个圆里套三角，两个播放图标摞在一起，谁也不是重点。
   黄色底留着 —— 那才是这一类的识别色，也在跟形状配合（三角 + 黄）。 */
.work__play .work__ph svg{ display:none; }
