/* ==========================================================================
   鲜进份子 · 品牌视觉体系【知味】V2 · 岭南合璧
   --------------------------------------------------------------------------
   V1 解决的是「有没有一套能自洽的东方语言」；
   V2 解决的是「这套语言是不是只属于我们」。

   三条升级轴，对应三层不可替代性：

     A 宋骨   —— 双线、界格、题签、墨色层级。
                 宋式不是「古风」，是**克制到只剩结构**：
                 一根线、一块白、一个字的位置，都要有理由。
     B 岭南气 —— 满洲窗冰裂、趟栊横棂、骑楼柱廊、蚝壳墙颗粒。
                 这些不是贴图，是**几何**：用渐变与重复韵律画出建筑感，
                 不增加一张图片、不增加一次请求。
     C 西学用 —— 编辑网格、表格化数据、等宽数字、双语小标。
                 岭南是中国最早看世界的地方，粤菜把世界带回来；
                 版式上也一样：宋的骨架，装世界的度量衡。

   ⚠ 本文件只允许做三件事：
       1. 定义令牌（值只在这里出现一次）；
       2. 定义工具类与组件类（引用令牌，不写字面值）；
       3. 覆盖 xj.css 的局部表现（必须写清为什么）。

   ⚠ 本文件不得出现：`#hex` 形式的颜色（trad.css 生成色阶除外）、
       `margin-top:1.6rem` 这类字面间距、任何 `!important`。
       判据见 _build/vi_check.py「V2 零硬编码」三条。
   ========================================================================== */

/* ==========================================================================
   层 0 · 原始值 Primitive
   ========================================================================== */
:root {
  color-scheme: light;

  /* ---- 笔画：宋式只用三种线 ----
     界格线（最细，分栏用）、轮廓线（构件用）、强调线（朱，少用）。
     线宽不做 1.5px：在 1x 屏上会糊成 2px，在 2x 屏上又细到看不见，
     是「看起来讲究、实际不可控」的典型。 */
  --line-hair: 1px;
  --line-frame: 1px;
  --line-accent: 2px;
  --line-double-gap: 3px;      /* 双线之间的空隙：3px 是印刷双线的传统间距 */

  /* ---- 节奏刻度：0.1rem 一级 ----
     为什么另立一套，而不是复用 --sp-*：
     --sp-* 是**版式尺度**（4/8pt 主拍，用于区块与模块）；
     这里是**构件尺度**（条目内的微调，0.4–4rem）。
     两套混用会让「这个 1.4rem 到底是版式还是微调」失去判断依据。

     数值全部来自既有页面的实测写法，1:1 迁移，不改一个像素。 */
  --r-4: 0.4rem;
  --r-5: 0.5rem;
  --r-6: 0.6rem;
  --r-8: 0.8rem;
  --r-10: 1rem;
  --r-12: 1.2rem;
  --r-14: 1.4rem;
  --r-16: 1.6rem;
  --r-18: 1.8rem;
  --r-20: 2rem;
  --r-22: 2.2rem;
  --r-24: 2.4rem;
  --r-25: 2.5rem;
  --r-26: 2.6rem;
  --r-30: 3rem;
  --r-35: 3.5rem;
  --r-40: 4rem;

  /* ---- 行宽：中文一行多少字，是可以算出来的 ----
     正文 16px，中文单字宽约 1em；28–38 字/行最舒适。
     26em ≈ 26 字（短引文），34em ≈ 34 字（正文），38em ≈ 38 字（宽栏）。 */
  --measure-quote: 26em;
  --measure-body: 34em;
  --measure-wide: 38em;
  --measure-30: 30em;
  --measure-42: 42em;
  --measure-22: 22em;
  --measure-24: 24em;
  --measure-28: 28em;
  --measure-32: 32em;

  /* 块的最小高：卡片要能放下「名 + 一行说明」，低于 200px 会挤。 */
  --min-card: 200px;
  --min-card-tall: 220px;
  --min-hero: 62vh;

  /* 图形尺寸：全站只有两处写死的方形——页头印 34、首屏水印 180。 */
  --mark-sm: 34px;
  --mark-lg: 180px;

  /* ---- 材质：只做纹理，不做品牌色 ----
     岭南三种墙：蚝壳墙（白）、青砖（灰青）、夯土（暖）。
     它们永远以 ≤8% 的浓度出现，是「纸的肌理」，不是「第六个品牌色」。 */
  --mat-oyster: rgba(230, 224, 210, 0.55);
  --mat-brick: rgba(124, 138, 138, 0.18);
  --mat-earth: rgba(176, 130, 67, 0.10);

  /* ---- 装饰尺寸 ---- */
  /* ---- 流体大字：V2 把散在页面里的 clamp 收成一套刻度 ----
     原来每页各写各的 clamp(2.2rem,5vw,3.2rem)，
     同一层级的标题在三个页面上是三个大小。
     这里按「视觉体量」排队，页面只选档，不算数。 */
  --fs-d1: clamp(2.6rem, 6vw, 3.8rem);      /* 专题大标题 */
  --fs-d2: clamp(2.4rem, 5.5vw, 3.4rem);    /* 页面主标题 */
  --fs-d3: clamp(2.4rem, 5.4vw, 3.6rem);    /* 页面主标题（宽栏） */
  --fs-d4: clamp(2.2rem, 5vw, 3.2rem);      /* 区块主标题 */
  --fs-d5: clamp(2.2rem, 5vw, 3.1rem);      /* 区块主标题（窄栏） */
  --fs-d6: clamp(2rem, 4.6vw, 2.9rem);      /* 卡片群标题 */
  --fs-d7: clamp(2rem, 4.4vw, 2.8rem);      /* 卡片群标题（紧凑） */
  --fs-d8: clamp(1.9rem, 4vw, 2.6rem);      /* 小节标题 */

  --seal-sm: 1.75rem;
  --seal-md: 2.125rem;
  --lattice-cell: 14px;        /* 满洲窗格心：14px 一格，手机上也看得见 */
  --rule-col: 2.4rem;          /* 乌丝栏：每 2.4rem 一条竖界行 */
  --arcade-span: 30px;         /* 骑楼拱券跨度 */
  --arcade-rise: 14px;         /* 拱高 */

  /* ---- 动效：V2 只加一条「落款」 ---- */
  --dur-seal: 620ms;

  /* ---- 语义层：把「纸/墨/朱」翻译成「面/字/线」 ----
     写页面时想的是「这一块要比上一块低半级」，
     不是「这里该用 paper-sink 还是 ink-04」。 */
  --surface-page: var(--xj-paper);
  --surface-raise: var(--xj-paper-raise);
  --surface-sink: var(--xj-paper-sink);
  --surface-accent: var(--xj-vermilion-wash);
  --text-strong: var(--xj-ink);
  --text-body: var(--xj-ink-70);
  --text-quiet: var(--xj-ink-70);   /* V2：quiet 不再等于「淡到读不动」 */
  --text-deco: var(--xj-ink-38);
  --line-soft: var(--xj-ink-08);
  --line-mid: var(--xj-ink-16);
  --line-strong: var(--xj-ink-38);
}

