/* ============================================================================
 * 装修区块样式（C 端共用）
 * ----------------------------------------------------------------------------
 * 装修页（/index/page/detail）与商品详情智能模板（/index/product/detail）
 * 渲染的是**同一套区块**，样式必须只有一份 —— 否则同一个图文组件在两个页面
 * 表现不一样，就又回到「装修所见 ≠ 前台所得」的老问题。
 *
 * ⚠️ 只放「区块」样式。页面骨架（顶栏 / 面包屑 / 页脚 / .wrap）各模板自己管，
 *    不要往这里加，否则商品详情会被装修页的骨架规则串到。
 *
 * ⚠️ 区块级尺寸/颜色一律用行内 style 写在片段根节点上（同一页可能有多块同类型区块，
 *    写进这里会串值）。
 * ========================================================================== */

/* 主题色默认值：让本文件可「整块打包、独立引用」——引用页若自己定义了 --theme
   （如 /index/page/detail 的行内 :root），会覆盖这里的默认，互不影响。 */
:root {
    --theme: #409eff;
}

/* ---------------- 区块容器 ---------------- */
.blocks {
    padding-bottom: 20px;
}
.block {
    background: #fff;
}
/* 未选图时的通用灰占位。
   画布（BlockRender / ImageOverlay）对空图显示占位盒，前台若直接输出 <img src=""> 会变成
   破图图标 —— 两边不一致。所有「可能为空」的图片位置统一走这个 span。 */
.ph-img {
    display: block;
    width: 100%;
    height: 100%;
    background: #f0f0f0;
}
/* 显示宽度：每个区块外面包一层，由控制器按 width_mode 输出 class + 行内 max-width。
   · bw-full  通屏 —— 父容器多宽就多宽
   · bw-fixed 固定 —— 最多 N px 并水平居中，两侧露出页面背景
   ⚠️ 行内样式里已经带了 max-width / margin：width:100% 负责「窄屏自动缩」，
      max-width 负责「宽屏封顶」、margin:auto 负责居中。这里别再写死宽度。 */
.bw {
    width: 100%;
    box-sizing: border-box;
}

/* ---------------- 轮播图 ---------------- */
.banner {
    position: relative;
    width: 100%;
    overflow: hidden;
}
.banner img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* ⚠️ 幻灯片必须叠在一起（absolute + 淡入淡出），切换由 detail.html 的轮播脚本加 .is-active。
   以前这里是 position:relative —— 所有幻灯片从上到下排成一列，就是「轮播不轮播」的现场。 */
.banner .bn-slide {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    visibility: hidden;
    z-index: 1;
    /* 覆盖文字与蒙版贴着各自的幻灯片定位 */
    transition: opacity 0.45s ease;
}
.banner .bn-slide.is-active {
    opacity: 1;
    visibility: visible;
    z-index: 2;
}
/* JS 没跑起来（被拦截 / 报错 / 页面是纯静态预览）时至少显示第一张，
   不要整块空白，也不要一堆图纵向堆叠 */
.banner:not(.bn-ready) .bn-slide:first-child {
    opacity: 1;
    visibility: visible;
    z-index: 2;
}
/* 未开启图文分离：文字压在图片底部一条独立的文字条上。
   ⚠️ 必须与画布 BlockRender.vue 的 .bn-caption 逐条一致（绝对定位盖在底部，
      不参与文档流，否则会把图片高度挤没）。 */
.banner .bn-caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 5;
    padding: 8px 12px;
    background: #fff;
    color: #333;
    font-size: 13px;
    line-height: 1.5;
}
.banner .bn-caption-html p,
.banner .bn-caption-html div,
.banner .bn-caption-html li {
    margin: 0;
    line-height: 1.45;
}
.banner .dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 12px;
    display: flex;
    justify-content: center;
    gap: 6px;
    /* 幻灯片是 z-index:2，圆点必须更高，否则被当前这张盖住点不到 */
    z-index: 6;
}
.banner .dots i {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.5);
}
.banner .dots i.on {
    background: var(--theme);
}

