/* ==========================================================================
   图片视觉层 · 全站统一
   --------------------------------------------------------------------------
   只做加法：复用 style.css 的既有设计令牌（--radius-lg / --shadow* / 主色），
   不覆盖任何既有规则。作用范围限定在 .pe-* 与 .pe-card 之下。

   四条统一基线：
     · 配色  —— 只沿用现有森林绿。照片统一压一层薄绿罩，悬停退掉「亮起来」；
                扫描件 / 界面截图不压暗，保证文字清楚。
     · 间距  —— 全部走 --pe-gap（默认 20px，和站内卡片栅格一致）。
     · 层级  —— 底图 → 绿罩 → 颗粒 → 暗角 → 文字，五层固定顺序。
     · 动效  —— 同一条缓动曲线 + 同一个时长，并尊重「减少动态效果」。
   ========================================================================== */

/* ------------------------------------------------------------ 基线令牌 -- */
.pe-stack, .pe-flow, .pe-card {
  --pe-gap: 20px;
  --pe-radius: var(--radius-lg);
  --pe-z-tint: 1;
  --pe-z-grain: 2;
  --pe-z-vig: 3;
  --pe-z-cap: 4;
  --pe-ease: cubic-bezier(.22, .68, .28, 1);
  --pe-dur: .58s;
  --pe-tint: rgba(14, 51, 39, .28);
  --pe-hover-shadow:
    0 2px 6px rgba(14, 42, 32, .07),
    0 22px 48px rgba(14, 42, 32, .16);
}

/* ==========================================================================
   图片地板：底图 + 绿罩 + 颗粒 + 暗角
   比例由 --pe-ratio 统一控制，组件只负责给值，
   这样卡片怎么变高变矮，图片的裁切都不会跟着乱。
   ========================================================================== */
.pe-media {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--gray-100);
  border-radius: var(--radius);
  isolation: isolate;
  aspect-ratio: var(--pe-ratio, 16 / 11);
}
.pe-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* 初始略降饱和、略压暗，悬停才回到正常 */
  filter: saturate(.92) contrast(1.02) brightness(.975);
  transition:
    transform var(--pe-dur) var(--pe-ease),
    filter var(--pe-dur) var(--pe-ease);
}

/* 照片的绿罩：上浅下深，给下方文字留对比 */
.pe-plate::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: var(--pe-z-tint);
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(10, 42, 32, .04) 0%, rgba(10, 42, 32, .30) 100%),
    var(--pe-tint);
  transition: opacity var(--pe-dur) var(--pe-ease);
}

/* 细颗粒：给照片一点印刷质感 */
.pe-plate .pe-grain {
  position: absolute;
  inset: 0;
  z-index: var(--pe-z-grain);
  pointer-events: none;
  opacity: .12;
  mix-blend-mode: overlay;
  background-image:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .5) 0 1px, transparent 1px 2px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .4) 0 1px, transparent 1px 2px);
  background-size: 3px 3px, 3px 3px;
}

/* 暗角：把视线收拢到画面中心 */
.pe-plate .pe-vignette {
  position: absolute;
  inset: 0;
  z-index: var(--pe-z-vig);
  pointer-events: none;
  background: radial-gradient(120% 92% at 50% 42%, transparent 48%, rgba(8, 28, 21, .30) 100%);
  opacity: .9;
  transition: opacity var(--pe-dur) var(--pe-ease);
}

/* 悬停 / 被指到时「亮起来」 */
.pe-card:hover .pe-plate::before,
.pe-card.is-hot .pe-plate::before { opacity: 0; }
.pe-card:hover .pe-plate .pe-vignette,
.pe-card.is-hot .pe-plate .pe-vignette { opacity: .5; }
.pe-card:hover .pe-media img,
.pe-card.is-hot .pe-media img {
  filter: saturate(1.05) contrast(1.03) brightness(1.03);
  transform: scale(1.05);
}

/* ==========================================================================
   卡片外壳
   在 .pe-stack 里用 .card.pe-card 以便吃到站内 .card 的既有样式；
   在网格布局（gallery / cases）里单独用 .pe-card。
   ========================================================================== */
.pe-card {
  position: relative;
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius-lg) + 2px);
  padding: 6px;
  box-shadow: var(--shadow-xs);
  display: flex;
  flex-direction: column;
  transition:
    transform var(--pe-dur) var(--pe-ease),
    box-shadow var(--pe-dur) var(--pe-ease),
    border-color var(--pe-dur) var(--pe-ease);
}
.pe-card:hover,
.pe-card.is-hot {
  border-color: rgba(30, 122, 87, .42);
  box-shadow: var(--pe-hover-shadow);
}
/* .card 自带 34/30 内边距，放进图墙时收窄，否则图片被挤小 */
.pe-stack .card.pe-card { padding: 6px; }