/* ==========================================================================
   层 1 · 工具类 Utility
   --------------------------------------------------------------------------
   这些类的唯一职责，是把「写在标签上的样式」搬进样式表。
   命名规则：u-<族>-<刻度>，刻度与 --r-* 同名（12 = 1.2rem）。

   ⚠ 顺序即优先级：my 在 mt/mb 之前，pad 在 py/pt/pb/pl 之前。
      同一元素同时挂 u-my-14 与 u-mb-4 时，后者生效——这是刻意的，
      因为「先给上下、再单独改下」是最常见的写法。
   ========================================================================== */

/* ---- 外边距 ---- */
.u-m-0 { margin: 0; }
.u-mx-auto { margin-left: auto; margin-right: auto; }
.u-my-4 { margin-top: var(--r-4); margin-bottom: var(--r-4); }
.u-my-5 { margin-top: var(--r-5); margin-bottom: var(--r-5); }
.u-my-6 { margin-top: var(--r-6); margin-bottom: var(--r-6); }
.u-my-8 { margin-top: var(--r-8); margin-bottom: var(--r-8); }
.u-my-10 { margin-top: var(--r-10); margin-bottom: var(--r-10); }
.u-my-12 { margin-top: var(--r-12); margin-bottom: var(--r-12); }
.u-my-14 { margin-top: var(--r-14); margin-bottom: var(--r-14); }
.u-my-16 { margin-top: var(--r-16); margin-bottom: var(--r-16); }
.u-my-18 { margin-top: var(--r-18); margin-bottom: var(--r-18); }
.u-my-20 { margin-top: var(--r-20); margin-bottom: var(--r-20); }
.u-my-24 { margin-top: var(--r-24); margin-bottom: var(--r-24); }
.u-my-26 { margin-top: var(--r-26); margin-bottom: var(--r-26); }
.u-my-30 { margin-top: var(--r-30); margin-bottom: var(--r-30); }
.u-my-sp3 { margin-top: var(--sp-3); margin-bottom: var(--sp-3); }
.u-my-sp4 { margin-top: var(--sp-4); margin-bottom: var(--sp-4); }
.u-my-sp5 { margin-top: var(--sp-5); margin-bottom: var(--sp-5); }
.u-my-sp6 { margin-top: var(--sp-6); margin-bottom: var(--sp-6); }

.u-mt-0 { margin-top: 0; }
.u-mt-4 { margin-top: var(--r-4); }
.u-mt-5 { margin-top: var(--r-5); }
.u-mt-6 { margin-top: var(--r-6); }
.u-mt-8 { margin-top: var(--r-8); }
.u-mt-10 { margin-top: var(--r-10); }
.u-mt-12 { margin-top: var(--r-12); }
.u-mt-14 { margin-top: var(--r-14); }
.u-mt-16 { margin-top: var(--r-16); }
.u-mt-18 { margin-top: var(--r-18); }
.u-mt-20 { margin-top: var(--r-20); }
.u-mt-22 { margin-top: var(--r-22); }
.u-mt-24 { margin-top: var(--r-24); }
.u-mt-26 { margin-top: var(--r-26); }
.u-mt-30 { margin-top: var(--r-30); }
.u-mt-35 { margin-top: var(--r-35); }
.u-mt-40 { margin-top: var(--r-40); }
.u-mt-sp3 { margin-top: var(--sp-3); }
.u-mt-sp4 { margin-top: var(--sp-4); }
.u-mt-sp5 { margin-top: var(--sp-5); }
.u-mt-sp6 { margin-top: var(--sp-6); }
.u-mt-sp8 { margin-top: var(--sp-8); }