/* ---------------- 图片广告（多图布局 + 覆盖文字） ---------------- */
.ad-grid {
    display: grid;
    padding: 8px;
    background: #fff;
    /* 与画布 BlockRender.vue 一致：行内 padding 会加到 width 上，
       不写 border-box 的 100% 宽度会溢出父容器（图片广告左右被挤出去）。 */
    box-sizing: border-box;
}
.ad-cell {
    position: relative;
    overflow: hidden;
    border-radius: 6px;
    background: #f5f5f5;
    display: flex;
    flex-direction: column;
    /* 与画布一致：flex 子项默认 min-height:auto，会撑破固定行高 */
    min-height: 0;
}
.ad-media {
    position: relative;
    flex: 1;
    min-height: 0;
}
/* ⚠️ 前台模板里 <img> 被 <a> 包裹（图片可点击跳转），所以这里必须同时命中
   .ad-media > a（链接铺满单元格）与 .ad-media > a > img（图片铺满链接），
   否则 .ad-media > img 这条「直接子元素」选择器命中不到、object-fit:cover 失效，
   图片会按自然比例顶部对齐裁切 —— 与画布（ImageOverlay cover 居中）不一致，
   表现为「图片广告拉伸 / 商品详情智能模板前台显示图头、画布显示图身」。 */
.ad-media > a {
    display: block;
    width: 100%;
    height: 100%;
}
.ad-media > img,
.ad-media > a > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* 没选图时的占位：画布显示灰底占位，前台保持同样的灰底，不输出 <img src=""> */
.ad-media > .ad-ph {
    display: block;
    width: 100%;
    height: 100%;
    background: #f5f5f5;
}
.ad-mask {
    position: absolute;
    inset: 0;
    /* 蒙版/遮罩只是视觉层，绝对不能挡住底下的图片链接 */
    pointer-events: none;
}
/* ⚠️ 渐变数值必须跟画布组件 ImageOverlay.vue 里的 .ov-grad 完全一致 ——
   装修画布是「所见」的基准，前台（所得）照抄，否则两边深浅差一截。 */
.ad-mask.mask-top {
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0));
}
.ad-mask.mask-bottom {
    background: linear-gradient(to top, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0));
}
.ad-mask.mask-center {
    background: rgba(0, 0, 0, 0.25);
}
/* 没开文字遮罩时后端把 mask_group 设为 none，用 display:none 关掉（避免模板里嵌套 IF） */
.ad-mask.mask-none {
    display: none;
}
/* 图片蒙版：整图一层半透明纯色，颜色与不透明度由行内 style 给；
   没开蒙版时后端把 opacity 写成 0，同样是靠样式关掉。 */
.ov-mask {
    position: absolute;
    inset: 0;
    /* 蒙版只做视觉，不能直接吃掉图片上的点击/链接 */
    pointer-events: none;
}
/* 覆盖文字层（九宫格/自由定位都走这里）：铺满模式下会把整张图盖住，
   必须让指针穿透到底图的 <a>，否则点了图片没反应（画布里也是 pointer-events:none）。
   但文字自带的超链接要能点，单独给它放开。 */
.ad-text {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    padding: 10px 12px;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
    pointer-events: none;
}
.ad-text a {
    pointer-events: auto;
}
/* 自由定位：用户在装修画布里拖过文字后才有 text_x / text_y（百分比），
   此时不再铺满整格，宽度由内容撑开，中心点落在 (text_x, text_y)。 */
.ad-text.free {
    inset: auto;
    width: auto;
    max-width: 86%;
    padding: 2px 6px;
}
.ad-text.pos-top-left {
    justify-content: flex-start;
    text-align: left;
}
.ad-text.pos-top-center {
    justify-content: flex-start;
    text-align: center;
}
.ad-text.pos-top-right {
    justify-content: flex-start;
    text-align: right;
}
.ad-text.pos-center-left {
    justify-content: center;
    text-align: left;
}
.ad-text.pos-center {
    justify-content: center;
    text-align: center;
}
.ad-text.pos-center-right {
    justify-content: center;
    text-align: right;
}
.ad-text.pos-bottom-left {
    justify-content: flex-end;
    text-align: left;
}
.ad-text.pos-bottom-center {
    justify-content: flex-end;
    text-align: center;
}
.ad-text.pos-bottom-right {
    justify-content: flex-end;
    text-align: right;
}
.ad-text p,
.ad-text h1,
.ad-text h2,
.ad-text h3,
.ad-text div,
.ad-text li {
    margin: 0;
    padding: 0;
    line-height: 1.4;
}
.ad-caption {
    padding: 6px 8px;
    background: #fff;
    color: #333;
    font-size: 13px;
}
.ad-caption p {
    margin: 0;
}

