/* ==========================================================================
   页面级样式 —— 商品页 / 下单页 / 完成页
   全站共用的部分在 site.css，这里只放这几个页面自己的版式。

   移动优先：默认样式就是手机的样子，min-width 往上加宽屏。
   90% 的访客用手机，所以手机不是「适配」，是默认。
   ========================================================================== */

/* ── 面包屑 ─────────────────────────────────────────────────── */
.crumb {
  display: flex; gap: var(--s2); flex-wrap: wrap;
  padding-block: var(--s5);
  font-size: var(--size-xs); color: var(--umber-faint);
}
.crumb a { text-decoration: none; }
.crumb a:hover { color: var(--umber); }

/* ── 下单步骤条（三页共用）─────────────────────────────────── */
.steps3 {
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s6);
  padding-block: var(--s5);
  border-bottom: 1px solid var(--line);
}
.steps3 li {
  display: flex; align-items: baseline; gap: var(--s3);
  font-size: var(--size-sm); color: var(--umber-ghost);
}
.steps3 i {
  font-style: normal; font-family: var(--face-display);
  font-size: var(--size-xs); font-variant-numeric: tabular-nums;
}
.steps3 .is-done { color: var(--umber-faint); }
.steps3 .is-done i, .steps3 .is-now i { color: var(--sienna); }
.steps3 .is-now { color: var(--umber); }
.steps3 .is-now span { border-bottom: 1px solid var(--umber); padding-bottom: 2px; }

/* ── 商品页骨架 ─────────────────────────────────────────────
   默认单列（手机）；980px 以上才两栏并让左图吸顶。      */
.pdp { display: grid; gap: var(--s8); padding-bottom: var(--s9); }
@media (min-width: 980px) {
  .pdp { grid-template-columns: 1fr 1fr; gap: var(--s10); align-items: start; }
  .pdp__media { position: sticky; top: var(--s6); }
}


.thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s3); margin-top: var(--s3); }
.thumb { padding: 0; border: 0; min-height: 44px; }   /* 44px 触摸目标 */
.thumb .plate { border-color: var(--line-soft); }
.thumb.is-on .plate { border-color: var(--umber); }
.thumb:focus-visible { outline: 2px solid var(--sienna); outline-offset: 2px; }

/* 规格表 —— 把材料讲清楚，这是「用心做」最直接的证据 */
.spec { margin-top: var(--s6); border-top: 1px solid var(--line); }
.spec > div {
  display: grid; grid-template-columns: 5.5em 1fr; gap: var(--s4);
  padding-block: var(--s3);
  border-bottom: 1px solid var(--line-soft);
  font-size: var(--size-sm);
}
.spec dt { color: var(--umber-faint); }
.spec dd { margin: 0; color: var(--umber-soft); }

.pdp__head { padding-bottom: var(--s6); border-bottom: 1px solid var(--line); }

/* ── 选项组 ─────────────────────────────────────────────────── */
.opt { border: 0; padding: 0; margin: 0; padding-block: var(--s6); border-bottom: 1px solid var(--line); }
.opt__legend {
  display: flex; align-items: baseline; gap: var(--s3);
  width: 100%; padding: 0; margin-bottom: var(--s4);
}
.opt__legend span { font-size: var(--size-xs); letter-spacing: var(--track-label); font-weight: 700; }
.opt__legend em {
  font-style: normal; font-size: var(--size-xs);
  color: var(--umber-faint); letter-spacing: .04em;
}

/* 相邻选项行共用一条边框 */
.opt__rows { display: grid; }
.opt__rows > * + * { margin-top: -1px; }

