/* ============================================================
   I CHING — The Twelve · magazine feature stylesheet
   ------------------------------------------------------------
   十二生肖长文页共用这一份。每页在 <html> 上写死 --ec（该生肖的五行色），
   整篇的强调色（小节序号、图号、首字下沉、标本卡标签）都跟着它走，
   金色 --gold 留给品牌层（报头、引语、发丝线）。

   排版系统（刻意避开 AI 通感字体）：
     展示层  Cormorant Garamond —— 高对比、细笔画，大字号下有印刷质感
     正文层  Newsreader         —— 为长文阅读设计的老式衬线，斜体极佳
     功能层  Archivo            —— 中立无衬线，只做眉题/图注/元信息的小字
     汉字层  Noto Serif SC

   2026-09-30 排版升级（「左右对齐 + 再高级一点」）：
     · 正文两端对齐 + 自动断词（门槛 5 2 2，扫描选定）+ 孤行寡行控制
     · 首字下沉从「1.83 行」修正为**精确的 3 行**（按字体度量反推，见下方公式）
     · 小节标题：量度上方的发丝线 + 「Section NN」（标题上方独立一行，齐版心左缘）
     · 标本卡改成真正的表格版式（每格上方发丝线 + 等宽数字）
     · 图注加发丝线；标签层从「全大写」换成**小型大写字母**
   实测确认「写了但当前不生效」的两条，都不当成卖点（详见下方各自注释）：
     · hanging-punctuation —— Chrome 系不支持，仅 Safari 17.4+ 生效
     · 正文 oldstyle-nums —— 属性支持，但 Newsreader 不带 onum，无效果
   ============================================================ */

:root{
  /* 纸与墨：不用纯黑纯白 */
  --ink:#050710;
  --ink2:#090b16;
  --plate:#0c0e1a;
  --ink3:#12151f;

  --text:#c3cade;
  --text-hi:#e0e4ef;
  --muted:#8b95ab;
  --muted2:#6d7688;

  --gold:#c9b98a;
  --gold-hi:#e8dfc0;
  --gold-mid:#b8a97e;
  --gold-lo:#8a7f57;

  --line:rgba(148,137,94,.20);
  --line2:rgba(148,137,94,.44);
  --rule:rgba(195,202,222,.13);
  /* 更弱的一档发丝线：用在表格内部分隔、图注上沿这类「结构线」上，
     比 --rule 再退一步，不会和内容抢注意力。 */
  --hair:rgba(195,202,222,.085);

  --display:"Cormorant Garamond",Georgia,"Times New Roman",serif;
  --body:"Newsreader",Georgia,"Times New Roman",serif;
  --util:"Archivo","Helvetica Neue",system-ui,sans-serif;
  --cjk:"Noto Serif SC",Georgia,serif;

  /* 量度：正文栏宽。620px 在 18px Newsreader 下约 70 字符，杂志舒适区。 */
  --measure:620px;
  --mast-h:58px;
  /* 版心左右留白。破版图版靠它算出到视口边缘的距离 —— 刻意不用 vw，
     见 .fig--wide 的注释。 */
  --pad:26px;

  /* 指数缓动：不用回弹/弹性 */
  --ease:cubic-bezier(.16,1,.30,1);      /* easeOutExpo 近似 */
  --ease-q:cubic-bezier(.25,1,.50,1);    /* easeOutQuart 近似 */
}

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

/* 破版图版（.fig--wide）是 100vw 宽，横向由这里兜住。
   🔴 用 clip 而不是 hidden：overflow:hidden 会造出滚动容器，把报头的
   position:sticky 一并废掉；clip 不造滚动容器，sticky 照常。 */