/* ---------------- 多图轮播（与商家端 BlockRender.vue 的 .cr-* 逐条一致） ---------------- */
.cr-block {
    width: 100%;
    box-sizing: border-box;
}
.cr-viewport {
    position: relative;
}
.cr-track {
    display: flex;
    width: 100%;
    gap: var(--cr-gap, 12px);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}
.cr-track::-webkit-scrollbar {
    display: none;
}
.cr-card {
    flex: 0 0 auto;
    scroll-snap-align: start;
    min-width: 0;
}
/* 一屏 N 张：--cr-gap 由片段行内 style 给出，参与 flex-basis 计算 */
.cr-per-1 .cr-card {
    flex-basis: 100%;
}
.cr-per-2 .cr-card {
    flex-basis: calc((100% - var(--cr-gap, 12px)) / 2);
}
.cr-per-3 .cr-card {
    flex-basis: calc((100% - 2 * var(--cr-gap, 12px)) / 3);
}
.cr-per-4 .cr-card {
    flex-basis: calc((100% - 3 * var(--cr-gap, 12px)) / 4);
}
.cr-media {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    background: #f5f5f5;
}
.cr-media > a {
    display: block;
    width: 100%;
    height: 100%;
}
.cr-media > img,
.cr-media > a > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.cr-caption {
    padding: 8px 10px 0;
    font-size: 14px;
    color: #333;
}
.cr-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 3;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}
.cr-prev {
    left: 8px;
}
.cr-next {
    right: 8px;
}
.cr-dots {
    display: flex;
    justify-content: center;
    gap: 6px;
    margin-top: 10px;
}
.cr-dot {
    /* ⚠️ 前台圆点是 JS 创建的 <button>：必须清掉浏览器默认的 border/padding，
       否则 7px 的点会被撑成一个带边框的小矩形（与画布的圆点对不上）。 */
    display: inline-block;
    width: 7px;
    height: 7px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #d0d3d9;
    box-sizing: border-box;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}
.cr-dot.on {
    background: #165dff;
}

/* ---------------- 文本公告 / 富文本 / 标题 / 公告栏 ---------------- */
.text-block {
    padding: 14px 18px;
    border-radius: 6px;
}
.text-title {
    font-weight: 600;
    margin-bottom: 6px;
}
.text-content {
    font-size: 14px;
    line-height: 1.6;
}

/* 富文本内部排版统一交给 /css/rich-content.css 的 .rich-content。
   ⚠️ 这里不要再写 .richtext-block p / ul / table —— 内联 <style> 比外部样式表
   后加载，写了就会盖掉 rich-content，前台立刻与编辑器不一致。 */
.richtext-block {
    padding: 18px;
    background: #fff;
    color: #333;
    line-height: 1.7;
    font-size: 14px;
}

.title-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 18px 10px;
    background: #fff;
}
.title-bar.align-center {
    justify-content: center;
}
.title-bar.align-right {
    flex-direction: row-reverse;
}
/* 标题 + 副标题同一行：与画布 BlockRender.vue 的 .tb-main 同口径。
   ⚠️ 标题/副标题是富文本，内容常是 <h2>/<p>（块级元素）；若不 flex 排列，
      它们会各占一行（「副标题被顶到下一行」）。 */
.tb-main {
    display: flex;
    align-items: baseline;
    gap: 10px;
}
.title-bar.align-center .tb-main {
    text-align: center;
}
.tb-title {
    font-size: 18px;
    font-weight: 600;
    color: #222;
}
.tb-sub {
    font-size: 13px;
    color: #909399;
    /* 间距交给 .tb-main 的 gap，这里再加 left 会变成双倍 */
    margin-left: 0;
}
.tb-more {
    font-size: 13px;
    color: #909399;
}

.divider-block {
    background: #fff;
}
.blank-block {
    width: 100%;
}