.row {
  position: relative;
  display: grid; grid-template-columns: auto 1fr auto;
  gap: var(--s4); align-items: start;
  padding: var(--s4);
  min-height: 44px;                       /* 触摸目标 */
  border: 1px solid var(--line);
  cursor: pointer; background: var(--gesso-white);
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
/* ⚠️ 这条必须包在 hover 媒体查询里。
   iOS Safari 和 Android Chrome 点击后会把 :hover 留在被点元素上直到点别处，
   而下面 .row:has(input:checked) 的底色跟它**完全相同** ——
   客人点了「16×20」再点「11×14」，屏幕上会同时有两格亚麻底，
   只差一圈 1px 边框颜色。在单选组里给出两个「已选」信号，
   是配置器最不该犯的错，而 90% 的访客用手机。 */
@media (hover: hover) and (pointer: fine) {
  .row:hover { background: var(--linen); }
}
/* 触屏没有 hover，用按下反馈补上 —— 只改底色，不做位移 */
.row:active { background: var(--linen-edge); }
.row input { position: absolute; opacity: 0; width: 0; height: 0; }

.row__box {
  width: 17px; height: 17px; margin-top: 5px;
  border: 1px solid var(--line-control);   /* 控件边界 → WCAG 1.4.11 要 3:1 */
  border-radius: var(--r-pill);
  display: grid; place-content: center;
  transition: border-color var(--t-fast) var(--ease);
}
.row__box--sq { border-radius: var(--r-sm); }
.row__box::after {
  content: ""; width: 7px; height: 7px;
  border-radius: inherit; background: var(--umber);
  transform: scale(0); transition: transform var(--t-fast) var(--ease);
}
.row input:checked ~ .row__box { border-color: var(--umber); border-width: 1.5px; }
.row input:checked ~ .row__box::after { transform: scale(1); }
.row:has(input:checked) { border-color: var(--umber); background: var(--linen); z-index: 1; }
.row:has(input:focus-visible) { outline: 2px solid var(--sienna); outline-offset: 2px; z-index: 2; }

/* 尺寸数字要等宽 —— 「8 × 10」「11 × 14」「16 × 20」左对齐排一列时，
   比例数字会让每一行的 × 号错开。价格列早就开了，
   偏偏客人先看的这一列没开。 */
.row__label { font-size: var(--size-base); line-height: 1.6; font-variant-numeric: tabular-nums; }
.row__label em {
  display: block; margin-top: 2px;
  font-style: normal; font-size: var(--size-sm);
  color: var(--umber-faint); line-height: 1.7;
}
.row__price {
  font-family: var(--face-display); font-size: var(--size-base);
  font-variant-numeric: tabular-nums; white-space: nowrap; padding-top: 2px;
}

/* 方块式选项：档位少且描述短的用这个 */
.opt__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3); }
.opt__grid--3 { grid-template-columns: repeat(3, 1fr); }
@media (min-width: 520px) {
  .opt__grid--4 { grid-template-columns: repeat(4, 1fr); }
}
.chip { position: relative; cursor: pointer; }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip__in {
  display: grid; gap: 4px; align-content: center;
  min-height: 74px; padding: var(--s3);
  border: 1px solid var(--line-control);
  background: var(--gesso-white); text-align: center;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .chip:hover .chip__in { background: var(--linen); }
}
.chip:active .chip__in { background: var(--linen-edge); }
.chip__in b {
  font-family: var(--face-display); font-weight: 500;
  font-size: var(--size-md); font-variant-numeric: tabular-nums;
  font-variation-settings: "SOFT" 20, "WONK" 1; line-height: 1.3;
}
.chip__in em {
  font-style: normal; font-size: var(--size-xs);
  color: var(--umber-faint); font-variant-numeric: tabular-nums; line-height: 1.3;
}
.chip input:checked + .chip__in {
  border-color: var(--umber); border-width: 1.5px;
  background: var(--linen); padding: calc(var(--s3) - .5px);
}
.chip input:focus-visible + .chip__in { outline: 2px solid var(--sienna); outline-offset: 2px; }