html{-webkit-text-size-adjust:100%;overflow-x:hidden}
@supports(overflow-x:clip){html{overflow-x:clip}}
body{
  margin:0;
  background:var(--ink);
  color:var(--text);
  font-family:var(--body);
  font-size:16px;
  line-height:1.5;
  /* 字距调整与连字：Cormorant / Newsreader 都带完整的 kern 与标准连字表，
     打开后长文的小字密排会明显干净。 */
  font-kerning:normal;
  font-variant-ligatures:common-ligatures contextual;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
::selection{background:rgba(201,185,138,.28);color:var(--gold-hi)}

/* 键盘可达性 */
a:focus-visible,button:focus-visible{
  outline:1px solid var(--gold-hi);outline-offset:3px;border-radius:2px}

/* ============================================================
   正文排版核心 —— 左右对齐（全篇正文都用这一组）
   ------------------------------------------------------------
   620px 量度配 18px 衬线，**不断词的两端对齐一定会出「白河」**
   （词间距被拉到 1.5 倍以上，竖着看像几条白缝）。
   所以断词、悬挂标点、孤寡行控制是一套的，不能只取对齐那一行。

   <html lang="en"> 已在构建脚本里写死 —— hyphens:auto 依赖它，
   没有 lang 的话浏览器不知道用哪套断词规则，会直接不断。
   ============================================================ */
.lede p,
.sec p,
.standfirst{
  text-align:justify;
  text-justify:inter-word;
  hyphens:auto;
  -webkit-hyphens:auto;
  /* 只在「词长 ≥5 字、断点前 ≥2 字、断点后 ≥2 字」时才允许断。
     🔴 这个值不是拍脑袋来的 —— 用 tune-justify.js 扫过
     hyphenate-limit-chars ∈ {6 3 2, 5 2 2, 4 2 2} × 栏宽 ∈ {620,640,660}：
       6 3 2 @620 → 平均词距 ×1.329，过松行 9.2%，>2.0 占 4.1%
       5 2 2 @620 → 平均词距 ×1.298，过松行 6.1%，>2.0 占 2.0%   ← 取这组
       4 2 2 @620 → 与 5 2 2 完全一致（4 字词没有合法断点，再放宽无收益）
     放宽不会断出非法音节：Chrome 用**词典**断词，这个属性只是把词典里
     合法的断点按长度过滤掉 —— 放宽 = 少过滤，不是自己乱断。 */
  hyphenate-limit-chars:5 2 2;
  /* 连续两行都断词会排成阶梯状，限制成最多 2 行（WebKit 专有，其余浏览器忽略） */
  hyphenate-limit-lines:2;
  /* 避免末行只剩一个孤词 */
  text-wrap:pretty;
  /* 引号、逗号、句号探出版心 —— 西文印刷的经典手法。
     🔴 实测（brave-ctl/audit-features.js，Chrome/150）：**Chrome 系根本不支持这个属性** ——
        CSS.supports('hanging-punctuation','first') 两个值都是 false，
        getComputedStyle 回读 undefined。也就是说在 Brave/Chrome 里写了等于没写。
     ✅ 但 Safari 17.4+ / iOS Safari 17.4+ 确实支持（caniuse 官方数据，
        全球约 14.5% 流量）—— 海外站 iOS 占比不低，所以**保留**，
        定位是「Safari 专属渐进增强」，**不计入本轮的升级清单**。
     ⚠️ 断言千万别写成「computed 值等于 first last」—— 那是一条自己造出来的假失败。
        正确断言是：本浏览器**要么支持、要么明确不支持**（见 verify-justify-all.js）。 */
  hanging-punctuation:first last;
  orphans:2;
  widows:2;
  /* 旧式数字。
     ⚠️ 实测（audit-features.js）：这里有两层，别混为一谈 ——
        ① CSS.supports('font-variant-numeric','oldstyle-nums') = **true**，
           Chrome 是认这个属性的；
        ② 但**字体** Newsreader 不带 onum —— 「0123456789」在 60px 下，
           oldstyle-nums 与 lining-nums 宽度都是 339.9px，差 0.00px，特性没被应用。
     所以这一行**目前是空设置**（属性支持 × 字体不支持 = 无效果）。
     留着只为将来换字体时能自动生效，别把它当卖点。
     （真正用上等宽数字的是标本卡 dd：'1111111111' 等宽 339.9px vs 比例 225.6px，那个是有效的。） */
  font-variant-numeric:oldstyle-nums proportional-nums;
}

/* ============================================================
   阅读进度条 —— transform:scaleX（绝不写 width，避免每帧强制布局）
   ============================================================ */
.prog{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:70;
  background:linear-gradient(90deg,var(--gold-lo),var(--gold-hi));
  transform:scaleX(0);transform-origin:0 50%;
  will-change:transform;
}

/* ============================================================
   报头
   ============================================================ */
.mast{
  position:sticky;top:0;z-index:60;
  background:rgba(5,7,16,.80);
  backdrop-filter:blur(14px) saturate(1.1);
  -webkit-backdrop-filter:blur(14px) saturate(1.1);
  border-bottom:1px solid var(--line);
}
.mast-in{
  max-width:1180px;margin:0 auto;padding:0 var(--pad);
  height:var(--mast-h);
  display:flex;align-items:center;justify-content:space-between;gap:16px;
}
.mast-brand{
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--util);font-size:.66rem;font-weight:600;
  letter-spacing:.30em;text-transform:uppercase;color:var(--gold);
  white-space:nowrap;
}
.mast-brand .dm{
  width:6px;height:6px;flex:0 0 6px;background:var(--gold);transform:rotate(45deg);
}
.mast-sec{
  font-family:var(--util);font-size:.62rem;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:var(--muted2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.back{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--util);font-size:.63rem;font-weight:500;
  letter-spacing:.18em;text-transform:uppercase;color:var(--muted);
  border:1px solid var(--line);border-radius:999px;
  padding:7px 14px;white-space:nowrap;
  transition:color .3s var(--ease),border-color .3s var(--ease),background .3s var(--ease);
}
.back:hover{color:var(--gold-hi);border-color:var(--line2);background:rgba(201,185,138,.06)}
.back .bk-s{display:none}
/* 报头右侧：中文入口 + 返回键 成一组。
   原来 mast-in 是 space-between 的三段（品牌 / 期号 / 返回），
   直接塞第四个孩子会被推到中间去。 */
.mast-end{display:flex;align-items:center;gap:10px}
/* 「中文」用汉字自己标自己 —— 语言入口的通行做法。
   lang="zh-Hans" 让读屏按中文念，hreflang 告诉爬虫这是个中文页面。 */
.zh{
  display:inline-flex;align-items:center;text-decoration:none;
  font-family:var(--cjk);font-size:.74rem;letter-spacing:.06em;
  color:var(--muted);border:1px solid var(--line);border-radius:999px;
  padding:6px 12px;white-space:nowrap;line-height:1;
  transition:color .3s var(--ease),border-color .3s var(--ease),background .3s var(--ease);
}
.zh:hover{color:var(--gold-hi);border-color:var(--line2);background:rgba(201,185,138,.06)}

/* ============================================================
   HERO —— 满幅 16:9 大图 + 叠压在图上方的标题块
   ============================================================ */
.hero{position:relative}
/* 首屏要能同时容下大图 + 标题 + 导语引文 + 署名。
   16:9 在 1440 宽是 810px，加报头就顶到 868，标题块叠压后署名会被推到折线以下；
   压到 72vh 后整组在 1000px 视口内落齐。
   🔴 `width:100%` 绝对不能省。
   2026-09-29 实测踩过：这个盒子同时有 `aspect-ratio:3/2`（手机断点）和
   `min-height:380px`，而宽度是 auto。内容高度（390/1.5=260）低于 min-height
   时，高度被钉成 380 就成了**确定值**，浏览器随即拿比例**反推宽度**
   → 380 × 3/2 = 570。整页横向溢出 180px，移动端初始布局视口被撑到 570。
   给死宽度后，比例只用来算高，min/max-height 只管夹高，宽度不再被反推。 */
.hero-plate{
  position:relative;margin:0;overflow:hidden;width:100%;
  aspect-ratio:16/9;max-height:72vh;min-height:min(52vh,440px);
  background:var(--ink2);
}
.hero-plate img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center 46%;
}
/* 底部压暗，给叠压的标题让出可读底；顶部只压一点点，保住画面 */
.hero-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(5,7,16,.62) 0%,rgba(5,7,16,.10) 22%,rgba(5,7,16,0) 42%,
    rgba(5,7,16,.44) 68%,rgba(5,7,16,.86) 88%,rgba(5,7,16,.97) 100%);
}
.hero-head{
  position:relative;z-index:2;
  max-width:1180px;margin:-118px auto 0;padding:0 var(--pad) 0;
}
.kicker{
  display:block;margin:0 0 20px;
  font-family:var(--util);font-size:.72rem;font-weight:600;
  letter-spacing:.16em;font-variant-caps:all-small-caps;color:var(--gold);
}
.kicker .k-rule{
  display:inline-block;width:46px;height:1px;background:var(--gold-lo);
  vertical-align:middle;margin-right:14px;transform-origin:0 50%;
}
.kicker .k-cn{
  font-family:var(--cjk);font-size:.92rem;letter-spacing:.06em;
  color:var(--gold-hi);font-weight:400;font-variant-caps:normal;
}
/* 大图右上角的图注（走 .hero-plate 的 <figcaption>） */
.hero-credit{
  position:absolute;top:20px;right:24px;z-index:2;margin:0;
  max-width:min(330px,42%);text-align:right;
  font-family:var(--body);font-style:italic;font-size:.79rem;line-height:1.5;
  color:rgba(205,212,230,.60);
}
/* 标题：每个词一个 .w 遮罩，JS 让内层 i 从下方升起 —— 印刷式的逐词落版 */
.h1{
  margin:0;font-family:var(--display);font-weight:400;
  font-size:clamp(2.45rem,7.4vw,6.1rem);
  line-height:1.02;letter-spacing:-.022em;
  color:var(--text-hi);text-wrap:balance;
  hanging-punctuation:first last;   /* Safari 渐进增强，Chrome 系无效，见正文块注释 */
}
.h1 .w{display:inline-block;overflow:hidden;vertical-align:bottom;
  padding-bottom:.14em;margin-bottom:-.14em}
