/* ══════════════════════════════════════════════════════════
   qiuyiwu.com 设计系统 · 组件层
   依赖 tokens.css + base.css。不依赖 styles.css。

   ⚠️ 加载本文件的页面【不要】再加载 /styles.css：
      两边都定义 .nav / .wrap / .hero / .icon-btn / .book / .note /
      .sec-head / .nav-links / .hero-grid / .hero-cta 共 10 个同名类，
      同时加载时谁赢只取决于标签顺序。

   收编记录（2026-08-05）：
   - 8 个 *-v3.html 各自内联 66–193 行 CSS，78 个选择器重复，其中 50 个
     已经漂移（.wrap 1080/1180、.nav 透明度 .9/.92、.nav-in gap 30/28、
     .nav-links a padding 15/14、.ws-btn:hover 三个版本…）。
   - 15 个卡片类（.art .ocard .plat .book .prod .dcard .lcard .mcard
     .pcard .qcard .tcard .post .mp .lstep .role）底色与描边完全相同，
     只有圆角（11/13/14/16/18px）和 hover 位移（-2/-3/-4/-5px）随机不同。
     全部收敛到 .ds-card + 三档尺寸 + 一种 hover。
   ══════════════════════════════════════════════════════════ */


/* ═══ 1. 布局 ═══════════════════════════════════════════ */

.ds-wrap {
  max-width: var(--v-max);
  margin: 0 auto;
  padding: 0 var(--v-gutter);
}

.ds-section {
  padding: var(--sp-21) 0;
  border-top: 1px solid var(--v-line);
}
.ds-section:first-of-type { border-top: none; }


/* ═══ 2. 导航 ═══════════════════════════════════════════ */

.ds-nav {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--v-bg) 92%, transparent);
  -webkit-backdrop-filter: blur(18px);
          backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--v-line);
}
/* color-mix 不支持时的兜底（Safari < 16.2 等） */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .ds-nav { background: var(--v-bg); }
}

.ds-nav-in {
  max-width: var(--v-max); margin: 0 auto;
  padding: 14px var(--v-gutter);
  display: flex; align-items: center; gap: 28px;
}

.ds-brand {
  font-family: var(--v-font-cn-serif);
  font-size: 19px; font-weight: 600; letter-spacing: .04em;
  color: var(--v-ink); white-space: nowrap;
}
.ds-brand span {
  font-family: var(--v-font-mono); font-size: 9.5px; letter-spacing: .28em;
  color: var(--v-ink3); margin-left: 9px; text-transform: uppercase; font-weight: 400;
}

.ds-nav-links { display: flex; gap: 2px; margin-left: 6px; }
.ds-nav-links a {
  font-size: 14.5px; font-weight: 500; color: var(--v-ink2);
  padding: 7px 14px; border-radius: var(--r-pill);
  transition: background-color var(--t-fast), color var(--t-fast);
}
.ds-nav-links a:hover { background: var(--v-bg3); color: var(--v-ink); }
.ds-nav-links a[aria-current="page"] { color: var(--v-ink); background: var(--v-bg3); }

.ds-nav-right { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }


/* ── 移动端菜单 ────────────────────────────────────────
   ⚠️ 修复 P0：此前 8 页统一写 @media(max-width:980px){.nav-links{display:none}}
      却没有任何替代入口，窄屏下六个主栏目完全不可达。 */

.ds-nav-toggle { display: none; }   /* 宽屏隐藏，窄屏由下面的 media query 打开 */

.ds-nav-panel {
  display: none;
  border-top: 1px solid var(--v-line);
  background: var(--v-bg);
  padding: var(--sp-2) var(--v-gutter) var(--sp-4);
}
.ds-nav-panel a {
  display: block; padding: 13px 4px;
  font-size: 16px; font-weight: 500; color: var(--v-ink2);
  border-bottom: 1px solid var(--v-line);
}
.ds-nav-panel a:last-child { border-bottom: none; }
.ds-nav-panel a[aria-current="page"] { color: var(--v-accent); font-weight: 600; }
.ds-nav[data-open="true"] .ds-nav-panel { display: block; }