/* ── 表单控件 ───────────────────────────────────────────────── */
.field { display: block; }
.field__label { display: block; margin-bottom: var(--s2); font-size: var(--size-sm); font-weight: 600; }
.field__label i { font-style: normal; font-weight: 400; color: var(--umber-faint); margin-left: 4px; }
.field input[type=text], .field textarea {
  width: 100%; min-height: 44px; padding: var(--s3) var(--s4);
  background: var(--linen);
  border: 1px solid var(--line-control);
  border-radius: var(--r-sm);
  font-size: 16px;                     /* ★ 手机上小于 16px 会触发自动放大 */
  line-height: 1.7; resize: vertical;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.field input::placeholder, .field textarea::placeholder { color: var(--umber-ghost); }
.field input:focus, .field textarea:focus {
  /* ⚠️ 这里曾经写 outline: none —— 全站十三个下单输入框的焦点环
     就是被这一行干掉的。site.css 的 :focus-visible 在 @layer base 里，
     而 pages.css 整份不在任何 layer 内，无层样式无条件压过有层样式，
     所以那一行是必然生效的。键盘用户看不出自己在哪个框。 */
  outline: 2px solid var(--sienna); outline-offset: 2px;
  border-color: var(--umber); background: var(--gesso-white);
}

/* 上传区 */
.drop {
  display: grid; justify-items: center; gap: var(--s2);
  padding: var(--s7) var(--s5);
  border: 1.5px dashed var(--line-control); border-radius: var(--r-sm);
  background: var(--linen); text-align: center; cursor: pointer;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .drop:hover { border-color: var(--umber); background: var(--gesso-white); }
}
.drop:active { border-color: var(--umber); background: var(--gesso-white); }
.drop svg { color: var(--umber-faint); }
.drop b { font-size: var(--size-base); }
.drop em { font-style: normal; font-size: var(--size-sm); color: var(--umber-faint); line-height: 1.8; }
.drop.is-filled { border-style: solid; border-color: var(--umber); }
.drop.is-missing { border-color: var(--alert); background: var(--alert-wash); }

/* ⚠️ 报错文案曾经写在这里的 content: 里。三个问题：
   ① CSS 生成的内容不进无障碍树，读屏软件读不到 ——
      客人按了提交，得到的是完全的沉默
   ② 中文硬编码在 CSS 里，换英文时一定会漏
   ③ 靠 setTimeout 撤掉，读得慢的人会错过
   现在报错在模板里一个真实的 <p role="alert">，见 .fld__err */

/* 看得见但不占位的输入框 ——
   必须能被 Tab 聚焦，所以不能用 display:none / visibility:hidden / [hidden] */
.sr-input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
/* 焦点落在这个隐形输入框上时，把焦点环画在它外面那个可见的框上 */
.drop:has(.sr-input:focus-visible) {
  outline: 2px solid var(--sienna);
  outline-offset: 2px;
  border-color: var(--umber);
}

.fld__err {
  display: flex; align-items: flex-start; gap: var(--s2);
  margin-top: var(--s3);
  padding: var(--s3) var(--s4);
  background: var(--alert-wash);
  border-inline-start: 2px solid var(--alert);
  border-radius: var(--r-sm);
  font-size: var(--size-sm);
  color: var(--alert-deep);
  line-height: 1.7;
}
.fld__err[hidden] { display: none; }

.picked { margin-top: var(--s3); border-top: 1px solid var(--line-soft); }
.picked li {
  display: flex; justify-content: space-between; gap: var(--s4);
  padding-block: var(--s2); border-bottom: 1px solid var(--line-soft);
  font-size: var(--size-sm); color: var(--umber-soft);
}
.picked b { font-weight: 400; font-variant-numeric: tabular-nums; color: var(--umber-ghost); white-space: nowrap; }

/* ── 估价 ───────────────────────────────────────────────────── */
.quote { padding-top: var(--s6); }
.quote__sum { border: 1px solid var(--line); background: var(--gesso-white); padding: var(--s5); }
.quote__lines { display: grid; gap: var(--s2); margin-bottom: var(--s4); }
.quote__lines li {
  display: flex; justify-content: space-between; gap: var(--s4);
  font-size: var(--size-sm); color: var(--umber-soft); line-height: 1.6;
}
.quote__lines b { font-weight: 500; font-variant-numeric: tabular-nums; color: var(--umber); }
.quote__total {
  display: flex; justify-content: space-between; align-items: baseline;
  padding-top: var(--s4); border-top: 1px solid var(--line);
}
.quote__total span { font-size: var(--size-xs); letter-spacing: var(--track-label); color: var(--umber-faint); }
.quote__total b {
  font-family: var(--face-display); font-weight: 500;
  font-size: var(--size-2xl); font-variant-numeric: tabular-nums;
  font-variation-settings: "SOFT" 20, "WONK" 1;
}
.quote__note { margin-top: var(--s4); font-size: var(--size-sm); line-height: 1.8; color: var(--umber-faint); }
.btn--wide { width: 100%; justify-content: center; margin-top: var(--s5); min-height: 52px; }
.quote__alt { margin-top: var(--s4); text-align: center; font-size: var(--size-sm); color: var(--umber-faint); }

/* ── 错误提示 ───────────────────────────────────────────────── */
.alert {
  margin-top: var(--s5);
  padding: var(--s4) var(--s5);
  background: var(--alert-wash);
  border-inline-start: 2px solid var(--alert);
  border-radius: var(--r-sm);
  font-size: var(--size-sm); line-height: 1.9;
}
.alert ul { margin-top: var(--s2); }
.alert li { position: relative; padding-left: var(--s4); }
.alert li::before { content: ""; position: absolute; left: 0; top: .85em; width: 8px; height: 1px; background: var(--alert); }

/* ── FAQ ────────────────────────────────────────────────────── */
.faq { display: grid; gap: var(--s7); }
@media (min-width: 900px) { .faq { grid-template-columns: 5fr 7fr; gap: var(--s10); } }
.faq__list { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer; padding-block: var(--s5);
  min-height: 44px;
  font-size: var(--size-md); display: flex; justify-content: space-between; gap: var(--s5);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: var(--face-display); color: var(--umber-faint); flex-shrink: 0; }
.faq details[open] summary::after { content: "–"; }
.faq details p { padding-bottom: var(--s5); max-width: 34em; color: var(--umber-soft); font-size: var(--size-base); }

/* ── 手机吸底估价条 ─────────────────────────────────────────
   Fitts's Law：主行动点放在拇指够得到的地方。
   90% 的访客用手机，这一条直接影响转化。                    */
.stickybar { display: none; }
@media (max-width: 979px) {
  .stickybar {
    position: fixed; inset-inline: 0; bottom: 0; z-index: 55;
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s4);
    padding: var(--s3) var(--s5);
    padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom));  /* 避开 iPhone 底部横条 */
    background: var(--gesso-white); border-top: 1px solid var(--line-control);
  }
  .stickybar span {
    display: block; font-size: 10px; letter-spacing: var(--track-label); color: var(--umber-faint);
  }
  .stickybar b {
    font-family: var(--face-display); font-size: var(--size-lg);
    font-variant-numeric: tabular-nums; line-height: 1.3;
  }
  .dock { bottom: calc(84px + env(safe-area-inset-bottom)); }
  body { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
}