.u-mb-0 { margin-bottom: 0; }
.u-mb-4 { margin-bottom: var(--r-4); }
.u-mb-5 { margin-bottom: var(--r-5); }
.u-mb-6 { margin-bottom: var(--r-6); }
.u-mb-8 { margin-bottom: var(--r-8); }
.u-mb-10 { margin-bottom: var(--r-10); }
.u-mb-12 { margin-bottom: var(--r-12); }
.u-mb-14 { margin-bottom: var(--r-14); }
.u-mb-16 { margin-bottom: var(--r-16); }
.u-mb-18 { margin-bottom: var(--r-18); }
.u-mb-20 { margin-bottom: var(--r-20); }
.u-mb-22 { margin-bottom: var(--r-22); }
.u-mb-24 { margin-bottom: var(--r-24); }
.u-mb-26 { margin-bottom: var(--r-26); }
.u-mb-30 { margin-bottom: var(--r-30); }
.u-mb-sp4 { margin-bottom: var(--sp-4); }
.u-mb-sp5 { margin-bottom: var(--sp-5); }
.u-mb-sp6 { margin-bottom: var(--sp-6); }
.u-mb-sp8 { margin-bottom: var(--sp-8); }
.u-gap-10 { gap: var(--r-10); }
.u-gap-12 { gap: var(--r-12); }
.u-gap-16 { gap: var(--r-16); }
.u-gap-20 { gap: var(--r-20); }
.u-gap-30 { gap: var(--r-30); }
.u-gap-hair { gap: 1px; }

.u-w-full { width: 100%; }
.u-w-38 { width: 38%; }
.u-w-5 { width: 5%; }
.u-measure-30 { max-width: var(--measure-30); }
.u-measure-22 { max-width: var(--measure-22); }
.u-measure-24 { max-width: var(--measure-24); }
.u-measure-28 { max-width: var(--measure-28); }
.u-measure-32 { max-width: var(--measure-32); }
.u-measure-42 { max-width: var(--measure-42); }
.u-min-card { min-height: var(--min-card); }
.u-min-card-tall { min-height: var(--min-card-tall); }
.u-min-hero { min-height: var(--min-hero); }
.u-mark-sm { width: var(--mark-sm); height: var(--mark-sm); }
.u-mark-lg { width: var(--mark-lg); height: var(--mark-lg); }

.u-ml-auto { margin-left: auto; }

/* ---- 内边距 ---- */
.u-pad-0 { padding: 0; }
.u-pad-10 { padding: var(--r-10); }
.u-pad-14 { padding: var(--r-14); }
.u-pad-16 { padding: var(--r-16); }
.u-pad-18 { padding: var(--r-18); }
.u-pad-20 { padding: var(--r-20); }
.u-pad-24 { padding: var(--r-24); }
.u-pad-26 { padding: var(--r-26); }
.u-pad-sp6 { padding: var(--sp-6); }

.u-py-18 { padding-top: var(--r-18); padding-bottom: var(--r-18); }
.u-py-20 { padding-top: var(--r-20); padding-bottom: var(--r-20); }
.u-py-22 { padding-top: var(--r-22); padding-bottom: var(--r-22); }
.u-py-24 { padding-top: var(--r-24); padding-bottom: var(--r-24); }
.u-py-26 { padding-top: var(--r-26); padding-bottom: var(--r-26); }

.u-pt-0 { padding-top: 0; }
.u-pt-20 { padding-top: var(--r-20); }
.u-pt-25 { padding-top: var(--r-25); }
.u-pt-40 { padding-top: var(--r-40); }
.u-pb-0 { padding-bottom: 0; }
.u-pb-20 { padding-bottom: var(--r-20); }
.u-pb-25 { padding-bottom: var(--r-25); }
.u-pb-30 { padding-bottom: var(--r-30); }
.u-pb-35 { padding-bottom: var(--r-35); }
.u-pb-40 { padding-bottom: var(--r-40); }
.u-pl-12 { padding-left: var(--r-12); }

/* ---- 排布：一行的三种关系 ---- */
.u-flex { display: flex; }
.u-block { display: block; }
.u-none { display: none; }
.u-col { flex-direction: column; }
.u-wrap { flex-wrap: wrap; }
.u-fill { height: 100%; }
.u-flex-1 { flex: 1; min-width: 0; }
.u-items-end { align-items: end; }
.u-items-start { align-items: start; }
.u-items-center { align-items: center; }
.u-justify-between { justify-content: space-between; }
.u-justify-center { justify-content: center; }
.u-center-both { display: flex; flex-direction: column; justify-content: center; }
.u-square { aspect-ratio: 1; }
.u-sticky-rail { position: sticky; top: 120px; }

/* 卡片内的一行：两端对齐 + 竖向居中 + 可换行。
   这是全站出现最多的一种排布（24 处），单独给名字，不必拼四个类。 */
.u-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--r-20); flex-wrap: wrap;
}
.u-row-tight { gap: var(--r-16); padding: var(--r-22) 0; }

/* 细线分格：1px 的底色透出来就是网格线。
   比自己给每个格子写 border 更稳——不会出现「两个边框叠成 2px」。 */
.u-hairgrid {
  gap: var(--line-hair);
  background: var(--xj-ink-08);
  border: var(--hair);
}
.u-hairgrid > * { background: var(--xj-paper-raise); }

.u-plain { border: 0; background: none; padding: 0; }
.u-bg-none { background: none; }
.u-grid { display: grid; }
.u-relative { position: relative; }
.u-absolute { position: absolute; }
.u-clip { overflow: hidden; }
.u-scroll { overflow: auto; }
.u-scroll-x { overflow-x: auto; }
.u-min-0 { min-width: 0; }
.u-pointer { cursor: pointer; }
.u-fs-normal { font-style: normal; }
.u-hei { font-family: var(--font-hei); }
.u-song { font-family: var(--font-song); }
.u-latin { font-family: var(--font-latin); }
.u-r-xs { border-radius: var(--r-xs); }
.u-r-sm { border-radius: var(--r-sm); }
.u-r-md { border-radius: var(--r-md); }
.u-ink-deco { color: var(--xj-ink-16); }