/* ---------------- 商品区块 ---------------- */
.goods-section {
    padding: 16px;
    background: #fff;
}
.section-title {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 14px;
    color: #222;
}
.goods-grid {
    display: grid;
    gap: 14px;
}
.goods-card {
    border: 1px solid #f0f0f0;
    border-radius: 8px;
    overflow: hidden;
    background: #fff;
}
.goods-img {
    height: 140px;
}
.goods-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.goods-name {
    padding: 8px 10px 0;
    font-size: 14px;
    color: #333;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.goods-price {
    padding: 4px 10px 10px;
    color: var(--theme);
    font-weight: 600;
}

.group-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}
.group-tabs {
    display: flex;
    gap: 8px;
}
.group-tab {
    font-size: 13px;
    padding: 4px 12px;
    border-radius: 14px;
    background: #f5f5f5;
    color: #666;
}
.group-tab.on {
    background: var(--theme);
    color: #fff;
}

.rank-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.rank-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px;
    border-radius: 8px;
    background: #fafafa;
}
.rank-no {
    width: 22px;
    height: 22px;
    line-height: 22px;
    text-align: center;
    border-radius: 6px;
    background: #dcdfe6;
    color: #fff;
    font-size: 12px;
    flex-shrink: 0;
}
.rank-no.no-1 {
    background: #f5222d;
}
.rank-no.no-2 {
    background: #fa8c16;
}
.rank-no.no-3 {
    background: #faad14;
}
.rank-thumb {
    width: 52px;
    height: 52px;
    border-radius: 6px;
    overflow: hidden;
    flex-shrink: 0;
}
.rank-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.rank-name {
    font-size: 14px;
    color: #333;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rank-price {
    color: var(--theme);
    font-weight: 600;
    font-size: 13px;
    margin-top: 2px;
}

.showcase {
    display: flex;
    gap: 16px;
    padding: 16px;
    background: #fff;
}
.showcase.layout-top {
    flex-direction: column;
}
.showcase-media {
    width: 260px;
    height: 260px;
    border-radius: 8px;
    overflow: hidden;
    flex-shrink: 0;
}
.showcase-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.showcase.layout-top .showcase-media {
    width: 100%;
    height: 320px;
}
.showcase-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.showcase-name {
    font-size: 18px;
    font-weight: 600;
    color: #222;
}
.showcase-price {
    color: var(--theme);
    font-size: 20px;
    font-weight: 700;
}
.showcase-btn {
    width: 160px;
    height: 38px;
    border: 0;
    border-radius: 19px;
    background: var(--theme);
    color: #fff;
    font-size: 14px;
    cursor: pointer;
}

/* ---------------- 视频 ---------------- */
/* ⚠️ 多视频布局下 .video-block 只是一个外壳，真正的黑色背景和尺寸在各 .video-cell 上，
   所以这里不要再写死 height / background，否则一行多列的空白会被拉成一大块黑。 */
.video-block {
    width: 100%;
    overflow: hidden;
}
/* 一行几个视频：用 grid 保证严格等宽，列数由行内 grid-template-columns 给 */
.video-grid {
    display: grid;
    width: 100%;
}
.video-cell {
    position: relative;
    width: 100%;
    overflow: hidden;
    background: #000;
}
.video-cell video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}
.video-cell > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* ArtPlayer 容器：撑满单元格高度，播放器自己铺满容器 */
.art-holder {
    width: 100%;
    height: 100%;
    background: #000;
}
.art-holder .artplayer-app {
    width: 100%;
    height: 100%;
}
/* 每个视频的标题 / 描述显示在播放器下方（不再叠在视频上）。
   ⚠️ 必须与装修画布 BlockRender.vue 里的同名类保持一致。 */
.video-item {
    width: 100%;
    overflow: hidden;
    /* 居左 / 居中 / 居右靠 align-self 实现：.video-cell 宽度不满时才有视觉效果，
       标题与描述跟着一起对齐（text-align 由 va-* 类带出）。 */
    display: flex;
    flex-direction: column;
}
.video-item.va-left .video-cell {
    align-self: flex-start;
}
.video-item.va-center .video-cell {
    align-self: center;
}
.video-item.va-right .video-cell {
    align-self: flex-end;
}
.video-item.va-left {
    text-align: left;
}
.video-item.va-center {
    text-align: center;
}
.video-item.va-right {
    text-align: right;
}
.video-title {
    padding: 10px 10px 0;
    color: #1f2329;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.5;
}
.video-desc {
    padding: 4px 10px 2px;
    color: #646a73;
    font-size: 13px;
    line-height: 1.6;
}