/* ==========================================================================
   下单页（第二步：收件信息）
   ========================================================================== */

.checkout { display: grid; gap: var(--s8); padding-block: var(--s7) var(--s10); }
@media (min-width: 940px) {
  .checkout { grid-template-columns: 7fr 5fr; gap: var(--s10); align-items: start; }
  .ck__side { position: sticky; top: var(--s5); }
}

.ck__h1 { font-size: var(--size-section); }
.ck__lede {
  margin-top: var(--s4); color: var(--umber-soft); max-width: 34em;
  padding-bottom: var(--s6); border-bottom: 1px solid var(--line);
}

/* ── 表单组 ─────────────────────────────────────────────────── */
.grp { border: 0; margin: 0; padding: var(--s7) 0 var(--s6); border-bottom: 1px solid var(--line); }
.grp__lg {
  padding: 0; margin-bottom: var(--s5);
  font-size: var(--size-xs); font-weight: 700; letter-spacing: var(--track-label);
}

.fld { display: block; margin-bottom: var(--s5); }
.fld--full { width: 100%; }
.fld__row { display: grid; gap: var(--s4); }
@media (min-width: 600px) {
  .fld__row { grid-template-columns: 1fr 1fr; }
  .fld__row--3 { grid-template-columns: 2fr 1fr 1fr; }
}
.fld__lb { display: block; margin-bottom: var(--s2); font-size: var(--size-sm); font-weight: 600; }
.fld__lb b { color: var(--sienna); font-weight: 600; }
.fld__lb i { font-style: normal; font-weight: 400; color: var(--umber-faint); margin-left: 4px; }
.fld__hint {
  display: block; margin-top: var(--s2);
  font-size: var(--size-xs); line-height: 1.7; color: var(--umber-faint);
}