/* 文字层：单独占一行放在图下方。
   不用绝对定位盖在图上 —— 卡片有内边距时，绝对定位的背景会延伸到内边距下面，
   放大或圆角处会看到图片「漏」到文字后面。 */
.pe-cap {
  position: relative;
  z-index: var(--pe-z-cap);
  padding: 12px 8px 6px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.pe-cap b {
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.45;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.pe-cap span {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--gray-500);
  letter-spacing: .02em;
  white-space: nowrap;
}
/* 标题太长时允许两行 */
.pe-cap--wrap b {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* 案例卡：案例名 + 分类并排会被挤到截断（有的名字 20 个字），
   改成上下两行，名字占满整行，分类单独一行。 */
.pe-cap--stack {
  display: block;
  padding: 12px 10px 8px;
}
.pe-cap--stack b { display: block; }
.pe-cap--stack span {
  display: inline-block;
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--blue-700);
  background: var(--blue-50);
  padding: 3px 10px;
  border-radius: 999px;
  font-weight: 600;
}

/* ==========================================================================
   变体一：文档 / 界面截图（不压暗）
   资质证书、专利、软著是扫描件；平台截图、架构图、对比图是白底图 ——
   这两类压暗就看不清字，所以单独一条「不压暗」路径。
   ========================================================================== */
/* 文档类不裁成竖长条：实测站内这些图几乎都是横构图 ——
   平台截图 2.0:1、架构图 1.9:1、资质证书 1.4-1.5:1、专利/软著 0.7:1（竖）。
   统一 16:10 已经能兼顾，竖着的专利只裁掉上下一点点。 */
.pe-card--doc .pe-media { --pe-ratio: 16 / 10; background: var(--gray-50); }
.pe-card--doc .pe-media img { filter: saturate(1) brightness(1.01); }
.pe-card--doc .pe-media::before,
.pe-card--doc .pe-grain,
.pe-card--doc .pe-vignette { display: none; }
.pe-card--doc:hover .pe-media img { filter: saturate(1) brightness(1.03); transform: scale(1.035); }
.pe-card--doc .pe-cap b { color: var(--ink-2); font-weight: 600; font-size: 13.5px; }
/* 资质证书图墙：这批是 1.4-1.5:1，用 4:3 比 16:10 少切一点纸边 */
.pe-stack--doc .pe-card .pe-media { --pe-ratio: 4 / 3; }

/* ---- 2026-10 图片框重做：细边、小圆角、无重阴影 ---- */
.pe-card {
  border-radius: 14px; padding: 4px; box-shadow: none;
  border-color: #E4EBE6;
}
.pe-card:hover, .pe-card.is-hot {
  border-color: rgba(30, 122, 87, .32);
  box-shadow: 0 6px 18px rgba(14, 42, 32, .07);
}
.pe-card--doc {
  padding: 10px; border-radius: 12px;
  background: #FBFCFB; border-color: #E1E9E4; box-shadow: none;
}
.pe-stack .card.pe-card--doc { padding: 10px; }
.pe-card--doc:hover, .pe-card--doc.is-hot {
  border-color: #CBDCD2; box-shadow: none;
}
/* 架构图按原比例完整显示，不裁边、不放大 */
.pe-card--doc .pe-media { aspect-ratio: auto; background: #fff; }
.pe-card--doc .pe-media img {
  height: auto; object-fit: contain; transform: none;
}
.pe-card--doc:hover .pe-media img { transform: none; filter: saturate(1) brightness(1); }
/* 手机上图会缩得很小，给一个明确的放大入口（点击图片即开灯箱） */
.figure-zoom {
  display: none;
  position: absolute; right: 10px; bottom: 10px; z-index: 3;
  padding: 4px 9px; border-radius: 6px;
  background: rgba(14, 51, 39, .72); color: #fff;
  font-family: var(--font-display); font-size: 10px; letter-spacing: .06em;
  pointer-events: none;
}
.fs-media--doc .figure-zoom { bottom: 3px; right: 12px; }
@media (max-width: 720px) {
  .figure-zoom { display: inline-block; }
}

/* ==========================================================================
   变体二：抬起让位（Hover Lift & Yield）
   停在哪张，哪张抬起来；左右邻居各让开一点空档；后排再退一层。
   只改 flex-basis，浏览器按同一行重新分配空间，过渡是连续的。
   ========================================================================== */
.pe-stack {
  /* 关键：flex-grow = 0。
     如果让它长，最后一行不满时（比如 14 张按 4 列排，尾行只剩 2 张）
     这两张会被拉伸成半个屏宽，跟上面几行完全不成比例。
     锁死宽度后尾行保持原尺寸，配合 justify-content:center 居中收尾。 */
  --pe-flex: 0 1 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--pe-gap);
  align-items: flex-start;
}
.pe-stack .pe-card {
  flex: var(--pe-flex);
  min-width: 0;
  flex-basis: calc((100% - var(--pe-gap) * 3) / 4);
  display: flex;
  flex-direction: column;
}
/* 让位：邻居缩小，被指的放大 */
.pe-stack[data-yield] .pe-card { flex-basis: calc((100% - var(--pe-gap) * 3) / 4 - 18px); }
.pe-stack[data-yield] .pe-card.is-hot {
  flex-basis: calc((100% - var(--pe-gap) * 3) / 4 + 36px);
  transform: translateY(-12px);
  z-index: 3;
  border-color: rgba(30, 122, 87, .5);
}
.pe-stack[data-yield] .pe-card.is-nb { transform: translateY(4px); }
.pe-stack[data-yield] .pe-card.is-nb .pe-media img { filter: saturate(.82) brightness(.94); }
.pe-stack[data-yield] .pe-card.is-far { transform: translateY(9px); opacity: .92; }
.pe-stack[data-yield] .pe-card.is-nb .pe-plate::before,
.pe-stack[data-yield] .pe-card.is-far .pe-plate::before { opacity: .72; }

/* ==========================================================================
   变体三：流式图墙（图片数量多的 gallery）
   沿用站内原本的 auto-fill 列宽思路，只是把外框换成卡片。
   卡片多了视觉重量大，所以列宽比原来略宽、留白更足。
   ========================================================================== */
.pe-flow {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: var(--pe-gap);
}
.pe-flow .pe-card { height: 100%; }
.pe-flow .pe-card .pe-media { --pe-ratio: 4 / 3; }

/* 图很少时（1-3 张）不要拉成一排小方块，居中限宽更好看 */
.pe-flow--few {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--pe-gap);
}
.pe-flow--few .pe-card { flex: 0 1 460px; max-width: 100%; }
/* 单张架构图 / 界面图占满整行，避免被 460px 卡片压得看不清 */
.pe-flow--few .pe-card--doc { flex: 1 1 100%; max-width: 100%; }
.pe-flow--few .pe-card .pe-media { --pe-ratio: 16 / 10; }