.h1 .w i{display:inline-block;font-style:inherit;font-weight:inherit}
.standfirst{
  margin:26px 0 0;max-width:44ch;
  font-family:var(--body);font-style:italic;font-weight:300;
  font-size:clamp(1.04rem,1.55vw,1.28rem);line-height:1.62;
  color:rgba(195,202,222,.94);
}
.byline{
  margin:30px 0 0;display:flex;flex-wrap:wrap;align-items:center;gap:14px;
  font-family:var(--util);font-size:.70rem;font-weight:500;
  letter-spacing:.13em;font-variant-caps:all-small-caps;color:var(--muted2);
}
.byline .sep{width:4px;height:4px;background:var(--gold-lo);transform:rotate(45deg);flex:0 0 4px}
.hero-rule{
  height:1px;background:linear-gradient(90deg,var(--line2),rgba(148,137,94,0));
  margin:44px 0 0;transform-origin:0 50%;
}

/* ============================================================
   正文流
   ============================================================ */
.flow{padding:0 var(--pad)}
.measure{max-width:var(--measure);margin-left:auto;margin-right:auto}

/* 导语：字号略大、颜色略亮，首字下沉 */
.lede{padding:56px 0 0}
.lede p{
  margin:0;
  font-size:clamp(1.1rem,1.5vw,1.26rem);line-height:1.66;
  color:var(--text-hi);
}
.lede p + p{margin-top:1.15em;font-size:clamp(1.02rem,1.3vw,1.14rem);color:var(--text)}