.fld input, .fld textarea, .sel select {
  width: 100%; padding: var(--s3) var(--s4);
  min-height: 48px;                    /* 触摸目标 */
  background: var(--linen);
  border: 1px solid var(--line-control);
  border-radius: var(--r-sm);
  font-size: 16px;                     /* ★ 小于 16px 时 iOS 会自动放大页面 */
  line-height: 1.6;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.fld textarea { resize: vertical; min-height: 96px; }
.fld input::placeholder, .fld textarea::placeholder { color: var(--umber-ghost); }
.fld input:focus, .fld textarea:focus, .sel select:focus {
  /* ⚠️ 这里曾经写 outline: none —— 全站十三个下单输入框的焦点环
     就是被这一行干掉的。site.css 的 :focus-visible 在 @layer base 里，
     而 pages.css 整份不在任何 layer 内，无层样式无条件压过有层样式，
     所以那一行是必然生效的。键盘用户看不出自己在哪个框。 */
  outline: 2px solid var(--sienna); outline-offset: 2px;
  border-color: var(--umber); background: var(--gesso-white);
}
/* 只在客人真的填错并离开焦点后才标红，不要一进页面就满屏红 */
.fld input:user-invalid { border-color: var(--alert); }

/* 自建下拉外观 —— 原生 select 在样式化界面里很跳 */
.sel { position: relative; }
.sel select { appearance: none; padding-right: var(--s8); cursor: pointer; }
.sel::after {
  content: ""; position: absolute; right: var(--s4); top: 50%;
  width: 7px; height: 7px; margin-top: -5px;
  border-right: 1.5px solid var(--umber-faint);
  border-bottom: 1.5px solid var(--umber-faint);
  transform: rotate(45deg); pointer-events: none;
}

/* 勾选项 */
.chk {
  display: flex; align-items: flex-start; gap: var(--s3);
  padding-block: var(--s3); min-height: 44px;
  font-size: var(--size-base); cursor: pointer;
}
.chk input { position: absolute; opacity: 0; width: 0; height: 0; }
.chk__box {
  flex-shrink: 0; width: 17px; height: 17px; margin-top: 5px;
  border: 1px solid var(--line-control); border-radius: var(--r-sm);
  display: grid; place-content: center;
}
.chk__box::after {
  content: ""; width: 7px; height: 7px; background: var(--umber);
  transform: scale(0); transition: transform var(--t-fast) var(--ease);
}
.chk input:checked ~ .chk__box { border-color: var(--umber); border-width: 1.5px; }
.chk input:checked ~ .chk__box::after { transform: scale(1); }
.chk input:focus-visible ~ .chk__box { outline: 2px solid var(--sienna); outline-offset: 2px; }

.ck__legal {
  margin-top: var(--s6);
  font-size: var(--size-xs); line-height: 1.9; color: var(--umber-faint);
}
.ck__legal a { color: var(--umber-soft); }
.ck__legal b { color: var(--umber); }

/* ── 订单摘要 ───────────────────────────────────────────────── */
.sum { border: 1px solid var(--line); background: var(--gesso-white); padding: var(--s5); }
.sum__head { display: grid; grid-template-columns: 76px 1fr; gap: var(--s4); align-items: center; }
.sum__img { padding: 5px; }
.sum__kicker { font-size: var(--size-xs); letter-spacing: var(--track-label); color: var(--umber-faint); }
.sum__title { font-size: var(--size-lg); margin-top: 4px; }

.sum__lines {
  display: grid; gap: var(--s2);
  margin-top: var(--s5); padding-top: var(--s5);
  border-top: 1px solid var(--line);
}
.sum__lines li {
  display: flex; justify-content: space-between; gap: var(--s4);
  font-size: var(--size-sm); color: var(--umber-soft); line-height: 1.6;
}
.sum__lines b { font-weight: 500; color: var(--umber); font-variant-numeric: tabular-nums; }

.sum__total {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: var(--s4); padding-top: var(--s4); border-top: 1px solid var(--line);
}
.sum__total span { font-size: var(--size-xs); letter-spacing: var(--track-label); color: var(--umber-faint); }
.sum__total b {
  font-family: var(--face-display); font-weight: 500; font-size: var(--size-2xl);
  font-variant-numeric: tabular-nums; font-variation-settings: "SOFT" 20, "WONK" 1;
}

.sum__notes { margin-top: var(--s5); display: grid; gap: var(--s2); }
.sum__notes li {
  position: relative; padding-left: var(--s5);
  font-size: var(--size-sm); color: var(--umber-faint); line-height: 1.6;
}
.sum__notes li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 8px; height: 1px; background: var(--sienna);
}
.sum__notes b { color: var(--umber); font-weight: 600; }

