/* ===== Block 1 from index.html =====
   ★ 首页「Featured Products」卡片改版：套用产品列表页的卡片观感
     （白底卡片 / 宽幅图 / 深绿加粗标题 / "View products →" 链接）
     ----------------------------------------------------------------------------
     本次目标（用户要求）：
       1. 卡片样式对齐产品列表页效果
       2. 每张卡片加 "View products →" 链接文字
       3. **PC 端「标题 + View products →」横排（同一行，标题左、链接右）**
          手机上仍为竖排，避免挤在一起

     ★★ 为什么这里必须用 !important（踩坑记录，别删）
     模块自己的样式表（由可视化编辑器生成，bzd 的 static/css/*.css）里有：

         .ly_products_22 .products_box              { display:block; text-align:center }
         .ly_products_22 .products_box .themes_prod { display:inline-block; margin-right:5px }

     这两条与本文件的 .ly_products_22 .products_box / .themes_prod
     **特异性完全相同（都是 2 个 class）**。同特异性下谁的 <link> 在后谁生效，
     而模块 CSS 的 <link> 就写在 home-inline.css 之后 —— 于是：
         · 我们的 display:grid 被压回 display:block
         · 卡片被压回 display:inline-block，按内容宽度排列
           （实测 4 张卡宽度 146/116/132/119px 各不相同，根本不是栅格）
         · 连带"标题与 View products 横排"也失效（卡片太窄，文字换行后上下排）
     所以这里统一：
         · 选择器加 [data-visual-id="54980"] 提升一层特异性
         · 布局关键属性（display / width / float / grid-template-columns）加 !important
     双保险，模块 CSS 重新生成多少次都不受影响。 */