/* 节气卡：底色与色标由同一枚 --hc 驱动。
   原来底色是 5 个手写的 #hex14，色标是另一个色——
   同一张卡上两个颜色不是同一个来源，是「看着差不多」的凑法。 */
.v2-wash { background: var(--xj-primary-wash); }
@supports (background: color-mix(in srgb, red 8%, transparent)) {
  .v2-wash { background: color-mix(in srgb, var(--hc) 8%, transparent); }
}
.v2-hc { background: var(--hc); }


/* ---- 字体与文字 ---- */
.u-fs-11 { font-size: var(--fs-11); }
.u-fs-12 { font-size: var(--fs-12); }
.u-fs-13 { font-size: var(--fs-13); }
.u-fs-14 { font-size: var(--fs-14); }
.u-fs-16 { font-size: var(--fs-16); }
.u-fs-18 { font-size: var(--fs-18); }
.u-fs-20 { font-size: var(--fs-20); }
.u-fs-25 { font-size: var(--fs-25); }
.u-fs-31 { font-size: var(--fs-31); }
.u-fs-39 { font-size: var(--fs-39); }
.u-fs-49 { font-size: var(--fs-49); }
.u-fs-61 { font-size: var(--fs-61); }
.u-fs-d1 { font-size: var(--fs-d1); }
.u-fs-d2 { font-size: var(--fs-d2); }
.u-fs-d3 { font-size: var(--fs-d3); }
.u-fs-d4 { font-size: var(--fs-d4); }
.u-fs-d5 { font-size: var(--fs-d5); }
.u-fs-d6 { font-size: var(--fs-d6); }
.u-fs-d7 { font-size: var(--fs-d7); }
.u-fs-d8 { font-size: var(--fs-d8); }

.u-lh-tight { line-height: var(--lh-tight); }
.u-lh-title { line-height: var(--lh-title); }
.u-lh-snug { line-height: var(--lh-snug); }
.u-lh-body { line-height: var(--lh-body); }
.u-lh-loose { line-height: var(--lh-loose); }
.u-lh-16 { line-height: 1.6; }
.u-lh-17 { line-height: 1.7; }
.u-lh-18 { line-height: 1.8; }
.u-lh-20 { line-height: 2; }

.u-track-14 { letter-spacing: 0.14em; }
.u-track-16 { letter-spacing: 0.16em; }
.u-track-18 { letter-spacing: 0.18em; }

.u-ta-r { text-align: right; }
.u-ta-c { text-align: center; }

.u-measure-quote { max-width: var(--measure-quote); }
.u-measure-body { max-width: var(--measure-body); }
.u-measure-wide { max-width: var(--measure-wide); }

/* ---- 颜色：只用语义名，不写色值 ---- */
.u-surface { background: var(--surface-raise); }
.u-surface-sink { background: var(--surface-sink); }
.u-vermilion { color: var(--xj-vermilion); }
.u-ink { color: var(--text-strong); }
.u-ink-quiet { color: var(--text-body); }

/* ⚠ V2 的显式决定：原 ink-38 (2.1:1) 不再用于任何文字。
   需要「退后一级」时用字号/字重，不靠把字调淡到读不动。
   这条有判据：vi_check 会拦 color: var(--xj-ink-38)。 */

/* ---- 中文排印细节（V2）----
   ① text-spacing-trim：全角标点收边。
      中文段落里的句号、逗号占一个字宽，收边之后段落不再「散」——
      这是中文排版的基本功，浏览器现在能做。
   ② hanging-punctuation：行首标点悬挂（Safari 支持，其它浏览器忽略）。
   ③ overflow-wrap：超长英文/网址不撑破容器。
   这三条都不改变字形，只改**间距**，但读起来的差别很大。 */
h1, h2, h3, h4, p, li, td, th, dd, dt, .lede, .hero-sub, .muted, .small {
  text-spacing-trim: normal;
  hanging-punctuation: allow-end;
}
body { overflow-wrap: anywhere; }

/* ==========================================================================
   层 2 · 组件 Component
   ========================================================================== */

/* ---- 转型叙事（从 A 到 B）----
   四段式封装：事前准备 → 体验 → 反思 → 整合。
   只写我们真实在做的事；没有做的，不写。 */
.v2-journey {
  padding: var(--sp-16) 0;
  border-top: var(--line-hair) solid var(--line-soft);
}
.v2-journey-hd { max-width: var(--measure-body); margin-bottom: var(--sp-8); }
.v2-journey-hd h2 {
  font-size: var(--fs-31); line-height: var(--lh-title);
  margin: var(--r-8) 0 var(--r-6);
}
.v2-journey-list {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--sp-4);
}
.v2-journey-step {
  border: var(--line-hair) solid var(--line-mid);
  background: var(--surface-raise);
  padding: var(--r-16);
}
.v2-journey-no {
  display: block; font-family: var(--font-hei); font-size: var(--fs-13);
  letter-spacing: 0.2em; color: var(--xj-vermilion); margin-bottom: var(--r-6);
}
.v2-journey-t {
  display: block; font-family: var(--font-song); font-weight: 400;
  font-size: var(--fs-18); letter-spacing: 0.06em; margin-bottom: var(--r-6);
}
.v2-journey-d {
  margin: 0; font-size: var(--fs-13); line-height: var(--lh-body);
  color: var(--text-body);
}
.v2-journey-note { margin-top: var(--sp-6); }