/* ---------------- 视频：封面图 + 播放按钮（点击由 /js/video-lightbox.js 弹层用 ArtPlayer 播放） ---------------- */
.video-poster {
    position: relative;
    width: 100%;
    height: 100%;
    min-height: 120px;
    display: block;
    cursor: pointer;
    overflow: hidden;
    background: #000;
}
.video-poster .vp-cover {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* 无封面时的黑底占位（仍可被点击弹层播放） */
.video-poster .vp-nocover {
    position: absolute;
    inset: 0;
    background: #000;
}
.video-poster .vp-play {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.5);
    border: 2px solid rgba(255, 255, 255, 0.85);
    box-sizing: border-box;
    transition: background 0.2s ease, transform 0.2s ease;
}
.video-poster .vp-play::before {
    content: "";
    display: block;
    margin-left: 4px;
    border-style: solid;
    border-width: 11px 0 11px 18px;
    border-color: transparent transparent transparent #fff;
}
.video-poster:hover .vp-play {
    background: rgba(0, 0, 0, 0.62);
    transform: translate(-50%, -50%) scale(1.06);
}

/* 视频灯箱 */
.vp-lightbox {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}
.vp-lightbox .vp-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.78);
}
.vp-lightbox .vp-dialog {
    position: relative;
    z-index: 1;
    width: min(92vw, 960px);
    max-height: 90vh;
    background: #000;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}
.vp-lightbox .vp-stage {
    width: 100%;
    aspect-ratio: 16 / 9;
    max-height: 90vh;
}
.vp-lightbox .vp-stage .artplayer-app {
    width: 100%;
    height: 100%;
}
.vp-lightbox .vp-close {
    position: absolute;
    top: 8px;
    right: 10px;
    z-index: 20;
    width: 36px;
    height: 36px;
    border: 2px solid rgba(255, 255, 255, 0.9);
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    pointer-events: auto;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.vp-lightbox .vp-close:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}
.vp-lightbox .vp-close:hover {
    background: rgba(0, 0, 0, 0.8);
}

/* ---------------- 布局组件 ---------------- */
.columns-block {
    display: grid;
    gap: 14px;
    padding: 16px;
    background: #fff;
}
.column-item {
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid #f0f0f0;
}
.column-img {
    height: 110px;
    position: relative;
    overflow: hidden;
}
.column-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.column-title {
    padding: 8px 10px 0;
    font-size: 14px;
    font-weight: 600;
    color: #333;
}
.column-desc {
    padding: 4px 10px 10px;
    font-size: 12px;
    color: #909399;
}
/* 文字压在图上时，标题/描述改用叠层里的样式 */
.ct-title {
    font-size: 14px;
    font-weight: 600;
}
.ct-desc {
    font-size: 12px;
    opacity: 0.9;
}

/* ---------------- 图文组件（一张图 + 一段文案，四种排布） ---------------- */
.it-block {
    display: flex;
    width: 100%;
    /* ⚠️ 必须 border-box：行内样式带了 padding，默认 content-box 会让整块宽度
       变成 100% + 左右 padding，直接溢出父容器 —— 画布有这条、前台没有，
       就是「图文组件前后端布局不一致」的根因。 */
    box-sizing: border-box;
    background: #fff;
}
.it-media {
    position: relative;
    overflow: hidden;
    min-width: 0;
    min-height: 0;
    box-sizing: border-box;
    border-radius: 4px;
}
.it-media > a {
    display: block;
    width: 100%;
    height: 100%;
}
.it-media img {
    width: 100%;
    height: 100%;
}
.it-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    /* 与画布 BlockRender.vue 同口径（画布 .it-body 有这两条） */
    box-sizing: border-box;
    padding: 4px 0;
}
.it-body.align-left {
    text-align: left;
    align-items: flex-start;
}
.it-body.align-center {
    text-align: center;
    align-items: center;
}
.it-body.align-right {
    text-align: right;
    align-items: flex-end;
}
.it-title {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.35;
    word-break: break-word;
}
.it-desc {
    font-size: 14px;
    line-height: 1.65;
    word-break: break-word;
}
.it-btn-wrap {
    display: flex;
}
.it-btn-wrap.align-left {
    justify-content: flex-start;
}
.it-btn-wrap.align-center {
    justify-content: center;
}
.it-btn-wrap.align-right {
    justify-content: flex-end;
}
.it-btn {
    display: inline-block;
    padding: 8px 20px;
    border-radius: 4px;
    font-size: 14px;
}

