/* =====================================================
   qing-prod-scene  —  适用场景（方形图片卡片 + 框外名称）
   前缀: qpsc-
   对应源码 .pd-section.pd-scene
   ===================================================== */

.qpsc-wrap {
  background: #f2f6fd;
  padding: 72px 0;
}

@keyframes qpsc-enter-up { from { opacity: 0; transform: translate3d(0,58px,0); } to { opacity: 1; transform: none; } }
.qing-motion-js .qpsc-wrap:not(.is-motion-visible) .qpsc-title,
.qing-motion-js .qpsc-wrap:not(.is-motion-visible) .qpsc-card { opacity: 0; transform: translate3d(0,58px,0); }
.qpsc-wrap.is-motion-visible .qpsc-title,
.qpsc-wrap.is-motion-visible .qpsc-card { animation: qpsc-enter-up 1.1s cubic-bezier(.16,1,.3,1) backwards; }
.qpsc-wrap.is-motion-visible .qpsc-title { animation-delay: 100ms; }
.qpsc-wrap.is-motion-visible .qpsc-card { animation-delay: calc(320ms + var(--motion-i,0) * 210ms); }
@media (prefers-reduced-motion: reduce) { .qing-motion-js .qpsc-wrap .qpsc-title, .qing-motion-js .qpsc-wrap .qpsc-card { opacity: 1; transform: none; animation: none; } }

.qpsc-inner {
  max-width: 1140px;
  margin: 0 auto;
  padding: 0 50px;
  box-sizing: border-box;
}

/* ---------- 版块标题 ----------
   两种形态由「标题对齐」控件切换：
   --left  ：装饰条是标题左侧的竖条（原样式，默认）
   --center：标题居中，装饰条变成标题下方的横线

   装饰条颜色 / 粗细由控件以自定义属性传入（--qpsc-bar-c、
   --qpsc-bar-w），两种形态各自消费。不让控件直接输出 border-left-*：
   居中模式要把竖条整条去掉，而控件内联 CSS 的权重和加载顺序都在本
   文件之后，压不掉。 */
.qpsc-title {
  font-size: 30px;
  font-weight: 800;
  color: #111;
  line-height: 1.3;
  margin: 0 0 40px;
}

/* 左对齐：竖条 */
.qpsc-title--left {
  text-align: left;
  padding-left: 18px;
  border-left: var(--qpsc-bar-w, 5px) solid var(--qpsc-bar-c, #1f6feb);
}

/* 居中：横线在标题下方。
   用 ::after 而不是 border-bottom —— border 会拉满整个块宽度，
   这里要的是一小段居中短线。 */
.qpsc-title--center {
  text-align: center;
  padding-bottom: 14px;
  position: relative;
}

.qpsc-title--center::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: var(--qpsc-bar-len, 56px);
  height: var(--qpsc-bar-w, 5px);
  background-color: var(--qpsc-bar-c, #1f6feb);
  border-radius: 2px;
}

/* ---------- 网格 ---------- */
.qpsc-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 24px;
}

/* 卡片本体为透明容器：白框图片 + 框外灰色标签 */
.qpsc-card {
  border: none;
  background: none;
  display: block;
  text-decoration: none;
}

/* ---------- 图片框 ---------- */
.qpsc-media {
  aspect-ratio: 1 / 1;
  background: #fff;
  border: 1px solid #d8e6fb;
  border-radius: 10px;
  overflow: hidden;
  display: block;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.qpsc-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}

/* 悬停投影不写在这里：由「图片框样式 → 悬停 → 启用悬停投影」开关
   控制，开关关闭时 Elementor 不输出 box-shadow，这里也就不该有
   硬编码值，否则关不掉。边框色同理由控件驱动。 */
.qpsc-card:hover .qpsc-media {
  border-color: #1f6feb;
}

.qpsc-card:hover .qpsc-media img {
  transform: scale(1.05);
}

/* ---------- 跨列卡片（占 2 列以上且要求等高） ----------
   .qpsc-card--fill 由 PHP 在「占几列 > 1」且「跨列时与同行等高」
   开启时输出。行高由同行只占 1 列的卡片撑开，这里让图片框吃掉
   名称之外的剩余高度，于是卡片变宽而不变高。
   选择器带上 .qpsc-grid 提升权重，压过 Elementor 那条同权重的
   aspect-ratio 内联规则（它在本文件之后加载）。 */