/* ------------------------------------------------------------
   首字下沉 —— 精确 3 行，按字体度量反推（2026-09-30 修正）
   ------------------------------------------------------------
   原来写 3.9em / .78，实测**只占 1.83 行**（注释写 3 行是错的）。
   float 的首字下沉，占几行由「行盒高度 ÷ 正文字行高」决定，
   而字母看起来多大由 cap-height 决定 —— 两件事必须分开解。

   实测度量（canvas fontBoundingBox* / actualBoundingBoxAscent）：
     Cormorant Garamond  A=.924  D=.287  cap=.625
     Newsreader          A=.735  D=.265  cap=.676
   导语行高比 R = 1.66。

   ① 下沉字基线要落在正文第 3 行的基线上：
        line3 = Fb·[(R-(An+Dn))/2 + An] + 2·R·Fb = 4.385·Fb
        drop  = Fd·[(L-(Ac+Dc))/2 + Ac]        = Fd·0.6835   (L=.735)
      ⇒ Fd = 6.42·Fb        → 6.42em
   ② 行盒高度必须 >2 行且 ≤3 行，正文才会绕排 3 行：
        L·Fd = .735 × 6.42 = 4.72em = 4.72/1.66 = 2.84 行 ✓
   ③ 大写顶与正文首行大写顶对齐（Fd·0.0608 ≈ 0.390·Fb vs 正文 0.389·Fb）✓

   三个条件同时满足，且全部是**比值**，所以任意视口下都成立。
   改导语行高（R）或换字体，这组数必须重算 —— 别只改字号。 */