.catnav-section {
    padding: 16px;
    background: #fff;
}
.catnav-grid {
    display: grid;
    gap: 12px;
}
.catnav-grid.layout-list {
    grid-template-columns: 1fr !important;
}
.catnav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px;
    border: 1px solid #f0f0f0;
    border-radius: 8px;
}
.cn-thumb {
    width: 56px;
    height: 56px;
    border-radius: 8px;
    overflow: hidden;
    flex-shrink: 0;
    background: #f2f3f5;
}
.cn-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.cn-name {
    font-size: 14px;
    font-weight: 600;
    color: #333;
}
.cn-sub {
    font-size: 12px;
    color: #909399;
    margin-top: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------------- 互动组件 ---------------- */
.inquiry-block {
    padding: 20px;
    background: #fff;
}
/* 左 / 中 / 右：标题跟 text-align，表单靠 margin 挪（与画布 .inquiry-block.align-* 同口径） */
.inquiry-block.align-center {
    text-align: center;
}
.inquiry-block.align-right {
    text-align: right;
}
.inquiry-block.align-center .inquiry-form {
    margin-left: auto;
    margin-right: auto;
}
.inquiry-block.align-right .inquiry-form {
    margin-left: auto;
    margin-right: 0;
}
.inquiry-title {
    font-size: 18px;
    font-weight: 600;
    color: #222;
    margin-bottom: 16px;
}
.inquiry-form {
    /* 与画布 .inquiry-form 同宽；默认左对齐（margin-right:auto） */
    max-width: 620px;
    margin-right: auto;
}
.inquiry-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 12px;
}
.inquiry-label {
    width: 110px;
    flex-shrink: 0;
    text-align: right;
    font-size: 13px;
    color: #606266;
    line-height: 32px;
}
.inquiry-label .req {
    color: var(--theme);
    margin-left: 2px;
}
.inquiry-input {
    flex: 1;
    min-width: 0;
    border: 1px solid #dcdfe6;
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 13px;
    color: #303133;
    background: #fff;
    outline: none;
    resize: vertical;
    font-family: inherit;
}
textarea.inquiry-input {
    height: 76px;
}
.inquiry-btn {
    margin-left: 122px;
    height: 36px;
    padding: 0 26px;
    border: 0;
    border-radius: 18px;
    background: var(--theme);
    color: #fff;
    font-size: 14px;
    cursor: pointer;
}
.inquiry-tip {
    margin: 10px 0 0 122px;
    font-size: 12px;
    color: #909399;
}

.contact-block {
    padding: 16px;
    background: #fff;
}
.contact-list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}
.contact-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px;
    border-radius: 8px;
    background: #fafafa;
}
.ci-icon {
    font-size: 22px;
}
.ci-label {
    font-size: 12px;
    color: #909399;
}
.ci-value {
    font-size: 14px;
    color: #333;
    font-weight: 500;
}

/* ---------------- 下载模块（与商家端 BlockRender.vue 的 .dl-* 逐条一致） ----------------
   三种布局共用同一套类名，靠 .dl-list / .dl-cards / .dl-btns 区分：
     list   纵向列表：缩略图 + 名称/描述 + 按钮
     card   图文卡片：封面图 + 标题/描述 + 按钮（一行 N 列，N 由行内 grid-template-columns 给）
     button 纯按钮：只显示一排按钮
   ⚠️ 画布是「所见」的基准：改这里的任何一条，都要同步改 BlockRender.vue 的同名类。 */
