/* =====================================================
   qing-scene-mosaic  —  场景拼图（大小卡混排，文字压在图上）
   前缀: qsm-

   与 qing-prod-scene（适用场景版块）的分工：
   - qpsc-：等宽卡片，文字在图片下方
   - qsm- ：大小不等的拼图，文字压在图片上
   两者前缀独立，样式互不影响。
   ===================================================== */

.qsm-wrap {
  background: #fff;
  padding: 72px 0;
}

.qsm-inner {
  max-width: 1140px;
  margin: 0 auto;
  padding: 0 50px;
  box-sizing: border-box;
}

/* ---------- 左侧蓝色竖条标题 ---------- */
.qsm-title {
  font-size: 30px;
  font-weight: 800;
  color: #111;
  line-height: 1.3;
  text-align: left;
  padding-left: 18px;
  border-left: 5px solid #1f6feb;
  margin: 0 0 40px;
}

/* ---------- 拼图网格 ----------
   两种流向，靠 --col / --row 两个类切换：

   列优先（--col，默认）：先往下排满一列再换下一列。
   「左边两张小卡竖排 + 右边一张大卡占满高度」必须用这个方向——
   行优先下第二张小卡会跑到第一张右边去，大卡被挤到下一行，
   拼不出那个版式。
   行数固定、行高固定，列宽由「首列宽度占比」给第一列，
   其余列自动占剩余空间。

   行优先（--row）：先往右排满一行再换行，列等宽。传统网格行为。

   两种方向下，占 2 行的卡片高度都会自动等于
   「两倍行高 + 一份行间距」，和旁边两张小卡的上下边缘天然对齐，
   不用手算。

   行数 / 行高 / 首列宽度都以自定义属性传入，在这里组装成
   grid-template-* ——因为 repeat() 的两个参数来自两个不同控件，
   让它们各写一条 grid-template-rows 会互相覆盖。 */
.qsm-grid {
  display: grid;
  gap: 20px;
}

.qsm-grid--col {
  grid-auto-flow: column;
  grid-template-rows: repeat(var(--qsm-rows, 2), var(--qsm-row-h, 170px));
  /* 第一列用设定宽度，后续列平分剩余。1fr 作为 auto-columns 应用到
     第二列及之后，所以右侧大卡会自动吃掉剩下的宽度。 */
  grid-template-columns: var(--qsm-first-col, 22%);
  grid-auto-columns: 1fr;
}

.qsm-grid--row {
  grid-auto-flow: row;
  grid-template-columns: repeat(var(--qsm-cols, 3), 1fr);
  grid-auto-rows: var(--qsm-row-h, 170px);
}

/* dense 会回填空格，让拼图更紧凑，代价是打乱视觉顺序。
   两种流向各自的 dense 值不同，所以分开写。 */
.qsm-grid--col.qsm-grid--dense {
  grid-auto-flow: column dense;
}

.qsm-grid--row.qsm-grid--dense {
  grid-auto-flow: row dense;
}

/* ---------- 卡片 ----------
   卡片本身是定位上下文：图片铺满，衬底和文字叠在上面。
   overflow: hidden 是必需的——图片悬停放大时超出的部分要裁掉，
   圆角也才裁得住。 */
.qsm-card {
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  display: block;
  text-decoration: none;
  background: #e9eef6;
  transition: box-shadow 0.3s ease;
}

/* ---------- 图片 ---------- */
.qsm-media {
  position: absolute;
  inset: 0;
}

.qsm-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.45s ease;
}

/* ---------- 渐变衬底 ----------
   夹在图片和文字之间。颜色与高度由控件驱动，这里是兜底值。
   从底部往上由深到透明：底部压住文字区，上半部分不遮挡画面。 */
.qsm-scrim {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 55%;
  background-image: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.45) 0%,
    transparent 100%
  );
  pointer-events: none;
}

/* ---------- 文字 ----------
   铺满整卡再用 flex 定位，这样「正中 / 底部 / 左下 / 左上」四种
   位置只需切换 align-items 和 justify-content，不必换定位方式。 */
.qsm-label {
  position: absolute;
  inset: 0;
  display: flex;
  padding: 18px 20px;
  box-sizing: border-box;
  pointer-events: none;
}

.qsm-name {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.5;
  color: #fff;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);
}

/* 四种文字位置。类名由 PHP 按「文字位置」控件输出，
   单卡可在重复器里覆盖全局值。 */
.qsm-card--center .qsm-label {
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* 注：文字居中的卡片不对衬底做任何特殊处理。
   曾经在这里把渐变换成铺满整卡的纯色（想着居中文字会落在渐变的透明
   区、浅色图上看不清），但那会让卡片变成一块硬边色块，和底部文字那些
   卡片的观感完全不一致。渐变统一保留；居中文字若需要更多衬托，把
   「衬底高度」调到 100% 即可，那样仍是渐变。 */

.qsm-card--bottom-center .qsm-label {
  align-items: flex-end;
  justify-content: center;
  text-align: center;
}

.qsm-card--bottom-left .qsm-label {
  align-items: flex-end;
  justify-content: flex-start;
  text-align: left;
}

.qsm-card--top-left .qsm-label {
  align-items: flex-start;
  justify-content: flex-start;
  text-align: left;
}

/* 无图占位：编辑器里能看出这里是一张卡 */
.qsm-card--empty {
  border: 1px dashed #b8b8b8;
  background: repeating-linear-gradient(
    -45deg,
    #dcdcdc,
    #dcdcdc 10px,
    #e4e4e4 10px,
    #e4e4e4 20px
  );
}

/* 无图时文字改成深色，否则白字落在浅色斜纹上看不见 */
.qsm-card--empty .qsm-name {
  color: #555;
  text-shadow: none;
}

/* =====================================================
   响应式
   说明：总列数、行高、网格间距、圆角、文字内边距、标题下方间距
   等，均由 Elementor 响应式控件按断点输出内联 CSS；同一属性不在
   此重复声明，否则桌面默认值会压掉媒体查询。
   此处仅保留没有控件默认值的属性（字号）。
   ===================================================== */

@media (max-width: 860px) {
  .qsm-title {
    font-size: 24px;
  }
}

/* ---------- 手机端：拼图退化为单列堆叠 ----------
   窄屏下首列只有 22% 宽（约 80px），左栏那两张小卡会挤成一条，
   完全没法看。这里统一改成单列，卡片依次往下排。
   跨列 / 跨行的 span 值需要一并压掉：span 2 在单列网格里会溢出，
   或者让某张卡莫名变成两倍高。选择器写成 0,3,0 压过重复器控件
   输出的 0,2,0。 */
@media (max-width: 767px) {
  .qsm-grid--col,
  .qsm-grid--row {
    grid-auto-flow: row;
    grid-template-columns: 1fr;
    grid-template-rows: none;
    grid-auto-rows: var(--qsm-row-h, 140px);
  }

  .qsm-grid .qsm-card.qsm-card {
    grid-column: auto;
    grid-row: auto;
  }
}

@media (max-width: 480px) {
  .qsm-title {
    font-size: 21px;
  }

  .qsm-name {
    font-size: 15px;
  }
}