@media (max-width: 980px) {
  .ds-nav-links { display: none; }
  .ds-nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; border-radius: 50%;
    border: 1px solid var(--v-line); color: var(--v-ink2);
    transition: border-color var(--t-fast), color var(--t-fast);
  }
  .ds-nav-toggle:hover { border-color: var(--v-accent); color: var(--v-accent); }
  .ds-nav-in { gap: var(--sp-4); }
}


/* ═══ 3. 按钮 ═══════════════════════════════════════════ */

.ds-btn {
  display: inline-block;
  padding: 12px 26px; border-radius: var(--r-pill);
  font-size: 14.5px; font-weight: 600; white-space: nowrap;
  transition: background-color var(--t-base), border-color var(--t-base),
              color var(--t-base), transform var(--t-base), box-shadow var(--t-base);
}

/* 主按钮：前景走 --v-on-accent，暗色下会自动翻成深墨。
   写死 #fff 在暗色 accent（#E08A72）上只有 2.61:1。 */
.ds-btn--primary {
  background: var(--v-accent); color: var(--v-on-accent);
  box-shadow: 0 2px 8px var(--v-accent-soft);
}
.ds-btn--primary:hover {
  background: var(--v-accent-hover);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px var(--v-accent-soft);
}

.ds-btn--ghost { border: 1.5px solid var(--v-line2); color: var(--v-ink); }
.ds-btn--ghost:hover { border-color: var(--v-accent); color: var(--v-accent); }

/* 工作台入口：主按钮 + 状态点 */
.ds-btn--app { display: inline-flex; align-items: center; gap: 7px; padding: 9px 19px; font-size: 14px; }
.ds-btn--app .ds-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; opacity: .9; flex: none;
}

.ds-icon-btn {
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--v-line); color: var(--v-ink2);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px;
  transition: border-color var(--t-fast), color var(--t-fast);
}
.ds-icon-btn:hover { border-color: var(--v-accent); color: var(--v-accent); }


/* ═══ 4. 区块头 ═════════════════════════════════════════ */

.ds-sec-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-6); flex-wrap: wrap;
}
.ds-sec-label {
  font-family: var(--v-font-mono); font-size: 11px; letter-spacing: .26em;
  color: var(--v-accent); text-transform: uppercase; font-weight: 500;
  margin-bottom: 14px;
}
.ds-sec-title {
  font-size: var(--fs-h2); font-weight: 600; line-height: 1.32;
  margin: 0 0 var(--sp-3); letter-spacing: .01em;
}
.ds-sec-lede {
  font-size: var(--fs-lede); color: var(--v-ink2);
  max-width: var(--v-read); line-height: var(--lh-loose);
  margin: 0 0 34px;
}
.ds-more {
  font-size: 14.5px; font-weight: 600; color: var(--v-accent);
  white-space: nowrap; padding-bottom: 2px;
  border-bottom: 1.5px solid transparent;
  transition: border-color var(--t-fast);
}
.ds-more:hover { border-bottom-color: var(--v-accent); }

/* 强调词。中文不斜体，靠颜色 + 字重区分。 */
.ds-hl { color: var(--v-accent); font-weight: 700; font-style: normal; }


/* ═══ 5. 卡片（唯一的卡片组件）═══════════════════════════ */

.ds-card {
  background: var(--v-card);
  border: 1px solid var(--v-line);
  border-radius: var(--r-md);
  box-shadow: var(--v-shadow);
  padding: var(--sp-5) var(--sp-6);
  display: block;
  transition: border-color var(--t-base), transform var(--t-base), box-shadow var(--t-base);
}
/* 一种 hover，全站统一：描边转 accent + 上浮 2px + 阴影加深。
   此前 15 个卡片类用了 -2/-3/-4/-5px 五种位移，没有任何依据。 */
a.ds-card:hover,
.ds-card--interactive:hover {
  border-color: var(--v-accent);
  transform: translateY(-2px);
  box-shadow: var(--v-shadow-lg);
}
/* 横向列表项用平移而非上浮，避免长列表整体抖动 */
a.ds-card--row:hover { transform: translateX(3px); }

.ds-card--sm  { border-radius: var(--r-sm); padding: var(--sp-4) var(--sp-5); }
.ds-card--lg  { border-radius: var(--r-lg); padding: 28px var(--sp-6); }
.ds-card--flush { padding: 0; overflow: hidden; }     /* 图片打头的大卡 */
.ds-card--quiet { background: var(--v-bg2); box-shadow: none; }  /* 嵌入式面板 */