.sum__back {
  display: block; margin-top: var(--s4); text-align: center;
  font-size: var(--size-sm); color: var(--umber-faint); text-decoration: none;
  min-height: 44px; padding-top: var(--s3);
}
.sum__back:hover { color: var(--umber); }

/* ==========================================================================
   完成页
   ========================================================================== */

.done { display: grid; gap: var(--s8); padding-block: var(--s8) var(--s11); }
@media (min-width: 940px) { .done { grid-template-columns: 7fr 5fr; gap: var(--s10); align-items: start; } }

.done__no {
  font-size: var(--size-xs); letter-spacing: var(--track-label);
  color: var(--umber-faint); margin-bottom: var(--s5);
}
.done__no b {
  font-family: var(--face-display); font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--umber); letter-spacing: .04em;
}
.done h1 { font-size: var(--size-display); }
.done__lede {
  margin-top: var(--s6); max-width: 34em;
  color: var(--umber-soft); line-height: var(--lead-loose);
}
.done__lede b { color: var(--umber); font-weight: 600; }

.next { margin-top: var(--s8); border-top: 1px solid var(--line); }
.next li {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s5);
  padding-block: var(--s5); border-bottom: 1px solid var(--line); align-items: baseline;
}
.next i {
  font-style: normal; font-family: var(--face-display);
  font-size: var(--size-sm); font-variant-numeric: tabular-nums; color: var(--sienna);
}
.next b { display: block; font-weight: 500; font-size: var(--size-base); }
.next span { display: block; margin-top: 4px; font-size: var(--size-sm); color: var(--umber-faint); }

/* ==========================================================================
   内容页（关于 / 法务 / FAQ）
   ========================================================================== */

.doc { display: grid; gap: var(--s8); padding-block: var(--s6) var(--s11); }
@media (min-width: 940px) {
  .doc { grid-template-columns: 240px 1fr; gap: var(--s10); align-items: start; }
  .doc__aside { position: sticky; top: var(--s6); }
  /* max-width 已提到基础规则里，这里不再重复 */
}
/* 行宽上限写在基础规则里，不能只写在 @media (min-width:940px) 内 ——
   写在里面的话，屏幕越窄行反而越长：768px 时每行约 48 个汉字，
   换英文后接近 100 字符，远超 45–75 的可读区间。
   而这是全站最长的正文（隐私政策、服务条款），且是「不许删、必须能读」的页面。 */
.doc__body { max-width: var(--measure-prose); }
.doc__head { padding-bottom: var(--s6); border-bottom: 1px solid var(--line); }
.doc__head h1 { font-size: var(--size-section); }
.doc__meta { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s7); margin-top: var(--s5); }
.doc__meta dt { font-size: var(--size-xs); letter-spacing: var(--track-label); color: var(--umber-faint); }
.doc__meta dd { margin: 3px 0 0; font-size: var(--size-sm); font-variant-numeric: tabular-nums; }

.prose { padding-top: var(--s7); }
.prose h2 {
  font-size: var(--size-lg); margin-top: var(--s8); padding-top: var(--s5);
  border-top: 1px solid var(--line-soft); scroll-margin-top: var(--s7);
}
.prose h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.prose p { margin-top: var(--s5); color: var(--umber-soft); }
/* 标题要「粘」在它引出的那一段上：
   标题到自己第一段的距离，必须小于两段正文之间的距离。
   原来两者一样大，读起来标题是浮着的、不属于任何一段（Gestalt 邻近原则）。
   列表不动 —— 列表本来就该贴着引出它的那句话。 */