.dl-block {
    width: 100%;
    background: #fff;
    box-sizing: border-box;
}
.dl-list {
    display: flex;
    flex-direction: column;
    width: 100%;
}
.dl-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid #f0f0f0;
    border-radius: 8px;
    background: #fff;
}
.dl-thumb {
    width: 44px;
    height: 44px;
    border-radius: 6px;
    object-fit: cover;
    flex-shrink: 0;
}
/* 没有封面图时的文件图标占位（与画布同一个 📄） */
.dl-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    background: #f5f7fa;
}
.dl-info {
    flex: 1;
    min-width: 0;
}
.dl-name {
    font-size: 14px;
    font-weight: 600;
    color: #333;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dl-desc {
    font-size: 12px;
    color: #909399;
    line-height: 1.5;
    margin-top: 2px;
}
.dl-btn {
    display: inline-block;
    padding: 6px 18px;
    border-radius: 16px;
    font-size: 13px;
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
    cursor: pointer;
}
.dl-cards {
    display: grid;
    width: 100%;
}
.dl-card {
    border: 1px solid #f0f0f0;
    border-radius: 8px;
    overflow: hidden;
    background: #fff;
    display: flex;
    flex-direction: column;
}
.dl-card-img {
    height: 140px;
    background: #f5f5f5;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dl-card-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.dl-card-ph {
    font-size: 34px;
    color: #c0c4cc;
}
.dl-card-body {
    padding: 10px 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
}
/* 卡片里的按钮吸底左对齐，多卡片高度不一时按钮也在同一水平线 */
.dl-card-body .dl-btn {
    align-self: flex-start;
    margin-top: auto;
}
.dl-btns {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    width: 100%;
}
/* 名称 / 描述对齐：每项独立（编辑器 it.align → dl-align-*），只作用于文字与卡片内按钮 */
.dl-align-left {
    text-align: left;
}
.dl-align-center {
    text-align: center;
}
.dl-align-right {
    text-align: right;
}
.dl-card-body.dl-align-left .dl-btn {
    align-self: flex-start;
}
.dl-card-body.dl-align-center .dl-btn {
    align-self: center;
}
.dl-card-body.dl-align-right .dl-btn {
    align-self: flex-end;
}

/* ---------------- 文件预览（iframe 直接加载 Excel / Word / PDF 等） ---------------- */
.fp-block {
    width: 100%;
    box-sizing: border-box;
    padding: 12px 16px;
    background: #fff;
}
.fp-frame-wrap {
    width: 100%;
    background: #f5f5f5;
    border-radius: 6px;
    overflow: hidden;
}
.fp-frame {
    display: block;
    width: 100%;
    height: 100%;
    border: none;
    background: #fff;
}

/* ---------------- 下载模块 · 在线阅读弹层（与骨架里的 #dlPreview 对应） ---------------- */
.dl-modal[hidden] {
    display: none !important;
}
.dl-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dl-modal-mask {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
}
.dl-modal-box {
    position: relative;
    z-index: 1;
    width: min(860px, 92vw);
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
}
.dl-modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid #eef0f4;
}
.dl-modal-title {
    font-size: 15px;
    font-weight: 600;
    color: #1f2329;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dl-modal-x {
    border: 0;
    background: transparent;
    font-size: 22px;
    line-height: 1;
    color: #909399;
    cursor: pointer;
    padding: 0 4px;
}
.dl-modal-body {
    flex: 1;
    min-height: 0;
    background: #f5f5f5;
}
.dl-preview-frame {
    display: block;
    width: 100%;
    height: 65vh;
    max-height: calc(88vh - 120px);
    border: none;
    background: #f5f5f5;
}
.dl-modal-foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 10px 16px;
    border-top: 1px solid #eef0f4;
}
.dl-modal-btn {
    height: 32px;
    padding: 0 18px;
    border: 1px solid #dcdfe6;
    border-radius: 16px;
    background: #fff;
    color: #606266;
    font-size: 13px;
    cursor: pointer;
}
.dl-modal-dl {
    height: 32px;
    line-height: 32px;
    padding: 0 18px;
    border-radius: 16px;
    background: #165dff;
    color: #fff;
    font-size: 13px;
    text-decoration: none;
}

/* ============================================================================
 * 区块响应式（窄屏）
 * ----------------------------------------------------------------------------
 * ⚠️ 区块的「列数 / 高度 / grid-template-areas」全部是后端写在**行内 style**上的，
 *    行内样式优先级高于这里的规则，所以每一条都必须带 !important。
 * ⚠️ 改 grid-template-columns 时必须同时清掉 grid-template-areas 与 cell 的 grid-area，
 *    否则区域名还在，列数改了布局照样错乱。
 * ⚠️ 高度一律用 vw 而不是 auto：轮播图所有幻灯片都在 DOM 里，
 *    height:auto 会让它们纵向全部展开（页面被拉得老长）。
 * ========================================================================== */