.ds-card-title { font-size: var(--fs-h3); font-weight: 600; margin: 0 0 10px; }
.ds-card-desc  { font-size: var(--fs-sm); color: var(--v-ink2); line-height: 1.72; margin: 0; }
.ds-card-go    { font-size: 13px; font-weight: 600; color: var(--v-accent); margin-top: var(--sp-4); }

/* mono 微标签：卡片里的分类 / 年份 / 单位 */
.ds-meta {
  font-family: var(--v-font-mono); font-size: var(--fs-micro);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--v-ink3); font-weight: 500;
}
.ds-meta--accent { color: var(--v-accent); }


/* ═══ 6. 场景徽章（演讲档案五类听众）═════════════════════ */

.ds-scene {
  display: inline-block; white-space: nowrap;
  font-size: 12px; font-weight: 600; letter-spacing: .04em;
  color: #fff; padding: 4px 13px; border-radius: var(--r-pill);
}
.ds-scene--ent     { background: var(--scene-ent); }
.ds-scene--gov     { background: var(--scene-gov); }
.ds-scene--uni     { background: var(--scene-uni); }
.ds-scene--edu     { background: var(--scene-edu); }
.ds-scene--startup { background: var(--scene-startup); }


/* ═══ 7. 反白 CTA 条 ════════════════════════════════════ */

.ds-cta {
  background: var(--v-ink); color: var(--v-bg);
  border-radius: var(--r-lg); padding: 36px var(--sp-10);
  display: flex; align-items: center; justify-content: space-between;
  gap: 28px; flex-wrap: wrap;
}
.ds-cta-title { font-family: var(--v-font-cn-serif); font-size: 1.34rem; font-weight: 600; margin-bottom: var(--sp-2); }
.ds-cta-sub   { font-size: 14px; opacity: .85; line-height: var(--lh-body); max-width: 58ch; }
.ds-cta .ds-btn--primary { background: var(--v-accent); color: var(--v-on-accent); }
.ds-cta .ds-btn--primary:hover { background: var(--v-bg); color: var(--v-ink); }


/* ═══ 8. 页脚 ═══════════════════════════════════════════ */

.ds-foot {
  border-top: 1px solid var(--v-line);
  padding: 36px 0; font-size: 13px; color: var(--v-ink3);
}
.ds-foot-in { display: flex; justify-content: space-between; gap: var(--sp-5); flex-wrap: wrap; align-items: center; }
.ds-foot a:hover { color: var(--v-accent); }


/* ═══ 9. 响应式 ═════════════════════════════════════════ */

@media (max-width: 980px) {
  .ds-section { padding: var(--sp-14) 0; }
  .ds-wrap, .ds-nav-in, .ds-nav-panel { padding-left: var(--sp-5); padding-right: var(--sp-5); }
}


/* ══════════════════════════════════════════════════════════
   10. 迁移垫片 · LEGACY SHIM
   ─────────────────────────────────────────────────────────
   下面这些是 8 个 v3 页现有 markup 里的旧类名。把它们指到上面的
   真组件上，让页面【不改一行 HTML】就能拿到统一定义。
   页面逐个迁到 .ds-* 之后，对应的行就可以从这里删掉。
   ⚠️ 别往这一段里加新类名——新页面直接用 .ds-*。
   ══════════════════════════════════════════════════════════ */

.wrap { max-width: var(--v-max); margin: 0 auto; padding: 0 var(--v-gutter); }
section:not(.hero) { padding: var(--sp-21) 0; border-top: 1px solid var(--v-line); }

.nav        { position: sticky; top: 0; z-index: 60;
              background: color-mix(in srgb, var(--v-bg) 92%, transparent);
              -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
              border-bottom: 1px solid var(--v-line); }
.nav-in     { max-width: var(--v-max); margin: 0 auto; padding: 14px var(--v-gutter);
              display: flex; align-items: center; gap: 28px; }
.brand      { font-family: var(--v-font-cn-serif); font-size: 19px; font-weight: 600;
              letter-spacing: .04em; color: var(--v-ink); white-space: nowrap; }
.brand span { font-family: var(--v-font-mono); font-size: 9.5px; letter-spacing: .28em;
              color: var(--v-ink3); margin-left: 9px; text-transform: uppercase; font-weight: 400; }