.qpsc-grid .qpsc-card--fill {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.qpsc-grid .qpsc-card--fill .qpsc-media {
  aspect-ratio: auto;
  flex: 1 1 0;
  min-height: 0;
}

.qpsc-grid .qpsc-card--fill .qpsc-media img {
  height: 100%;
}

/* ---------- 自适应比例（图片宽高比 = 自适应） ----------
   .qpsc-grid--auto-ratio 由 PHP 在选了「自适应」时输出。
   图片框没有固定高度，img 的 height:100% 会算成 0，这里改回 auto，
   让图片按原始比例撑开框子。 */
.qpsc-grid--auto-ratio .qpsc-media img {
  height: auto;
}

/* 自适应下无图占位没有内容撑高，给个兜底高度，
   否则编辑器里会塌成一条线看不见。 */
.qpsc-grid--auto-ratio .qpsc-media--empty {
  min-height: 120px;
}

/* 自适应 + 跨列等高：上面 --fill 那条权重更高，img 仍是 height:100%，
   即拉伸填满同行最高的卡片。此时「图片填充方式」控件是隐藏的，
   object-fit 会退回默认值 fill 把图压变形，这里显式兜一个 cover。 */
.qpsc-grid--auto-ratio .qpsc-card--fill .qpsc-media img {
  object-fit: cover;
}

/* =====================================================
   自适应布局（布局模式 = 自适应）
   目标：所有图片高度一致，宽度由各自原始比例决定，横图更宽，
   名称在图片正下方且底部对齐成一条线。
   grid 的轨道天生等宽，做不到「等高不等宽」，所以这里整体换成
   flex：图片框吃固定高度，img 用 height:100% + width:auto，
   宽度就是「固定高度 × 图片原始比例」，卡片被图片撑开。
   写在文件末尾并带 --flex 前缀，靠加载顺序与权重压过上面的
   网格规则。
   ===================================================== */
.qpsc-grid--flex {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
}

/* flex-basis:auto + 不许拉伸：卡片宽度完全由内容（图片）决定。
   min-width:0 允许在窄屏被压缩，避免溢出容器。 */
.qpsc-grid--flex .qpsc-card {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
}

/* 高度由「统一图片高度」控件给（这里的 170px 是无控件值时的兜底），
   宽度 auto 让图片说话。
   aspect-ratio 必须清掉：它和固定高度同时存在时会反推出固定宽度，
   那就又变成等宽了，正是要避免的结果。
   选择器特意多带一层 .qpsc-card（权重 0,3,0），压过「图片宽高比」
   控件的 0,2,0 —— 那条虽然在自适应布局下被 condition 隐藏，但不能
   指望它一定不输出。 */
.qpsc-grid--flex .qpsc-card .qpsc-media {
  aspect-ratio: auto;
  height: 170px;
  width: auto;
  max-width: 100%;
  display: inline-flex;
}

/* 这是整套布局的支点：高度撑满框子，宽度按原始比例算出来。
   object-fit 用 contain 保证不裁切——宽度既然是按比例算的，
   contain 下不会产生留白。同样多带一层压过「图片填充方式」。 */
.qpsc-grid--flex .qpsc-card .qpsc-media img {
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/* 无图占位在 flex 下没有内容撑宽，会塌成 0，给个兜底宽度 */
.qpsc-grid--flex .qpsc-media--empty {
  width: 160px;
  max-width: 100%;
}

/* 名称不参与撑开卡片：卡片宽度已由图片定死，这里让文字在该宽度
   内换行，长名称不会把卡片顶宽导致图片间距不均。 */
.qpsc-grid--flex .qpsc-name {
  width: 100%;
  box-sizing: border-box;
  overflow-wrap: break-word;
}

/* =====================================================
   整齐布局（布局模式 = 整齐）
   目标：图片等高不裁切（和自适应布局一样），但每行数量固定，
   排不满的末行自动居中。
   自适应布局是「按图片实际宽度贪心排，能塞几个算几个」，一行几个
   不可控、末行左对齐；这里改成给卡片定死宽度
   （(100% - 间距总和) ÷ 每行数量），再用 justify-content: center
   让不满的末行居中。满行时卡片正好铺满，居中不产生偏移。
   ===================================================== */
.qpsc-grid--tidy {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
}

/* 卡片宽度 = (100% - 间距总和) ÷ 每行数量。
   两个变量由控件输出：--qpsc-per-row（每行数量）、
   --qpsc-col-gap（列间距）。都给了兜底值，控件没设也能用。
   flex-grow: 0 很关键：一旦允许拉伸，末行那几个会被拉宽填满整行，
   就不是「居中」而是「撑开」了。 */
.qpsc-grid--tidy .qpsc-card {
  --qpsc-pr: var(--qpsc-per-row, 4);
  --qpsc-cg: var(--qpsc-col-gap, 24px);
  flex: 0 0
    calc((100% - (var(--qpsc-pr) - 1) * var(--qpsc-cg)) / var(--qpsc-pr));
  max-width: calc(
    (100% - (var(--qpsc-pr) - 1) * var(--qpsc-cg)) / var(--qpsc-pr)
  );
  min-width: 0;
}

/* 图片框吃统一高度、铺满卡片宽度；图片在框内等比完整显示。
   用 contain 而不是 cover：整齐布局的前提是不裁切，而卡片等宽、
   图片比例不一，只能靠 contain 在框内留白。
   权重带 .qpsc-card（0,3,0），压过「图片宽高比 / 填充方式」控件的
   0,2,0 —— 那两个控件在本模式下已隐藏，但不能指望它们一定不输出。 */
.qpsc-grid--tidy .qpsc-card .qpsc-media {
  aspect-ratio: auto;
  height: 170px;
  width: 100%;
  display: flex;
}

.qpsc-grid--tidy .qpsc-card .qpsc-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 无图占位交回卡片宽度 */
.qpsc-grid--tidy .qpsc-media--empty {
  width: auto;
}

/* 名称在卡片宽度内换行，不参与撑宽 */
.qpsc-grid--tidy .qpsc-name {
  width: 100%;
  box-sizing: border-box;
  overflow-wrap: break-word;
}

/* ---------- 自适应布局：手机端退化为固定 2 列 ----------
   窄屏下按图片原始宽度排会很乱（一行塞不下就换行，出现一行一个、
   宽窄不一）。这里改回 grid 走固定 2 列：卡片等宽，图片框吃统一
   高度，图片用 contain 在框内居中完整显示。
   选了「占几列 ≥ 2」的项（.qpsc-card--wide）占满整行，即一排一个。

   为什么用 grid 而不是继续 flex：grid 才有 grid-column，能让
   --wide 项干净地占满整行；flex 下要靠百分比宽度算，还要扣掉
   gap，容易错。 */
@media (max-width: 767px) {
  .qpsc-grid--flex {
    display: grid;
    /* 列数由「手机端每行数量」控件以自定义属性传进来，默认 2。
       控件本身不带媒体查询，属性只在这里被消费。 */
    grid-template-columns: repeat(var(--qpsc-mobile-cols, 2), 1fr);
    /* 桌面端用 flex-end 让名称底部对齐成一条线；手机端图片框已经
       等高等宽，改成顶部对齐——万一某个名称换行成两行，底部对齐
       会把这一格的图片往下推，反而错位。 */
    align-items: start;
  }

  /* 重复器的「占几列」控件输出的是 grid-column: span N（权重 0,2,0），
     在这里会突然生效。span 3 / 4 会在 2 列网格里溢出，所以统一压成
     整行：选择器写成 0,3,0 压过控件。 */
  .qpsc-grid--flex .qpsc-card.qpsc-card--wide {
    grid-column: 1 / -1;
  }

  /* 非跨列项同理，强制回单列，避免控件的 span 值在 2 列网格里错位 */
  .qpsc-grid--flex .qpsc-card:not(.qpsc-card--wide) {
    grid-column: auto;
  }

  /* 卡片交回 grid 管宽度，不再由图片撑开 */
  .qpsc-grid--flex .qpsc-card {
    flex: none;
    max-width: none;
  }

  /* 图片框撑满格子宽度，高度仍由「统一图片高度」控件给（手机断点
     默认 110px）。这里只改 width，height 不写，免得压掉控件值。
     权重与桌面那条 .qpsc-grid--flex .qpsc-card .qpsc-media 一致。 */
  .qpsc-grid--flex .qpsc-card .qpsc-media {
    width: 100%;
    display: flex;
  }

  /* 宽度改由框子决定，图片在框内完整居中显示。
     比例不同的图会有左右留白，这是等宽格子下保持不裁切的代价；
     想让某张宽图不留白，把它的「占几列」设成 2 即可占满整行。 */
  .qpsc-grid--flex .qpsc-card .qpsc-media img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  /* 无图占位交回格子宽度 */
  .qpsc-grid--flex .qpsc-media--empty {
    width: auto;
  }
}

/* 无图占位 */
.qpsc-media--empty {
  border-style: dashed;
  border-color: #b8b8b8;
  background: repeating-linear-gradient(
    -45deg,
    #dcdcdc,
    #dcdcdc 10px,
    #e4e4e4 10px,
    #e4e4e4 20px
  );
}

/* ---------- 场景名称（框外） ---------- */
.qpsc-name {
  padding: 14px 4px 0;
  font-size: 14px;
  font-weight: 400;
  color: #666;
  line-height: 1.6;
  text-align: center;
  margin: 0;
}

/* =====================================================
   响应式
   说明：版块内边距、内容区左右内边距、列数、网格间距、图片
   宽高比与圆角、名称间距、标题下方间距等，均由 Elementor
   响应式控件按断点输出内联 CSS；同一属性不在此重复声明，
   否则桌面默认值会压掉媒体查询。
   此处仅保留没有控件默认值的属性（字号）。
   ===================================================== */

@media (max-width: 860px) {
  .qpsc-title {
    font-size: 24px;
  }
}

@media (max-width: 480px) {
  .qpsc-title {
    font-size: 21px;
  }

  .qpsc-name {
    font-size: 13px;
  }
}