/* ---- 意图层（2026-10-30）----
   四个最常被问的问题。对人是导航，对机器是 ItemList。
   每张卡都带一行「依据」——AI 时代，品牌被选中靠的不是被看见，
   是**可被核验**：节气怎么算的、价格什么口径、批次能不能查。 */
.v2-intent { padding-bottom: var(--sp-12); }
.v2-intent-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-4);
}
.v2-intent-card {
  border: var(--line-hair) solid var(--line-mid);
  background: var(--surface-raise);
  padding: var(--r-18);
  display: flex; flex-direction: column; gap: var(--r-10);
  transition: background var(--dur) var(--ease);
}
.v2-intent-card:hover { background: var(--xj-primary-wash); }
.v2-intent-q {
  font-size: var(--fs-25); line-height: var(--lh-title);
  letter-spacing: 0.04em; margin: 0;
}
.v2-intent-a {
  font-size: var(--fs-14); color: var(--text-body); line-height: 1.8; margin: 0;
}
.v2-intent-ev {
  margin-top: auto; padding-top: var(--r-10);
  border-top: var(--line-hair) dashed var(--line-soft);
  font-size: var(--fs-12); color: var(--text-body); line-height: 1.7;
}
.v2-intent-ev b {
  font-family: var(--font-hei); font-weight: 400; letter-spacing: 0.12em;
  color: var(--xj-vermilion); margin-right: var(--r-8);
}
.v2-intent-go {
  font-family: var(--font-hei); font-size: var(--fs-12);
  letter-spacing: 0.12em; color: var(--xj-vermilion);
}
.v2-intent-note { margin-top: var(--sp-8); }
.v2-intent-note code {
  font-family: var(--font-hei); font-size: var(--fs-12);
  color: var(--xj-vermilion);
}

/* ---- 题签 Kicker ----
   宋版书的「书耳」：一小条竖栏，标这一块是什么。
   比 eyebrow 更轻，不占一整行。 */
.v2-kicker {
  display: inline-flex; align-items: center; gap: var(--r-8);
  font-family: var(--font-hei); font-size: var(--fs-12);
  letter-spacing: 0.18em;
  color: var(--text-body);
  padding-left: var(--r-8);
  border-left: var(--line-accent) solid var(--xj-vermilion);
  line-height: 1.4;
}

/* ---- 匾额 Plaque ----
   双线细框：外 1px，内 1px，中间隔 3px。
   宋式建筑匾额的「子母框」，也是书籍装帧的经典做法。 */
.v2-plaque {
  display: inline-block;
  padding: var(--r-10) var(--r-18);
  border: var(--line-frame) solid var(--line-mid);
  box-shadow: inset 0 0 0 var(--line-double-gap) var(--surface-page),
              inset 0 0 0 calc(var(--line-double-gap) + var(--line-frame)) var(--line-soft);
  font-family: var(--font-song); font-size: var(--fs-18);
  letter-spacing: 0.12em; color: var(--text-strong);
}

/* ---- 乌丝栏 Ruled ----
   宋版书的界行是**竖线**，不是横线。用在长文栏里，
   每 2.4rem 一条，浓度 4%——只让「行」有形，不做装饰。 */
.v2-ruled {
  background-image: repeating-linear-gradient(
    to right,
    var(--line-soft) 0, var(--line-soft) var(--line-hair),
    transparent var(--line-hair), transparent var(--rule-col)
  );
}

/* ---- 印 Seal ----
   朱文小印。字少、框厚、留白足。
   全站只在「此刻」「限定」「落款」三处出现——多了就成装饰。 */
.v2-seal {
  display: inline-grid; place-items: center;
  width: var(--seal-md); height: var(--seal-md);
  border: var(--line-accent) solid var(--xj-vermilion);
  color: var(--xj-vermilion);
  font-family: var(--font-song); font-size: var(--fs-12);
  letter-spacing: 0.08em; line-height: 1;
  background: var(--xj-vermilion-wash);
}

/* ---- 编号 Index ----
   西式编辑设计的「编号」+ 中式卷次的「第几」。
   等宽数字是硬要求：不等宽会让竖排的编号参差。 */
.v2-index {
  font-family: var(--font-latin, var(--font-song));
  font-size: var(--fs-12); letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  color: var(--text-body);
}

/* ---- 双语小标 Bilingual ----
   上一行中文，下一行拉丁。字距拉开，字号压小。
   「名从主人」：中文在前，拉丁是注解，不是并列。 */
.v2-bilingual { display: flex; flex-direction: column; gap: var(--r-4); }
.v2-bilingual b {
  font-family: var(--font-song); font-weight: 400;
  font-size: var(--fs-18); letter-spacing: 0.08em;
}
.v2-bilingual span {
  font-family: var(--font-hei); font-size: var(--fs-11);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--text-body);
}

/* ---- 边注 Note ----
   页边的一条细线 + 小字。用来放「口径」「来源」「免责」。
   这些字必须能读到，所以颜色用 70 档，不压到 38。 */
.v2-note {
  border-left: var(--line-accent) solid var(--line-mid);
  padding-left: var(--r-12);
  font-size: var(--fs-12); line-height: var(--lh-loose);
  color: var(--text-body);
}