.nav-links  { display: flex; gap: 2px; margin-left: 6px; }
.nav-links a{ font-size: 14.5px; font-weight: 500; color: var(--v-ink2);
              padding: 7px 14px; border-radius: var(--r-pill);
              transition: background-color var(--t-fast), color var(--t-fast); }
.nav-links a:hover { background: var(--v-bg3); color: var(--v-ink); }
.nav-right  { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }

.icon-btn   { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--v-line);
              color: var(--v-ink2); display: inline-flex; align-items: center; justify-content: center;
              font-size: 14px; transition: border-color var(--t-fast), color var(--t-fast); }
.icon-btn:hover { border-color: var(--v-accent); color: var(--v-accent); }

.ws-btn     { display: inline-flex; align-items: center; gap: 7px;
              background: var(--v-accent); color: var(--v-on-accent);
              border-radius: var(--r-pill); padding: 9px 19px;
              font-size: 14px; font-weight: 600; white-space: nowrap;
              box-shadow: 0 2px 8px var(--v-accent-soft);
              transition: background-color var(--t-base), transform var(--t-base), box-shadow var(--t-base); }
.ws-btn:hover { background: var(--v-accent-hover); transform: translateY(-1px);
                box-shadow: 0 4px 14px var(--v-accent-soft); }
.ws-btn .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .9; flex: none; }

.sec-label  { font-family: var(--v-font-mono); font-size: 11px; letter-spacing: .26em;
              color: var(--v-accent); text-transform: uppercase; font-weight: 500; margin-bottom: 14px; }
.sec-title  { font-family: var(--v-font-cn-serif); font-size: var(--fs-h2); font-weight: 600;
              color: var(--v-ink); line-height: 1.32; margin: 0 0 var(--sp-3); letter-spacing: .01em; }
.sec-lede   { font-size: var(--fs-lede); color: var(--v-ink2); max-width: var(--v-read);
              line-height: var(--lh-loose); margin: 0 0 34px; }
.sec-head   { display: flex; align-items: flex-end; justify-content: space-between;
              gap: var(--sp-6); flex-wrap: wrap; }
.more       { font-size: 14.5px; font-weight: 600; color: var(--v-accent); white-space: nowrap;
              border-bottom: 1.5px solid transparent; transition: border-color var(--t-fast); padding-bottom: 2px; }
.more:hover { border-bottom-color: var(--v-accent); }
.hl         { color: var(--v-accent); font-weight: 700; font-style: normal; }

.btn-p      { display: inline-block; padding: 12px 26px; border-radius: var(--r-pill);
              font-size: 14.5px; font-weight: 600; background: var(--v-accent); color: var(--v-on-accent);
              transition: background-color var(--t-base), transform var(--t-base); }
.btn-p:hover{ background: var(--v-accent-hover); transform: translateY(-1px); }
.btn-s      { display: inline-block; padding: 12px 26px; border-radius: var(--r-pill);
              font-size: 14.5px; font-weight: 600; border: 1.5px solid var(--v-line2); color: var(--v-ink);
              transition: border-color var(--t-base), color var(--t-base); }
.btn-s:hover{ border-color: var(--v-accent); color: var(--v-accent); }

/* ── 内页页头 .head（4–8 页共享）──────────────────────
   此前 padding 有 34/44px 三种、h1 有 32px 与 clamp(2rem,4vw,2.6rem) 两种、
   .lede 的 max-width 有 62/64ch 两种。统一。 */
.head { padding: 44px 0 var(--sp-4); }
.head h1 { font-family: var(--v-font-cn-serif); font-size: var(--fs-h1); font-weight: 700;
           margin: 0 0 var(--sp-4); line-height: 1.3; }
.head .lede { font-size: 16px; color: var(--v-ink2); max-width: 64ch; line-height: 1.85; margin: 0; }
.head .sub  { color: var(--v-ink3); font-size: 14px; line-height: 1.7; max-width: 60ch; }
.head .cnt  { font-family: var(--v-font-mono); font-size: 11px; letter-spacing: .16em;
              color: var(--v-ink3); text-transform: uppercase; white-space: nowrap; }
.head .cnt b{ font-family: var(--v-font-serif); font-size: 22px; color: var(--v-accent); font-weight: 600; }
.head--split { display: flex; justify-content: space-between; align-items: flex-end;
               flex-wrap: wrap; gap: var(--sp-4); }