.lede p.has-dropcap::first-letter{
  float:left;
  font-family:var(--display);font-weight:400;font-style:normal;
  font-size:6.42em;
  line-height:.735;
  color:var(--gold-hi);
  padding:0 .07em 0 0;
  margin:0;
}

/* ============================================================
   小节
   ============================================================ */
.body{padding:0 0 8px}
.sec{margin-top:3.2em}
.sec:first-child{margin-top:2.4em}
/* 量度上方一条发丝线 + 标题不与下文分离 —— 杂志的小节分栏感 */
.sh{
  margin:0 0 .9em;padding-top:1.05em;
  border-top:1px solid var(--hair);
  font-family:var(--display);font-weight:400;
  font-size:clamp(1.5rem,2.85vw,2.05rem);line-height:1.16;
  letter-spacing:-.006em;color:var(--text-hi);
  text-wrap:balance;
  break-after:avoid;
}
/* ------------------------------------------------------------
   🔴 「Section NN」**不再挂进版心外的白边**（2026-09-30 撤掉）。
   ------------------------------------------------------------
   原来在 ≥1100px 用 float + margin-left:-158px 把序号推到 x=252，
   正文左缘在 x=410 —— 杂志里常见的「分栏标注」做法。

   撤掉的原因：老板原话「电脑端的内文和小图 要么左对齐 要么右对齐，
   不然看起来很不整齐」。实测整篇左边线当时有**三档**：

       小节序号 252   /   竖图 340   /   正文·标题·图注 410

   竖图那 70px 探出已经改掉了（见 .fig--side 的注释）。序号这一档也一起收回，
   于是全篇只剩**一条**左边线。序号现在是标题上方独立一行、齐版心左缘
   —— 也就是下面这套基础样式，所有断点通用。

   ⚠️ 别再把它挂回白边。真要恢复，先想清楚会不会又造出第二条左边线。
   ------------------------------------------------------------ */
.sh-n{
  display:block;margin-bottom:.62em;
  font-family:var(--util);font-size:.68rem;font-weight:600;
  letter-spacing:.17em;font-variant-caps:all-small-caps;color:var(--ec);
}
.sh-n::before{
  content:"";display:inline-block;width:20px;height:1px;
  background:var(--ec);vertical-align:middle;margin-right:11px;opacity:.85;
}
.sec p{
  margin:0 0 1.28em;
  font-size:clamp(1.03rem,1.28vw,1.15rem);line-height:1.74;
  color:var(--text);
}
.sec p:last-child{margin-bottom:0}
.sec p > em{font-style:italic;color:var(--text-hi)}
.sec p > strong{font-weight:500;color:var(--text-hi)}
.cn{font-family:var(--cjk);font-weight:400;letter-spacing:.02em}

/* ------------------------------------------------------------
   宽屏：**原来这里把「Section NN」挂到版心外的白边里** —— 2026-09-30 撤掉，
   原因见上方 .sh-n 的注释（整篇左边线出现三档，老板要求收回对齐）。
   这块 @media(min-width:1100px) 覆盖已整体删除，序号在所有断点都用基础样式。
   ------------------------------------------------------------ */

/* ============================================================
   标本卡 —— 该生肖的六项属性，横向展布
   ------------------------------------------------------------
   2026-09-30：从「六段文字」升级成真正的**表格版式** ——
   每格上方一条发丝线，数字走等宽对齐。 */