/* ---- 图版 Figure ----
   照片进「版」：外框 1px，内衬一圈纸色（8px），
   照片与框之间留白——这是画册的做法，也是宋画的装裱法。 */
.v2-figure {
  padding: var(--r-8);
  border: var(--line-frame) solid var(--line-mid);
  background: var(--surface-page);
}
.v2-figure > img, .v2-figure > svg { display: block; width: 100%; height: auto; }

/* ---- 满洲窗 Lattice ----
   冰裂纹的简化：两组 45° 斜线交错。
   只用渐变，不引图片；浓度 4%，是「窗的影子」不是「窗」。 */
.v2-lattice {
  background-image:
    repeating-linear-gradient(45deg,
      var(--line-soft) 0, var(--line-soft) var(--line-hair),
      transparent var(--line-hair), transparent var(--lattice-cell)),
    repeating-linear-gradient(-45deg,
      var(--line-soft) 0, var(--line-soft) var(--line-hair),
      transparent var(--line-hair), transparent var(--lattice-cell));
}

/* ---- 骑楼 Arcade ----
   一连串半圆拱。做区块之间的「檐下」，高度只有 14px。
   用在页脚顶部：从内容走到页脚，像从街上走进骑楼底。 */
.v2-arcade {
  height: var(--arcade-rise);
  background-image: radial-gradient(
    circle at 50% 0,
    transparent calc(var(--arcade-rise) - var(--line-accent)),
    var(--line-mid) calc(var(--arcade-rise) - var(--line-accent)),
    var(--line-mid) calc(var(--arcade-rise) - var(--line-hair)),
    transparent calc(var(--arcade-rise) - var(--line-hair)));
  background-size: var(--arcade-span) var(--arcade-rise);
  background-repeat: repeat-x;
}

/* ---- 蚝壳墙 Ochre ----
   蚝壳砌墙是岭南独有的做法：壳面反光，远看是一层细密的亮点。
   用两层 radial-gradient 做颗粒，浓度极低——它是纸的肌理。 */
.v2-ochre {
  background-color: var(--surface-sink);
  background-image:
    radial-gradient(circle at 20% 30%, var(--mat-oyster) 0 1px, transparent 1px),
    radial-gradient(circle at 70% 60%, var(--mat-brick) 0 1px, transparent 1px);
  background-size: 7px 7px, 11px 11px;
}

/* ---- 编辑表格 Editorial table ----
   数据要像数据：表头小字距、数字等宽、行线只在需要处。 */
.v2-table { width: 100%; border-collapse: collapse; font-size: var(--fs-14); }
.v2-table th {
  font-family: var(--font-hei); font-weight: 400; font-size: var(--fs-12);
  letter-spacing: 0.14em; color: var(--text-body);
  text-align: left; padding: var(--r-10) var(--r-12);
  border-bottom: var(--line-frame) solid var(--line-mid);
  white-space: nowrap;
}
.v2-table td {
  padding: var(--r-10) var(--r-12);
  border-bottom: var(--line-hair) solid var(--line-soft);
  font-variant-numeric: tabular-nums;
}
.v2-table tbody tr:hover td { background: var(--surface-raise); }

/* ---- 引文 Quote ----
   宋式引文不加巨大引号，只加一条朱线。
   引号是西式的强调，朱线是批注的传统。 */
.v2-quote {
  margin: 0; padding-left: var(--r-18);
  border-left: var(--line-accent) solid var(--xj-vermilion);
  font-family: var(--font-song); font-size: var(--fs-25);
  line-height: var(--lh-title); color: var(--text-strong);
}
.v2-quote cite {
  display: block; margin-top: var(--r-12);
  font-family: var(--font-hei); font-style: normal;
  font-size: var(--fs-12); letter-spacing: 0.14em; color: var(--text-body);
}

/* ==========================================================================
   层 3 · 全站覆盖 Override
   --------------------------------------------------------------------------
   只改「一眼能看出是同一套体系」的地方，不改结构、不改节奏。
   ========================================================================== */

/* ---- 页头：双线 ----
   一根线是「分隔」，两根线是「装裱」。
   第二根线用 box-shadow 画，不占高度，不影响 sticky 定位。 */
.site-head {
  border-bottom: var(--line-frame) solid var(--line-mid);
  box-shadow: 0 var(--line-double-gap) 0
              calc(-1 * (var(--line-double-gap) - var(--line-hair)))
              var(--line-soft);
}

/* ---- 题签：eyebrow 左端加朱线 ----
   原来是一条通到底的灰线（::after），像分隔符；
   加一条 2px 朱线，它才成为「这一块的签」。 */
.eyebrow {
  border-left: var(--line-accent) solid var(--xj-vermilion);
  padding-left: var(--r-10);
}
.eyebrow::after {
  background: linear-gradient(90deg, var(--line-mid), transparent);
}

/* ---- 水印：离卦必须是「线」，不是「块」 ----
   原来的水印用 320px 宽的 SVG 承载 32 单位视图里的 2 单位描边，
   放大 10 倍后每根线变成 20px 粗的三条横杠——在浅色纸上看着像三块占位图。
   改成 non-scaling-stroke：无论放到多大，永远是 1px 的细线。
   这是乌丝栏的逻辑：靠线的密度表达大小，不靠线的粗细。 */
.watermark .mark-line {
  vector-effect: non-scaling-stroke;
  stroke-width: 1;
}
.watermark .mark-bud { vector-effect: non-scaling-stroke; }