/* ── 分组头 .gh（3 页共享）────────────────────────────── */
.gh    { display: flex; align-items: baseline; gap: var(--sp-3);
         padding-bottom: var(--sp-3); margin-bottom: 18px; border-bottom: 1px solid var(--v-line); flex-wrap: wrap; }
.gh h2 { font-family: var(--v-font-cn-serif); font-size: 1.24rem; font-weight: 600; margin: 0; }
.gh .gn{ font-family: var(--v-font-serif); font-size: 1.15rem; color: var(--v-accent); font-weight: 600; }
.gh .gd{ font-size: var(--fs-xs); color: var(--v-ink3); }
.gh p  { font-size: 14px; color: var(--v-ink2); line-height: 1.8; margin: 0; max-width: 64ch; }
.group { margin-bottom: var(--sp-10); }

/* ── 统计条 .stats（2 页共享）─────────────────────────── */
.stats  { display: flex; gap: 34px; flex-wrap: wrap; padding: var(--sp-6) 0 28px;
          border-bottom: 1px solid var(--v-line); }
.stat b { font-family: var(--v-font-serif); font-size: 1.9rem; color: var(--v-accent);
          font-weight: 600; display: block; line-height: 1; }
.stat span { font-family: var(--v-font-mono); font-size: var(--fs-micro); letter-spacing: .16em;
             color: var(--v-ink3); text-transform: uppercase; margin-top: 6px; display: block; }

/* ── 筛选条（3 页共享）──────────────────────────────── */
.filter-row { display: flex; gap: 6px; margin: 18px 0 28px; flex-wrap: wrap; align-items: center; }
.filter-btn { padding: 6px 14px; border-radius: var(--r-pill);
              background: var(--v-card); border: 1px solid var(--v-line);
              font-size: 13px; color: var(--v-ink2);
              transition: border-color var(--t-fast), color var(--t-fast), background-color var(--t-fast); }
.filter-btn:hover  { border-color: var(--v-accent); color: var(--v-accent); }
.filter-btn.active { background: var(--v-ink); color: var(--v-bg); border-color: var(--v-ink); }
.filter-btn .n     { font-family: var(--v-font-mono); font-size: 10px; opacity: .62; margin-left: 5px; }
.filter-search {
  flex: 1; min-width: 210px; padding: 7px var(--sp-4);
  border: 1px solid var(--v-line); border-radius: var(--r-pill);
  font-size: 13.5px; font-family: var(--v-font-cn);
  background: var(--v-card); color: var(--v-ink);
}
/* outline:none 由 base.css 的 :focus-visible 焦点环补偿 */
.filter-search:focus { outline: none; border-color: var(--v-accent); }

/* ── 空态 / 载入态（4 页共享）─────────────────────────── */
.loading, .empty { padding: 60px var(--sp-5); text-align: center; color: var(--v-ink3); font-size: 14px; }

/* ── 反白 CTA 条 · 旧类名（3 页共享）───────────────────── */
.cta      { background: var(--v-ink); color: var(--v-bg); border-radius: var(--r-lg);
            padding: 34px 38px; display: flex; align-items: center; justify-content: space-between;
            gap: 28px; flex-wrap: wrap; }
.cta .ct  { font-family: var(--v-font-cn-serif); font-size: 1.28rem; font-weight: 600; margin-bottom: 7px; }
.cta .cs  { font-size: 13.5px; opacity: .85; line-height: var(--lh-body); max-width: 58ch; }
.cta a    { background: var(--v-accent); color: var(--v-on-accent);
            padding: 12px 28px; border-radius: var(--r-pill);
            font-size: 14.5px; font-weight: 600; white-space: nowrap;
            transition: background-color var(--t-base), color var(--t-base); }
.cta a:hover { background: var(--v-bg); color: var(--v-ink); }

/* ── 平台大卡 .plat（index + about 共享）─────────────────
   此前两页图片比例 16:10 与 4:3、标题 1.42rem/700 与 1.28rem/600、
   gap 22 与 20px，各是各的。统一到 index 那套，about 用 --compact 收窄。 */