/* ---- 栅格容器：PC 4 列 / 平板 3 列 / 手机 2 列 ---- */
.ly_products_22[data-visual-id="54980"] .products_box {
    display: grid !important;
    grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
    gap: 24px !important;
    align-items: stretch;
    text-align: left !important;        /* 覆盖模块 CSS 的 text-align:center */
    margin-top: 30px;
}
/* 覆盖模板/旧样式里可能残留的浮动与百分比宽度 */
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod {
    display: flex !important;           /* 压过模块 CSS 的 display:inline-block */
    width: auto !important;
    margin-right: 0 !important;
    margin-left: 0 !important;
    float: none !important;
    box-sizing: border-box;
    flex-direction: column;
    background: #fff;
    border: 1px solid #e8eae9;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
    text-align: left;
    transition: box-shadow .25s ease, transform .25s ease;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod:hover {
    box-shadow: 0 10px 26px rgba(0, 0, 0, .10);
    transform: translateY(-2px);
}

/* ---- 图片区：保持正方形（与 800×800 原图同比例，不变形、不裁切、不留白） ----
   ★ 演变记录（别删，避免来回改）：
     · 模板内联原值 padding-top:120%（偏方）→ 第 11 版曾改成 68%（宽幅），
       结果正方形原图被横向拉宽填满，盘子**被压扁变形**。
     · 第 13 版定为 100%：容器 = 正方形 = 原图比例，
       图片按原比例完整显示，既不变形也不裁切。
     · 若日后想改图片区高矮，改这个百分比即可（100% = 正方形）。
       注意：非 100% 时必须把 img 的 object-fit 设成 contain（见下），
       否则容器比例与图片比例不一致就会变形。 */
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .pic_box {
    width: 100%;
    overflow: hidden;
    background: #f6f8f7;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .compute_process_img {
    padding-top: 100% !important;       /* ★ 正方形（原图 800×800，1:1） */
}
/* 中间两层（a 与 compute_process_img）也要显式撑满，
   避免任何一层按内在尺寸收缩后又把 img 带偏 */
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .compute_process_img > a {
    display: block !important;
    width: 100% !important;
    height: 100% !important;
}
/* ★★ 图片：宽高撑满容器 + contain 保持原比例（踩坑记录，别删）
   模板给 img 写的是内联样式 style="top:0;left:0;right:0;bottom:0;margin:auto;"。
   这套「四边归零 + margin:auto」在 width/height 都是 auto 时**不会拉伸** ——
   Chrome 按内在比例算尺寸再用 margin:auto 居中（实测容器 340×231 时
   图片只渲染成 231×231，两侧各空 54px，表现为「两侧留白」）。
   所以必须显式给 width/height:100% 把 auto 覆盖掉。
   而 object-fit 的选择取决「容器比例 vs 图片比例」：
     · 容器 = 正方形（padding-top:100%）+ 原图 800×800 正方形
       → contain 与 cover 视觉等价（都完整显示）。这里用 **contain**，
         语义上「完整显示、绝不裁切也不变形」，日后再调容器比例也不会突然变形。
     · 若容器是宽幅（如 68%）→ 必须 contain，否则 cover 会把盘子拉扁。 */
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .pic_box img {
    width: 100% !important;
    height: 100% !important;
    object-fit: contain !important;     /* ★ 保持原比例，不变形不裁切 */
    object-position: center center !important;
    transition: transform .5s ease;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod:hover .pic_box img {
    transform: scale(1.05);
}

/* ---- 文字区：标题 + View products ---- */
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .name {
    padding: 14px 16px 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1 1 auto;
    text-align: left;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .name .themes_products_title {
    display: block;
    text-align: left;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .name h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    line-height: 1.35;
    color: #14532d;                     /* 深绿，对齐参考稿 */
    text-align: left;
    /* 标题最多两行，超出省略，保证卡片等高时视觉整齐 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/* "View products →" 链接 */
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .prod_view_more {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: #2f6b4f;
    text-decoration: none;
    white-space: nowrap;
    position: relative;
    transition: color .2s ease, gap .2s ease;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .prod_view_more .prod_view_arrow {
    display: inline-block;
    transition: transform .2s ease;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod:hover .prod_view_more {
    color: #14532d;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod:hover .prod_view_more .prod_view_arrow {
    transform: translateX(3px);
}
/* 下划线：伪元素做一条从左展开的细线，比 text-decoration 更可控 */
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod .prod_view_more::after {
    content: "";
    position: absolute;
    left: 0; right: auto; bottom: -2px;
    width: 0; height: 1px;
    background: currentColor;
    transition: width .25s ease;
}
.ly_products_22[data-visual-id="54980"] .products_box .themes_prod:hover .prod_view_more::after {
    width: 100%;
}

/* ---- ★ PC 端：标题与 View products 横排（同一行，标题左 / 链接右） ---- */
@media (min-width: 769px) {
    .ly_products_22[data-visual-id="54980"] .products_box .themes_prod .name {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        flex-wrap: wrap;                /* 卡片极窄时允许换行兜底 */
    }
    .ly_products_22[data-visual-id="54980"] .products_box .themes_prod .name .themes_products_title {
        flex: 1 1 auto;
        min-width: 0;                   /* 允许标题收缩并触发省略号 */
    }
    .ly_products_22[data-visual-id="54980"] .products_box .themes_prod .prod_view_more {
        flex: 0 0 auto;                 /* 链接不被压缩 */
    }
}

/* PC 中等屏：4 列变 3 列，卡片不至于太窄 */
@media (max-width: 1100px) {
    .ly_products_22[data-visual-id="54980"] .products_box {
        grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
        gap: 20px !important;
    }
}

/* 手机 / 平板：2 列，标题与链接改竖排 */
@media (max-width: 768px) {
    .ly_products_22[data-visual-id="54980"] .products_box {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
        gap: 12px !important;
    }
    .ly_products_22[data-visual-id="54980"] .products_box .themes_prod .name {
        padding: 10px 12px 12px;
        gap: 4px;
    }
    .ly_products_22[data-visual-id="54980"] .products_box .themes_prod .name h3 {
        font-size: 14px;
    }
    .ly_products_22[data-visual-id="54980"] .products_box .themes_prod .prod_view_more {
        font-size: 12px;
    }
}

/* ===== Block 2 from index.html ===== */
.stat_bar_wrap{
    width:100%;
    background: url(https://css02.v15cdn.com/m413/purple/ab-bg2.webp) #1f86c9;
    background-size:cover;
    background-position:center;
    padding:50px 20px;
    box-sizing:border-box;
    position:relative;
    overflow:hidden;
    font-family:Arial,Helvetica,sans-serif;
}
/* 背景水印图标 */
.stat_bar_wrap::before{
    content:"";
    position:absolute;
    inset:0;
    background-image:
        radial-gradient(circle at 5% 20%, rgba(255,255,255,0.06) 0%, transparent 8%),
        radial-gradient(circle at 15% 70%, rgba(255,255,255,0.05) 0%, transparent 10%),
        radial-gradient(circle at 25% 30%, rgba(255,255,255,0.06) 0%, transparent 8%),
        radial-gradient(circle at 35% 80%, rgba(255,255,255,0.05) 0%, transparent 10%),
        radial-gradient(circle at 45% 25%, rgba(255,255,255,0.06) 0%, transparent 8%),
        radial-gradient(circle at 55% 75%, rgba(255,255,255,0.05) 0%, transparent 10%),
        radial-gradient(circle at 65% 35%, rgba(255,255,255,0.06) 0%, transparent 8%),
        radial-gradient(circle at 75% 80%, rgba(255,255,255,0.05) 0%, transparent 10%),
        radial-gradient(circle at 85% 20%, rgba(255,255,255,0.06) 0%, transparent 8%),
        radial-gradient(circle at 95% 65%, rgba(255,255,255,0.05) 0%, transparent 10%);
    pointer-events:none;
}
.stat_bar_inner{
    max-width:1440px;
    margin:0 auto;
    display:grid;
    grid-template-columns:repeat(4,1fr);
    gap:20px;
    position:relative;
    z-index:2;
}
.stat_item{
    text-align:center;
    color:#fff;
}
.stat_icon{
    width:56px;
    height:56px;
    margin:0 auto 16px;
    display:flex;
    align-items:center;
    justify-content:center;
}
.stat_icon svg{
    width:100%;
    height:100%;
    fill:#fff;
}
.stat_number{
    font-size:clamp(32px,3.5vw,48px);
    font-weight:bold;
    line-height:1.1;
    margin-bottom:8px;
}
.stat_label{
    font-size:clamp(14px,1.2vw,18px);
    opacity:0.95;
}
/* 平板适配 */
@media(max-width:992px){
    .stat_bar_inner{
        grid-template-columns:repeat(2,1fr);
        gap:36px 20px;
    }
}
/* 手机端适配 */
@media(max-width:576px){
    .stat_bar_wrap{
        padding:36px 16px;
    }
    .stat_bar_inner{
        grid-template-columns:repeat(2,1fr);
        gap:30px;
    }
    .stat_icon{
        width:44px;
        height:44px;
        margin-bottom:12px;
    }
}

/* ============================================================================
   ===== 首页首屏 Banner：电脑端 / 移动端 拆成两套轮播，互斥显示 =====
   ----------------------------------------------------------------------------
   模板 /template/default/zizhu/index.html 里是两个并列的轮播模块，各自拥有
   **独立的 data-visual-id**：

     电脑端  ->  data-visual-id="54978"   {pboot:slide num=3 gid=1}
                 高度 padding-top:42.42%
     移动端  ->  data-visual-id="54979"   {pboot:slide num=3 gid=6}
                 高度 padding-top:65%

   【★ 关键：本文件不再依赖模板里的 .banner-pc / .banner-m 类 ★】
   上一版靠外层 div 上加 .banner-pc / .banner-m 来区分两套轮播。
   但外层 div 的 class 是「可视化编辑器按模块设置」生成的，
   只要在后台重新保存该模块，class 就会被重置 —— 实测 .banner-pc
   就是这样被抹掉的，导致手机端两个 banner 又叠在一起。

   所以本版**主用 data-visual-id 定位**：
     data-visual-id 在内层 .ly_carousel_28 上，是生成器分配的模块唯一标识，
     轮播 JS 正是靠它初始化（home-carousel.js 里全部选择器都基于它）。
     编辑器一旦删掉它，轮播本身就废了 —— 所以它是本页最稳定的锚点。

   用 :has() 从内层属性反向选中外层容器：
     .visual_plugins_container:has(> .ly_carousel_28[data-visual-id="54979"])

   同时保留 .banner-pc / 类名规则作兜底：万一将来 :has() 在某些环境不可用，
   只要类名还在（后台未重存模块时）也能正常工作。

   【为什么不按"模块顺序"兜底】
   本来想用 nth-of-type 加一层保险，实测不可行：
   {include file=head.html} 会展开出一批额外 div，且 {pboot:slide} 生成的
   .carousel_tab 也是 body 级 div，导致"第几个 carousel"会随 include 与
   slide 数量漂移，硬编码顺序反而会误伤其它模块。故放弃顺序兜底。

   【:has() 浏览器支持】
   Chrome/Edge 105+、Safari 15.4+、Firefox 121+（2023 年起全面可用）。
   个别老浏览器不支持时，会回落到 .banner-m 类名规则，行为与上一版一致。

   【高度只有一个"真相"：模板的内联 style】
   高度由模板内联的 padding-top 决定（.carousel_wrapper 与
   .compute_process_img 各一处，两处必须一致），本文件不参与高度。
   插件初始化时会读 item 真实高度写进 wrapper 的 height 并把 padding-top
   归零；被 display:none 隐藏的那一套读不到尺寸，就不写 height，
   继续由 padding-top 撑开 —— 两种结果一致，不冲突。

   断点沿用全站统一的 1000px（与 header-inline.css、轮播基础样式
   fd5f9377….css 里的 @media screen and (max-width:1000px) 一致）。

   为什么要 !important：这两个模块的样式表在 <body> 里、本文件在 <head>，
   同权重规则后者会被前者盖掉，所以关键规则统一加 !important。
   ============================================================================ */

/* ===== 首页 banner：横向滑动轨道 + 无缝循环（全端生效，自动播放 4 秒） =====
   用 :is() 让电脑端(54978) 与 移动端(54979) 共用同一套轨道规则。 */
:is(.ly_carousel_28[data-visual-id="54978"],
    .ly_carousel_28[data-visual-id="54979"]) .carousel_wrapper {
    overflow: hidden;
}
:is(.ly_carousel_28[data-visual-id="54978"],
    .ly_carousel_28[data-visual-id="54979"]) .carousel_wrapper .carousel_box {
    display: flex !important;
    flex-wrap: nowrap !important;
    align-items: flex-start;
    height: auto !important;
    overflow: visible !important;
    /* 逐帧位移靠 transform 合成层完成，避免触发 layout；backface 一同提升，
       手机上滑动期间不出现边缘闪白/抖动。 */
    will-change: transform;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}
:is(.ly_carousel_28[data-visual-id="54978"],
    .ly_carousel_28[data-visual-id="54979"]) .carousel_wrapper .carousel_box .carousel_item {
    position: relative !important;
    flex: 0 0 100% !important;
    width: 100% !important;
    min-width: 0 !important;          /* 防止内容（长图/横向溢出）把 flex 项撑宽，导致"半张图"卡在缝里 */
    opacity: 1 !important;
    z-index: auto !important;
    pointer-events: auto !important;
    transform: none !important;
    transition: none !important;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

/* ===== 手机端 banner 通栏（左右不留白）=====
   【问题】手机端 banner 左右各空 24px，图片没铺满屏。
   【来源】全局 .wide 的响应式规则链：
       .wide                                { width:1440px; margin:0 auto }
       @media (max-width:1480px) .wide      { width:auto;
                                              padding-left:20px; padding-right:20px;
                                              box-sizing:border-box }
       @media (max-width:1000px) .wide      { width:98% }
   390px 下：.wide 宽 382px（98%）且有 margin:0 auto 摊出的 3.9px，
   再叠加未被覆盖的 padding-left/right:20px → 内容从 4+20=24px 才开始，
   于是 .section / .carousel_wrapper 只剩 342px。

   【为什么 PC 端没这个问题】PC 模块自己生成的模块样式
   ab1e85091db644a24537120575e490f1.css 里显式写了
       .ly_carousel_28[data-visual-id="54978"] .wide .section { padding-left:0%; padding-right:0% }
   —— 但那条**只作用于 54978（电脑端）**，移动端 54979 没有对应规则，
   所以只有手机端留白。这里给移动端补上，并把 .wide 的 padding 一并归零。

   【写法】用「内层 id 反选」而不是依赖外层 class（外层 class 会被
   可视化编辑器重置，见下面互斥显示一节的说明），保证重存模块也不失效。
   外层 .wide 无 id，只能由内层祖先反查：`.ly_carousel_28[id] .wide`。 */
html body .ly_carousel_28[data-visual-id="54979"] .wide {
    width: 100% !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}
html body .ly_carousel_28[data-visual-id="54979"] .wide .section {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* ===== 手机端 banner：不控制高度，按图片自身比例自适应 =====
   【需求】宽度 100%，高度不写死 —— 图片多高就显示多高。
   用户上传的图尺寸一致（当前 750x703，比例 1.0669），所以每张显示高度都一样。

   【为什么不能简单删掉 height 就完事】
   基础样式把这条链上的每一层都设成了"不占高度"：
       .carousel_wrapper   { position:relative }        ← 高度靠内容撑
       .carousel_box       { position:absolute; height:100% }   ← 绝对定位，不撑高
       .carousel_item      { position:absolute }               ← 绝对定位，不撑高
       .compute_process_img{ 内联 padding-top:% }               ← 用百分比占位撑高
   全都绝对定位 / 百分比占位，**没有一层是由图片自身撑开的**。
   所以直接删掉 height 会让 wrapper 塌成 0 高，图片不可见。

   【解法：让图片回到正常文档流】
   把 compute_process_img 变回 static + 清掉 padding-top，
   图片改成 static + width:100% + height:auto。
   这样图片的固有比例（750:703）会自然决定整条链的高度，实现"图多高就多高"。

   【为什么仍要 overflow:hidden】
   .carousel_wrapper 保留 overflow:hidden 用于裁掉轨道两侧的克隆项；
   图片自身的比例决定 wrapper 高度，两者不冲突。

   【为什么 sticky/absolute 的 .carousel_box 还能工作】
   .carousel_box 被我们改成了 flex（见上方轨道规则），但仍是 absolute。
   这里把它改成 static + 让 wrapper 由内容撑开，轨道照样横向排列。 */
html body .ly_carousel_28[data-visual-id="54979"] .carousel_wrapper {
    height: auto !important;
    padding-top: 0 !important;
}
html body .ly_carousel_28[data-visual-id="54979"] .carousel_box {
    position: static !important;
    height: auto !important;
}
html body .ly_carousel_28[data-visual-id="54979"] .carousel_img,
html body .ly_carousel_28[data-visual-id="54979"] .compute_item_img,
html body .ly_carousel_28[data-visual-id="54979"] .compute_process_img {
    height: auto !important;
    padding-top: 0 !important;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}
/* compute_process_img 在模块 CSS 里是 display:flex，align-items 默认 stretch，
   这里补一条 align-items:flex-start，避免它给里面的 a/img 加额外垂直偏移。 */
html body .ly_carousel_28[data-visual-id="54979"] .compute_process_img {
    align-items: flex-start !important;
}
html body .ly_carousel_28[data-visual-id="54979"] .compute_process_img a,
html body .ly_carousel_28[data-visual-id="54979"] .carousel_wrapper img {
    position: static !important;
    display: block !important;
    width: 100% !important;
    height: auto !important;
    max-width: 100% !important;
    max-height: none !important;
    object-fit: initial !important;
    /* ★ margin 必须归零：
       插件初始化时会按「它以为的图片高度」给 img 写一个 margin-top 做垂直居中，
       实测 img 拿到 margin-top:11.2px，于是图片顶部露出 11.2px 空白
       （容器 .carousel_wrapper 又是 overflow:hidden，那 11.2px 就是一条灰白横带，
        同时图片底部被裁掉同样高度）。
       我们已经是"高度随图自适应"，不需要任何居中偏移，一并归零。 */
    margin: 0 !important;
}

/* ===== anti-revert-carousel-pad : 轮播上边距归零（防回退覆盖）=====
   可视化编辑器按模块设置生成的 static/css/ab1e85091db644a24537120575e490f1.css
   里写的是 padding-top:20px，重新保存该模块会被重新生成、20px 会写回来。
   本文件是人工维护的模板样式且只在首页加载，用「更高特异性 + !important」压过它，
   模块 CSS 被重新生成多少次都不受影响。手机端本来就是 0，这里全端统一为 0。 */
html body :is(.ly_carousel_28[data-visual-id="54978"],
              .ly_carousel_28[data-visual-id="54979"]) {
    padding-top: 0 !important;
}

/* ============================================================================
   ===== 互斥显示（核心）=====
   电脑端：默认显示电脑端轮播，隐藏移动端轮播。
   手机端：隐藏电脑端轮播，显示移动端轮播。

   ★ 不再写 .banner-m { display:none } —— 该选择器要匹配外层
     .visual_plugins_container，而外层 class 会被编辑器重置。
     改用 :has() 从内层 id 反向定位外层容器，编辑器改不动。
   ============================================================================ */

/* --- 电脑端（默认，不限断点）：隐藏移动端轮播 ---
   ① 主用：按内层 id 反向定位外层容器
   ② 兜底：保留类名规则 */
.visual_plugins_container:has(> .ly_carousel_28[data-visual-id="54979"]),
.visual_plugins_container.banner-m {
    display: none !important;
}

@media screen and (max-width: 1000px) {
    /* --- 手机 / 平板 ---
       隐藏电脑端（54978），显示移动端（54979）。 */

    .visual_plugins_container:has(> .ly_carousel_28[data-visual-id="54978"]),
    .visual_plugins_container.banner-pc {
        display: none !important;
    }

    .visual_plugins_container:has(> .ly_carousel_28[data-visual-id="54979"]),
    .visual_plugins_container.banner-m {
        display: block !important;
    }

    /* 轮播圆点离底边的距离：参考稿约 6%，基础样式里给的是 3%，这里跟随参考稿。
       视觉上觉得太低/太高，改这个百分比即可（也可以直接删掉这一条）。 */
    .visual_plugins_container:has(> .ly_carousel_28[data-visual-id="54979"]) .carousel_wrapper .tab_type_position,
    .banner-m .carousel_wrapper .tab_type_position {
        bottom: 6% !important;
    }
}