@media (max-width: 900px) {
    /* 轮播图 */
    .banner {
        height: 46vw !important;
        min-height: 170px !important;
        max-height: 380px !important;
    }

    /* 图片广告：3 / 4 列先降到 2 列（1 / 2 列本来就很窄，不动） */
    .ad-grid.ad-cols-3,
    .ad-grid.ad-cols-4 {
        grid-template-columns: repeat(2, 1fr) !important;
        grid-template-areas: none !important;
    }
    .ad-grid.ad-cols-3 .ad-cell,
    .ad-grid.ad-cols-4 .ad-cell {
        grid-area: auto !important;
    }

    /* 商品 / 多列图文 / 分类导航 */
    .goods-grid,
    .columns-block,
    .catnav-grid {
        grid-template-columns: repeat(2, 1fr) !important;
    }
    .goods-img {
        height: 34vw;
        max-height: 160px;
    }
    /* 列图高度是行内 px，窄屏改用比例，图不会被压扁 */
    .column-img {
        height: auto !important;
        aspect-ratio: 4 / 3;
    }

    /* 视频 / 商品橱窗 / 图文组件 */
    .video-cell {
        height: 52vw !important;
        min-height: 190px !important;
        max-height: 380px !important;
    }
    .showcase {
        flex-direction: column;
    }
    .showcase-media {
        width: 100%;
        height: 52vw !important;
        max-height: 320px;
    }
    .showcase-btn {
        width: 140px;
    }
    .it-block {
        flex-direction: column !important;
    }
    .it-media {
        flex: 0 0 auto !important;
        height: 46vw !important;
        max-height: 240px;
    }
    .it-title {
        font-size: 18px;
    }
    .it-desc {
        font-size: 13px;
    }

    /* 标题 / 表单 */
    .section-title {
        font-size: 16px;
        margin-bottom: 10px;
    }
    .tb-title {
        font-size: 16px;
    }
    .inquiry-block {
        padding: 14px;
    }
    .inquiry-label {
        width: 80px;
    }
    .inquiry-btn,
    .inquiry-tip {
        margin-left: 92px;
    }
    /* 下载模块：图文卡片最多两列（行内 grid-template-columns 需 !important 覆盖） */
    .dl-cards {
        grid-template-columns: repeat(2, 1fr) !important;
    }
    .contact-list {
        grid-template-columns: 1fr;
    }
    .goods-section,
    .catnav-section {
        padding: 12px;
    }
}

@media (max-width: 560px) {
    /* 图片广告：单列 + 高度交给内容 */
    .ad-grid {
        grid-template-columns: 1fr !important;
        grid-template-areas: none !important;
        height: auto !important;
    }
    .ad-grid .ad-cell {
        grid-area: auto !important;
    }
    /* 不锁 aspect-ratio：单列时图片按原始比例铺满宽度最自然，
       只兜一个最小高度，防止素材没加载出来时格子塌成 0 */
    .ad-grid .ad-media {
        min-height: 140px;
    }
    .ad-caption {
        font-size: 12px;
    }

    /* 多列图文与分类导航在手机上改单列；商品保持两列（电商习惯） */
    .columns-block,
    .catnav-grid {
        grid-template-columns: 1fr !important;
    }
    .goods-grid {
        gap: 10px;
    }
    .goods-name {
        font-size: 13px;
    }
    .goods-price {
        font-size: 13px;
    }

    .banner {
        height: 56vw !important;
        min-height: 150px !important;
    }
    .video-cell {
        height: 56vw !important;
        min-height: 180px !important;
    }
    .it-media {
        height: 56vw !important;
        max-height: 200px;
    }
    .showcase-media {
        height: 62vw !important;
    }
    .column-img {
        aspect-ratio: 3 / 2;
    }

    .inquiry-label {
        width: 70px;
    }
    .inquiry-btn,
    .inquiry-tip {
        margin-left: 82px;
    }
    .contact-list {
        grid-template-columns: 1fr;
    }
    /* 下载模块：卡片单列；列表行允许换行，避免按钮把名称挤没 */
    .dl-cards {
        grid-template-columns: 1fr !important;
    }
    .dl-row {
        flex-wrap: wrap;
    }
    .dl-info {
        flex: 1 1 60%;
    }
    .dl-card-img {
        height: 42vw;
        max-height: 180px;
    }
}