.plats { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.plat-img { position: relative; }
.plat-img img, .plat > img { width: 100%; aspect-ratio: 16/10; object-fit: cover; }
.plat-badge {
  position: absolute; top: var(--sp-4); left: var(--sp-4);
  background: rgba(34,30,26,.88); color: #F7F3EA;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font-family: var(--v-font-mono); font-size: 10px; letter-spacing: .18em;
  padding: 6px 13px; border-radius: var(--r-pill); text-transform: uppercase; font-weight: 500;
}
.plat-b      { padding: var(--sp-6) 26px 26px; }
.plat-b h3   { font-size: 1.42rem; font-weight: 700; margin: 0 0 var(--sp-1); }
.plat-b .en  { font-family: var(--v-font-mono); font-size: var(--fs-micro); letter-spacing: .22em;
               color: var(--v-accent); text-transform: uppercase; margin-bottom: 11px; font-weight: 500; }
.plat-b p    { font-size: 14px; color: var(--v-ink2); line-height: var(--lh-body); margin: 0 0 14px; }
.plat-b .go  { font-size: 13.5px; font-weight: 600; color: var(--v-accent); }
.plats--compact { gap: var(--sp-5); }
.plats--compact .plat-b    { padding: 22px var(--sp-6) var(--sp-6); }
.plats--compact .plat-b h3 { font-size: 1.28rem; font-weight: 600; margin-bottom: var(--sp-2); }
.plats--compact .plat-b p  { font-size: 13.5px; line-height: 1.72; margin: 0; }

/* ── V3 预览角标（8 页共享）───────────────────────────── */
.v3-flag { position: fixed; left: 14px; bottom: 14px; z-index: 80;
           background: var(--v-ink); color: var(--v-bg);
           font-family: var(--v-font-mono); font-size: 10px; letter-spacing: .16em;
           padding: 7px 13px; border-radius: var(--r-pill); text-transform: uppercase; opacity: .9; }

/* 15 个卡片类 → 一个定义。圆角与 hover 统一，不再各是各的。 */
.art, .ocard, .plat, .book, .prod, .dcard, .lcard, .mcard,
.pcard, .qcard, .tcard, .post, .mp, .lstep, .role {
  background: var(--v-card);
  border: 1px solid var(--v-line);
  border-radius: var(--r-md);
  box-shadow: var(--v-shadow);
  display: block;
  transition: border-color var(--t-base), transform var(--t-base), box-shadow var(--t-base);
}
a.art:hover, a.ocard:hover, a.plat:hover, a.book:hover, a.prod:hover,
a.dcard:hover, a.lcard:hover, a.mcard:hover, a.pcard:hover, a.qcard:hover,
a.tcard:hover, a.post:hover, a.mp:hover, a.lstep:hover, a.role:hover,
.art:hover, .ocard:hover, .plat:hover, .book:hover, .prod:hover,
.dcard:hover, .lcard:hover, .mcard:hover, .pcard:hover, .qcard:hover,
.tcard:hover, .post:hover, .mp:hover, .lstep:hover {
  border-color: var(--v-accent);
  transform: translateY(-2px);
  box-shadow: var(--v-shadow-lg);
}
a.art:hover { transform: translateX(3px); }          /* 纵向列表项：平移不上浮 */
.ocard, .pcard, .dcard { border-radius: var(--r-lg); }
.plat { border-radius: var(--r-xl); overflow: hidden; }
.book, .lcard { border-radius: var(--r-sm); }

/* ── 卡片底栏贴底 ────────────────────────────────────────
   grid 让同排卡片等高，但卡内的底栏（元信息/去向）仍会跟着正文走：
   描述多换一行，底栏就掉下去 20 多像素，整排底边参差。
   把卡片改成纵向 flex，底栏 margin-top:auto 顶到底部即可对齐。
   各页的底栏类名不同（.mf / .foot / .pfoot / .qmeta / .tmeta / .cites），
   一并在此收口——迁到 .ds-card 后统一叫 .ds-card-foot。 */
.mcard, .dcard, .pcard, .qcard, .tcard, .ocard, .post, .mp, .lstep {
  display: flex; flex-direction: column;
}
.mcard .mf,
.dcard .foot,
.pcard .pfoot,
.qcard .qmeta,
.tcard .tmeta,
.post .cites,
.ocard .go,
.ds-card-foot {
  margin-top: auto;
}