.specimen{
  position:relative;overflow:hidden;
  max-width:1080px;margin:64px auto 8px;padding:30px 0 32px;
  border-top:1px solid var(--line2);border-bottom:1px solid var(--line2);
  background:linear-gradient(180deg,rgba(201,185,138,.035),rgba(201,185,138,0));
}
.spec-glyph{
  position:absolute;right:4px;top:50%;transform:translateY(-50%);
  font-family:var(--cjk);font-size:clamp(4.4rem,7.2vw,6.6rem);line-height:1;
  color:rgba(201,185,138,.075);pointer-events:none;user-select:none;
}
.spec-k{
  margin:0 0 22px;position:relative;z-index:1;
  font-family:var(--util);font-size:.68rem;font-weight:600;
  letter-spacing:.20em;font-variant-caps:all-small-caps;color:var(--gold);
}
.spec-grid{
  position:relative;z-index:1;margin:0;
  display:grid;grid-template-columns:repeat(6,1fr);gap:22px 18px;
}
.spec-grid > div{
  min-width:0;
  border-top:1px solid var(--hair);
  padding-top:11px;
}
.spec-grid dt{
  font-family:var(--util);font-size:.64rem;font-weight:500;
  letter-spacing:.13em;font-variant-caps:all-small-caps;color:var(--muted2);
  margin-bottom:7px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.spec-grid dd{
  margin:0;font-family:var(--body);font-size:.97rem;line-height:1.35;
  color:var(--text-hi);
  /* 表格里数字要对齐 → 等宽数字，不用旧式 */
  font-variant-numeric:lining-nums tabular-nums;
}

/* ============================================================
   图版
   ============================================================ */
.fig{margin:3.1em 0}
.fig img{
  width:100%;height:auto;border-radius:2px;
  background:var(--ink3);
}
.figcap{
  display:flex;gap:12px;align-items:baseline;
  margin-top:13px;padding-top:11px;
  border-top:1px solid var(--hair);
}
.figcap b{
  font-family:var(--util);font-size:.65rem;font-weight:600;
  letter-spacing:.14em;font-variant-caps:all-small-caps;color:var(--ec);
  white-space:nowrap;flex:0 0 auto;
}
.figcap span{
  font-family:var(--body);font-style:italic;font-size:.88rem;
  line-height:1.5;color:var(--muted);
  text-wrap:pretty;
}

/* 竖幅：**与正文栏共用一条边**（左图齐左缘、右图齐右缘）。
   🔴 原来给 img 加了 margin-right:-70px（右图）/ margin-left:-70px（左图），
      把它挂进版心外的白边，看上去更「杂志」。但实测（brave-ctl/probe-side2.js，
      滚到图、等揭示动画结算后量）结果是两条边都不靠版心：

        右图 670..1100 → Δ右 = +70，左缘离版心 260
        左图 340..770  → Δ左 = −70，右缘离版心 260

      于是整篇出现了三条互不重合的左边线（小节序号 252 / 竖图 340 / 正文 410），
      老板原话：「要么左对齐 要么右对齐，不然看起来很不整齐」。改成齐版心后，
      竖图至少有一条边和正文严丝合缝。
      ⚠️ 手机端本来就没这个问题 —— 窄屏把竖图改成 100% 宽、正好齐版心。
      改这里不用动媒体查询。 */
.fig--side{margin:3.4em 0}
.fig--side img{width:min(430px,100%)}
.fig--side-r img{margin-left:auto;margin-right:0}
.fig--side-l img{margin-right:auto;margin-left:0}
.fig--side-r .figcap{margin-left:auto;margin-right:0;max-width:430px}
.fig--side-l .figcap{margin-right:auto;margin-left:0;max-width:430px}

/* 横幅：整屏破版。
   🔴 这里绝对不能用 `width:100vw; margin:calc(50% - 50vw)`。
   2026-09-29 实测：移动端模拟（mobile:true）下，vw 是按**初始包含块**算的，
   而初始包含块又要等布局结束才定 —— 于是和浏览器的 shrink-to-fit 形成循环，
   页面**初始布局视口被撑到 570px**（真机 390），要等用户滚一下才回落。
   症状极具迷惑性：探针里 `scrollWidth - innerWidth` 一直是 0（因为视口自己变宽了），
   只有直接断言 innerWidth 才能戳穿。
   改成「从 .flow 的左右内边距反向撑出去」——纯 px，无循环。 */
.fig--wide{margin:4em calc(-1 * var(--pad));overflow:hidden}
.fig--wide img{border-radius:0;max-height:88vh;object-fit:cover}
/* 🔴 破版图必须 overflow:hidden。
   入场动效给 img 的初始态是 scale:1.055，390 宽 × 1.055 = 411 —— 两边各探出
   10.5px，整页 scrollWidth 从 390 变 400，移动端就又出现横向可滚区。
   顺带这也是「推近式揭示」该有的遮罩：图片在框内放大，而不是溢出到框外。
   ⚠️ 不要把这行挪到通用的 .fig 上 —— 竖幅图靠 margin-right:-70px 故意挂进
   版心外的白边，父级一旦 overflow:hidden 就会把那 70px 裁掉。 */
.fig--wide .figcap{
  max-width:calc(var(--measure) + 2 * var(--pad));
  margin:13px auto 0;padding:11px var(--pad) 0;
}

/* ============================================================
   引语
   ============================================================ */
.pull{
  margin:3.6em auto;padding:0;
  max-width:min(860px,100%);text-align:center;
}
/* 两端收淡的渐变发丝线 —— 比一条实线高级，也不会把引语「框」起来 */
.pull .p-rule{
  display:block;width:96px;height:1px;
  background:linear-gradient(90deg,rgba(148,137,94,0),var(--gold-lo),rgba(148,137,94,0));
  margin:0 auto;transform-origin:50% 50%;
}
.pull blockquote{
  margin:34px 0;padding:0;
  font-family:var(--display);font-style:italic;font-weight:300;
  font-size:clamp(1.48rem,3.35vw,2.42rem);line-height:1.26;
  letter-spacing:-.010em;color:var(--gold-hi);text-wrap:balance;
  hanging-punctuation:first last;   /* Safari 渐进增强，Chrome 系无效，见正文块注释 */
}
.pull .p-attr{
  margin:0;font-family:var(--util);font-size:.66rem;font-weight:500;
  letter-spacing:.22em;font-variant-caps:all-small-caps;color:var(--muted2);
}

/* ============================================================
   篇末：上下篇
   ============================================================ */
.endmatter{
  margin-top:88px;padding:0 var(--pad);
  border-top:1px solid var(--line);
}
.endmatter-in{
  max-width:1180px;margin:0 auto;padding:38px 0 96px;
  display:flex;justify-content:space-between;gap:24px;
}
.pn{display:block;max-width:46%;min-width:0}
.pn-k{
  display:block;margin-bottom:9px;
  font-family:var(--util);font-size:.65rem;font-weight:600;
  letter-spacing:.20em;font-variant-caps:all-small-caps;color:var(--muted2);
}
.pn-v{
  display:block;font-family:var(--display);font-weight:400;
  font-size:clamp(1.22rem,2.2vw,1.72rem);line-height:1.16;color:var(--text-hi);
  transition:color .3s var(--ease);
}
.pn:hover .pn-v{color:var(--gold-hi)}
.pn:hover .pn-k{color:var(--gold)}
.pn-n{display:block;margin-top:7px;font-family:var(--cjk);font-size:.9rem;color:var(--muted2)}
.pn--next{text-align:right;margin-left:auto}
.pn--none{visibility:hidden}

/* ============================================================
   响应式
   ============================================================ */
@media(max-width:1000px){
  .spec-grid{grid-template-columns:repeat(3,1fr);gap:24px 18px}
  .hero-head{margin-top:-92px}
}
@media(max-width:760px){
  :root{--mast-h:52px;--pad:18px}
  .mast-sec{display:none}
  .back .bk-l{display:none}
  .back .bk-s{display:inline}
  .mast-end{gap:8px}
  .zh{padding:5px 10px;font-size:.70rem}
  .hero-plate{aspect-ratio:3/2;min-height:min(46vh,380px);max-height:none}
  .hero-plate img{object-position:center 42%}
  .hero-credit{display:none}
  .hero-head{margin-top:-58px}
  .hero-rule{margin-top:32px}
  .standfirst{margin-top:20px}
  .byline{margin-top:22px}
  .lede{padding-top:40px}
  /* 所有图版在窄屏一律回落到版心内，不做负外边距（会横向溢出） */
  .fig--side img,
  .fig--side-r img,
  .fig--side-l img{margin-left:0;margin-right:0;width:100%}
  .fig--side-r .figcap,
  .fig--side-l .figcap{margin-left:0;margin-right:0;max-width:none}
  .specimen{margin-top:48px}
  .spec-glyph{font-size:6.4rem;right:-10px;opacity:.8}
  .endmatter-in{padding-bottom:72px;gap:16px}
  .pn{max-width:50%}
}
@media(max-width:520px){
  .spec-grid{grid-template-columns:repeat(2,1fr)}
  .h1{letter-spacing:-.014em}
  .pull blockquote{margin:26px 0}
  /* 窄屏栏宽只有 ~354px，3 行下沉字会吃掉三成宽度 —— 回到 2 行。
     🔴 3.73em / .775 是**解出来**的，不是估的：用 brave-ctl/solve-dropcap.js
        在浏览器里二分收敛（实测 capDelta = −0.04px），行盒占 1.743 行 ∈ (1,2]。
     ⚠️ 这里原来写的是 `4.30em / .775`，实测 capDelta = **+6.18px** ——
        下沉字大写高比理想位置低了 6px，肉眼看得出来。
        而原来那条注释推的是「Fd = Fb·[(2R+0.676)/0.625] = Fb·6.40」：
        公式用的是 3 行解（2R），值写的却是 4.30 —— **公式和值互相对不上**，
        正是「注释一套、代码另一套」的典型。已一并修正。
     求解器在桌面复现了已知解（6.41em vs CSS 的 6.42em），所以结论可信。 */
  .lede p.has-dropcap::first-letter{font-size:3.73em;line-height:.775}
  /* 🔴 窄栏必须退回左对齐 —— 这是**量出来**的结论，不是审美偏好。
     justify 在窄栏里会把行尾缺额摊到很少的几个词距上，表现成肉眼可见的「白河」。
     实测（brave-ctl/measure-justify.js，rat 页，量的是「相邻词空隙 ÷ 字体自然空格」）：

       视口   内容宽   平均词距   过松行(>1.8×)
       760    620px    ×1.32       6.7%
       640    588px    ×1.27       2.2%
       520    484px    ×1.38       6.1%
       480    444px    ×1.48      13.3%   ← 开始劣化
       430    394px    ×1.47      18.2%
       390    354px    ×1.60      31.7%   ← 已经不能看
       370    334px    ×1.51      20.3%

     ⚠️ 试过用「放宽 hyphenate-limit-chars」救：5 2 2 → 4 2 2 → 3 2 2 → 2 2 2，
        390px 下过松行占比**一模一样 31.7%**（行数也都是 164）——
        断词确实在触发（设 hyphens:none 会多 3 行），但窄栏里它能提供的新断点
        根本用不上。**救不回来，只能整段退回左对齐**：
        宁可右缘参差，也不要词距被拉开 3 倍。
     判据：内容宽 ≤ ~484px（视口 520）是安全边界，再窄就劣化。 */
  .lede p,.sec p,.standfirst{text-align:left;text-justify:auto}
}

/* ============================================================
   减弱动态效果：整页按静态排版呈现。
   注意：本文件任何地方都不写 opacity:0 —— 初始态一律由 JS 现场设，
   这样无 JS / GSAP 挂掉 / 用户开减弱动效时，内容永远完整可见。
   ============================================================ */
@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
}

/* 打印 */
@media print{
  .mast,.prog,.endmatter,.fig--wide{display:none}
  body{background:#fff;color:#111}
  .hero-plate{max-height:none}
  /* 打印时两端对齐 + 断词保持，但去掉深色底 */
  .lede p,.sec p,.standfirst{color:#111}
}