/* ---- 印：朱文方印 ----
   原 .hero-seal 只有一层淡红底，像一块没对齐的色块。
   V2 给它四边实线 + 字距更松 + 宋体：它要看起来像一枚「印」，
   而不是一段带底色的文字。 */
.hero-seal {
  font-family: var(--font-song);
  letter-spacing: 0.26em;
  background: var(--xj-vermilion-wash);
  border: var(--line-hair) solid var(--xj-vermilion-line, rgba(168, 57, 46, 0.32));
  padding: var(--r-6) var(--r-12);
}
.hero-seal::before { width: var(--r-16); background: var(--xj-vermilion); }

/* ---- 标题 ----
   balance 让中文标题不会出现「最后一个字单独一行」。
   Safari/Chrome 已支持；不支持的浏览器忽略该声明，无副作用。 */
h1, h2, h3, .hero h1 { text-wrap: balance; }
p, .lede, .muted { text-wrap: pretty; }

/* ---- 数字 ----
   价格、编号、日期、表格：一律等宽。
   不等宽的数字在竖排里会「跳」，这是表格看起来不齐的真正原因。 */
.hero-meta dd, .price, .num, .v2-index,
.tbl-cat td, .v2-table td, .sku-price, .order-no {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ---- 页脚：骑楼檐下 ----
   到页脚之前先过一排拱。这是全站唯一一处「建筑」，
   放在页脚，是因为页脚本来就是「走出来」的地方。 */
.site-foot { position: relative; padding-top: 5rem; }
.site-foot::before {
  content: "";
  position: absolute; inset: 0 0 auto 0;
  height: var(--arcade-rise);
  background-image: radial-gradient(
    circle at 50% 0,
    transparent calc(var(--arcade-rise) - var(--line-accent)),
    var(--line-mid) calc(var(--arcade-rise) - var(--line-accent)),
    var(--line-mid) calc(var(--arcade-rise) - var(--line-hair)),
    transparent calc(var(--arcade-rise) - var(--line-hair)));
  background-size: var(--arcade-span) var(--arcade-rise);
  background-repeat: repeat-x;
  opacity: 0.7;
  pointer-events: none;
}

/* ---- 品牌家族：按条数分列 ----
   早先首页用 flex 让四个品牌「按内容宽度」自然排，结果是：
   刚须占半宽、它的三张卡挤成 2+1，右半空一大块；
   下面两组又错位，看上去像少了一张卡。

   现在列宽由**条数**决定：
     刚须 3 条 → 占 3 列；繁离 3 条 → 占 3 列
     拾分盏 2 条 → 占 2 列；端酱 1 条 → 占 1 列
   一行正好 3 列排满，最后一组的三张卡连成一行，
   每张卡压在自家品牌题下——与题头行对称。

   组的列跨度用类名给（brand-span-1/2/3），不用行内样式：
   行内样式是这个项目 V2 起禁掉的东西。 */
.brand-groups {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: var(--line-hair) solid var(--line-mid);
  border-left: var(--line-hair) solid var(--line-mid);
}
.brand-groups > .brand-group {
  grid-column: span var(--span, 3);
  border-right: var(--line-hair) solid var(--line-mid);
  border-bottom: var(--line-hair) solid var(--line-mid);
  min-width: 0;
}
.brand-groups > .brand-group > .brand-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  border-left: 0;
  border-top: 0;
}
.brand-groups > .brand-group > .brand-row > .brand-item:last-child {
  border-right: 0;
}
.brand-span-1 { --span: 1; }
.brand-span-2 { --span: 2; }
.brand-span-3 { --span: 3; }

/* ---- 选择与焦点 ----
   选中态用朱色极浅的一层，不反白：反白会打断阅读位置。
   焦点环必须有：键盘用户靠它知道自己在哪。 */
::selection { background: var(--xj-vermilion-wash); color: var(--text-strong); }
:focus-visible {
  outline: var(--line-accent) solid var(--xj-vermilion);
  outline-offset: var(--line-double-gap);
  border-radius: var(--r-xs);
}

/* ---- 滚动条 ----
   默认滚动条在浅色纸上是一条突兀的灰。
   细一点、淡一点，它才不抢版面。 */
* { scrollbar-width: thin; scrollbar-color: var(--xj-mist) transparent; }

/* ---- 图片底色 ----
   图片未加载时不要闪白：先铺纸色，加载完再显影。 */
img { background-color: var(--surface-sink); }

/* ---- 触控区：视觉可以小，热区不能小 ---- */
.btn, .head-login, .foot-list a, .tl-item { touch-action: manipulation; }

/* ==========================================================================
   层 4 · 响应式 Responsive
   --------------------------------------------------------------------------
   原则只有一条：密型条目按最小宽组排（见 --item-w-*），
   疏型卡片才允许单列。V2 的判据会按「实际生效的列数」检查。
   ========================================================================== */

@media (max-width: 640px) {
  /* 页脚檐口在窄屏上跨度收小，否则拱券会被裁成半截 */
  :root { --arcade-span: 24px; --lattice-cell: 12px; }

  /* 匾额在窄屏上不换行、不撑破 */
  .v2-plaque { font-size: var(--fs-16); padding: var(--r-8) var(--r-12); }
}

/* 超宽屏：内容上限不动，但把边距交给视口，避免两侧空白过大 */
@media (min-width: 1680px) {
  :root { --edge: clamp(2.5rem, 5vw, 4rem); }
}