.prose h2 + p, .prose h3 + p, .prose h4 + p { margin-top: var(--s4); }
.prose p b, .prose li b { color: var(--umber); font-weight: 600; }
.prose ul, .prose ol { margin-top: var(--s4); }
.prose li { position: relative; padding-left: var(--s5); margin-top: var(--s2); color: var(--umber-soft); }
.prose li::before {
  content: ""; position: absolute; left: 0; top: .85em;
  width: 9px; height: 1px; background: var(--sienna);
}

/* 空状态 / 404 */
.blank {
  display: grid; justify-items: center; gap: var(--s4);
  padding-block: var(--s11); text-align: center;
}
.blank h1 { font-size: var(--size-section); }
.blank p { max-width: 34em; color: var(--umber-soft); }

/* ── 分类页的产品卡 ────────────────────────────────────────────
   之前这里用的是 .menu，但 .menu 只定义在 home.css 里 ——
   分类页加载的是 pages.css，于是一直是个没有样式的裸列表。

   手工品类的分类页没有图，客人没法判断要不要点进去，
   所以这里给每个产品一张封面。图仍然是「实物」不是「素材」：
   沿用全站的相片白边 .plate--print。                          */
.picks {
  display: grid; gap: var(--s6);
  margin-top: var(--s6);
}
@media (min-width: 620px) { .picks { grid-template-columns: 1fr 1fr; } }
@media (min-width: 980px) { .picks { grid-template-columns: repeat(3, 1fr); } }

.picks a {
  display: grid; gap: var(--s2);
  text-decoration: none; color: inherit;
}
.picks .plate { margin-bottom: var(--s3); }
/* 必须 height:100% + object-fit —— 这条本来在 site.css 的 components 层
   写好了，但 pages.css 无层，会无声地压过它。写成 height:auto 的后果是
   格子的 aspect-ratio 还在、图却按原比例缩，横图下方空出一大块白，
   竖图被 overflow 从底部切掉 —— 每一张封面都是歪画框，
   而「图片是实物不是素材」全押在白边规整上。 */
.picks img { width: 100%; height: 100%; object-fit: cover; display: block; }

.picks b {
  font-family: var(--face-display);
  font-weight: 500; font-size: var(--size-lg);
  line-height: 1.25;
}
.picks em {
  font-style: normal; font-size: var(--size-sm);
  color: var(--umber-soft);
}
.picks .from {
  font-size: var(--size-sm);
  font-variant-numeric: tabular-nums;
  color: var(--umber-faint);
}

/* 整块可点，但只有标题加下划线 —— 整张卡都变色太吵 */
/* 名字常驻透明下划线，hover 才上色 —— 避免加边框时整行跳动 */
.picks b { border-bottom: 1px solid transparent; transition: border-color var(--t-fast) var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .picks a:hover b { border-bottom-color: var(--umber); }
}
.picks a:focus-visible {
  outline: 2px solid var(--sienna); outline-offset: 4px; border-radius: 2px;
}
@media (hover: hover) and (pointer: fine) {
  .picks a:hover .plate { border-color: var(--line-strong); }
}
.picks a:focus-visible .plate { border-color: var(--line-strong); }

/* ── 缓存指纹 v2 ─────────────────────────────────────────────
   2026-08-14：上线当天 Cloudflare 把源站的 403 页面当成 CSS 缓存了
   （CF 用 HTTPS 回源，而源站那时只监听 80，落到默认站返回 403），
   并且用 200 状态码发出去。前台整站没样式。

   源站修好后 CF 缓存已清，但**访客浏览器里那份坏的还在**。
   asset() 用文件内容的 md5 做 URL 后缀，所以在这里加一行注释
   就能换掉哈希、换掉 URL，让所有浏览器重新取。

   教训：反向代理会缓存源站的错误响应，源站修好前台不会自己恢复。 */