/* ==========================================================================
   分栏大图（feature 区块的 media）
   ========================================================================== */
.fs-media.pe-plate { position: relative; border-radius: 12px; overflow: hidden; }
.fs-media.pe-plate .pe-media { --pe-ratio: auto; aspect-ratio: auto; border-radius: 12px; }
.fs-media.pe-plate:hover::before { opacity: 0; }
.fs-media.pe-plate:hover .pe-media img { transform: scale(1.035); filter: saturate(1.04) brightness(1.03); }

/* ==========================================================================
   响应式
   ========================================================================== */
@media (max-width: 1080px) {
  .pe-stack .pe-card { flex-basis: calc((100% - var(--pe-gap) * 2) / 3); }
  .pe-stack[data-yield] .pe-card { flex-basis: calc((100% - var(--pe-gap) * 2) / 3 - 14px); }
  .pe-stack[data-yield] .pe-card.is-hot { flex-basis: calc((100% - var(--pe-gap) * 2) / 3 + 28px); }
}
@media (max-width: 900px) {
  /* 两列时不再做让位，只保留轻微抬起 —— 空间不够，让位会显得乱 */
  .pe-stack .pe-card { flex-basis: calc((100% - var(--pe-gap)) / 2); }
  .pe-stack[data-yield] .pe-card { flex-basis: calc((100% - var(--pe-gap)) / 2); }
  .pe-stack[data-yield] .pe-card.is-hot {
    flex-basis: calc((100% - var(--pe-gap)) / 2);
    transform: translateY(-6px);
  }
  .pe-stack[data-yield] .pe-card.is-nb,
  .pe-stack[data-yield] .pe-card.is-far { transform: none; opacity: 1; }
  .pe-flow { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 16px; }
}
@media (max-width: 640px) {
  .pe-stack .pe-card,
  .pe-stack[data-yield] .pe-card,
  .pe-stack[data-yield] .pe-card.is-hot { flex-basis: 100%; }
  .pe-stack .pe-card .pe-media { --pe-ratio: 4 / 3; }
  .pe-stack--doc .pe-card .pe-media { --pe-ratio: 4 / 3; }
  .pe-flow { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .pe-flow--few { display: grid; grid-template-columns: 1fr; }
  .pe-cap { padding: 10px 6px 4px; }
  .pe-cap b { font-size: 14px; }
}

/* --------------------------------------------------- 减少动态效果 -- */
@media (prefers-reduced-motion: reduce) {
  .pe-media img, .pe-card, .pe-media::before, .pe-grain, .pe-vignette {
    transition-duration: .01s !important;
  }
  .pe-media img { filter: saturate(.95) brightness(1); }
  .pe-plate::before { background: linear-gradient(180deg, rgba(10, 42, 32, .03), rgba(10, 42, 32, .24)); }
  .pe-card:hover .pe-media img,
  .pe-card.is-hot .pe-media img { transform: none; }
  .pe-stack[data-yield] .pe-card.is-hot { transform: translateY(-4px); }
  .pe-stack[data-yield] .pe-card.is-nb,
  .pe-stack[data-yield] .pe-card.is-far { transform: none; opacity: 1; }
}

/* ===== 2026-10 证书 / 文档图墙：统一 4:3 图框，横竖混排也对齐 ===== */
.pe-stack--doc { align-items: stretch; }
.pe-stack--doc .pe-card { height: auto; }
.pe-stack--doc .pe-card .pe-media { aspect-ratio: 4 / 3; background: #FFFFFF; }
.pe-stack--doc .pe-card .pe-media img { width: 100%; height: 100%; object-fit: contain; }
.pe-stack--doc .pe-cap { min-height: 54px; align-items: flex-start; }
.pe-stack--doc .pe-cap b {
  white-space: normal; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; min-height: 38px;
}


/* 成功案例照片：只看不放大，避免低分辨率图被点开 */
.case-card .pe-media img { cursor: default; }
.case-card:hover .pe-media img { transform: none; filter: saturate(.98) brightness(.99); }


/* 平台界面截图：2 列，保证文字看得清 */
.pe-stack--2col .pe-card { flex-basis: calc((100% - var(--pe-gap)) / 2); }
@media (max-width: 720px) { .pe-stack--2col .pe-card { flex-basis: 100%; } }


/* 提高优先级，覆盖 4 列默认值 */
.pe-stack.pe-stack--doc.pe-stack--2col .pe-card { flex-basis: calc((100% - var(--pe-gap)) / 2); }


/* 证书待更新标记 */
.pe-badge {
  position: absolute; left: 10px; top: 10px; z-index: 3;
  padding: 3px 9px; border-radius: 999px;
  background: #FFF4E0; color: #9A6A12; border: 1px solid #EBD3A5;
  font-family: var(--font-display); font-size: 10px; font-weight: 700; letter-spacing: .06em;
}


/* ===== 2026-10 图片去边框：让图自然落在页面背景上 ===== */
.fs-media, .fs-media--doc {
  border: 0; box-shadow: none; background: transparent; padding: 0; border-radius: 0;
}
.fs-media img { border-radius: 12px; }
.fs-media--doc img { border-radius: 0; }
.fs-media--doc .figure-zoom { bottom: 10px; right: 10px; }

.pe-card, .pe-card--doc,
.pe-stack .card.pe-card, .pe-stack .card.pe-card--doc {
  border: 0; box-shadow: none; background: transparent; padding: 0;
}
.pe-card:hover, .pe-card.is-hot,
.pe-card--doc:hover, .pe-card--doc.is-hot {
  border: 0; box-shadow: none; background: transparent;
}
.pe-card .pe-media, .pe-card--doc .pe-media { border-radius: 12px; }
.pe-card--doc .pe-media { background: #FFFFFF; }
.pe-cap, .pe-cap--stack { padding: 10px 2px 0; }


/* 架构图 / 平台界面：不要白底卡片，直接落在页面背景 */
.pe-card--bare .pe-media { background: transparent; aspect-ratio: auto; border-radius: 0; }
.pe-card--bare .pe-media img { width: 100%; height: auto; object-fit: contain; }
/* 位图裸图（界面截图）：按原尺寸居中显示，不放大 —— 源图常只有 500-600px，拉满整行会糊 */
.pe-card--bare-raster .pe-media { display: flex; justify-content: center; }
.pe-card--bare-raster .pe-media img { width: auto; max-width: 100%; }


/* 专利 / 软著：A4 竖向图框，完整显示 */
.pe-card--tall .pe-media { aspect-ratio: 3 / 4; }


.pe-stack--doc .pe-card--tall .pe-media { aspect-ratio: 3 / 4; }