/* ==========================================================================
   层 5 · 降级 Degradation
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
    transition-duration: 0.01ms;
    scroll-behavior: auto;
  }
}

@media (forced-colors: active) {
  .v2-plaque, .v2-seal, .v2-figure, .v2-note { border-color: CanvasText; }
  .v2-kicker { border-left-color: CanvasText; }
}

@media print {
  .site-foot::before, .v2-arcade { display: none; }
  .v2-figure { border-color: #000; }
}

/* ---- 品牌家族：窄屏回到单列 ----
   桌面靠「按条数分列」把三张卡连成一行；
   窄屏若照搬，卡会窄到 115px——一行挤三个字宽的条目，读不了。
   所以 ≤720px 回到单列：组一列、卡一列，和早先一致。 */
@media (max-width: 720px) {
  .brand-groups { grid-template-columns: minmax(0, 1fr); }
  .brand-groups > .brand-group { grid-column: 1 / -1; }
  .brand-groups > .brand-group > .brand-row { grid-template-columns: minmax(0, 1fr); }
}

/* ---- 页脚：手机端改成两列，链接自己铺满 ----
   早先 ≤640px 把 .foot-top 压成一列，于是每组链接竖着排一长条，
   右边空着大半屏，要滑两屏才看得完底。
   现在：分组两列，组内链接再按最小宽自动铺——链接自己填满宽度。 */
@media (max-width: 640px) {
  .foot-top {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--r-20) var(--sp-6);
  }
  .foot-top > .foot-brand { grid-column: 1 / -1; }
  /* 链接自己铺满整行：两列（够放「刚须 · 鲜果」这种 7 字条目），
     宽度再多就自动加列——不是写死两列。 */
  .foot-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: var(--sp-2) var(--sp-4);
  }
  .foot-list li { margin-bottom: 0; }
  .foot-h { margin-bottom: var(--r-8); }
}

/* ==========================================================================
   V2 · 字体与排印 Type System（2026-10-30）
   --------------------------------------------------------------------------
   这一段解决三件事——都是真机上看得见的问题：

   ① 同一个词里两种字形
      字库是 2026-10-04 建的；之后文案新增了约 380 个字，
      这些字不在子集里 → 掉回系统字体 →「爱的邂逅卡」四个字两种脸。
      对策：字库重建到全量覆盖（fonts_build.py）+ 判据常态化（vi_check 查覆盖率）。

   ② 展示体用在了小字上
      Cormorant Garamond 笔画极细、字腔开阔，是**展示体**。
      放在 10–12px 的节气拼音、编号、时间上，手机上几乎看不清。
      对策：Cormorant 只用于 ≥16px 的数字与英文名；
            小字号拉丁改用思源黑体自带的拉丁字形（与中文同源、笔画更实）。

   ③ 拉丁体里混进了中文
      .hou-n 写的是「一候」「二候」，却挂着 --font-latin（没有中文字形）
      → 中文字掉回系统字体 → 又是两种脸。
      对策：含中文的元素一律用中文字族；
            并且所有字体栈都补上 CJK 兜底——即使漏了，也不掉到系统字体。

   ④ 中文最小字号 12px
      10/11px 在中文里不是「小」，是「看不清」。
      苹果 HIG 与 WCAG 都把 11px 以下视为不可读区。
      改法见 _build/type_v2.py（把写死的 10/11px 换成 12px 令牌）。
   ========================================================================== */

:root {
  /* 拉丁栈补 CJK 兜底：即使有元素误用拉丁字体，
     里面的中文字也会落到我们的宋体，而不是系统字体。 */
  --font-latin: "Cormorant Garamond", "Noto Serif SC", "Songti SC",
    "Noto Serif CJK SC", "Times New Roman", Georgia, serif;
}

/* ---- ② 小字号的拉丁：改用黑体的拉丁 ----
   黑体的拉丁笔画更实，小字号站得住；
   字距从 0.06–0.08em 提到 0.12em，字母才不挤成一团。 */
.tl-date, .agent-n, .cell-time, .shichen-time, .lang,
.tier-range, .flow-n, .card-idx {
  font-family: var(--font-hei);
  letter-spacing: 0.12em;
}
.card-idx { letter-spacing: 0.1em; }
.tl-date, .cell-time, .shichen-time { letter-spacing: 0.08em; }

/* ---- ③ 含中文的元素：回到宋体 ---- */
.hou-n {
  font-family: var(--font-song);
  letter-spacing: 0.16em;
}

/* 中文内容的元素不许挂拉丁展示体：
   「行人」「6 母 6 公」「鲜进份子（母品牌）」这类整段中文，
   挂拉丁体只会有两个后果——字距按西文算（0.2em 的中文会散架），
   字形靠兜底（虽然现在兜到我们的宋体，但语义是错的）。 */
.tier-grade, .v2-index, .u-latin {
  font-family: var(--font-song);
}
/* 中英混排的数字行：数字用黑体（笔画实、小字站得住），单位字同族 */
.xie-spec, .nav-extra-lang, .lang {
  font-family: var(--font-hei);
}

/* ---- 数字：旧式数字在价格与表格里会跳 ----
   Cormorant 默认是 old-style figures（3、4、7、9 会下沉），
   在价格位与表格里看着像没对齐。统一改成等高数字 + 等宽。 */
.num, .sku-price, .stat-n, .tier-grade, .card-idx, .hou-n,
.serif-latin, .tl-date, .cell-time, .shichen-time {
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}

/* ---- ④ 中文最小字号 12px（覆盖层，源头在 type_v2.py） ---- */
.tl-season-tag, .agent-cat, .card-visual-tag, .chip { font-size: var(--fs-12); }
