/* ==========================================================================
   可视化编辑器「自建模块」样式合集
   --------------------------------------------------------------------------
   约定（2026-11-04 起）：
     1. 每个模块的样式在本文件里单独一段，用下面这种分节注释隔开，按模块 id 命名；
     2. 新增模块**不再**单独建 css 文件 —— 小体积样式合并进这里，HTTP 请求数只算 1；
     3. 例外：单个模块样式超过约 8–10KB（例如产品卡、图集这类重模块），
        才单独建 `assets/css/module-<id>.css` 并在 `inc/modules-assets.php` 里追加 enqueue，
        避免拖慢所有页面的首屏 CSS；
     4. 选择器统一写成「容器类 + 元素类」两层（特异性 0,2,0），压过父主题
        `.section h2` 这一级（0,1,1）的规则，不用 !important，也不外溢；
     5. 由 `inc/modules-assets.php` 统一 enqueue，版本号用 filemtime。

   已有分节：
     · [1] entrava-headline —— 文本标题（modules/text-headline.php）
     · [2] entrava-grid     —— 网格序号卡片（modules/grid-cards.php）
   ========================================================================== */


/* ==========================================================================
   [1] entrava-headline · 文本标题
       结构：.entrava-headline
               > .entrava-headline__eyebrow                    （小徽标 + 圆点）
               > .entrava-headline__title                      （整块只一个 H 标签）
                   > .entrava-headline__line--bold / --thin    （逐行，可 <br> 分行）
               > .entrava-headline__text                       （普通摘要，wpautop）
   ========================================================================== */

/* 徽标行：圆点 + 字距拉开的全大写小字 */
.entrava-headline .entrava-headline__eyebrow {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 12px;
	padding: 0;
	font-size: 13px;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #e8622c; /* 后台「徽标高亮色」留空时的默认值 */
}

/* 项目符号：圆点。颜色跟着徽标文字走（currentColor），改一个色两处同步 */
.entrava-headline .entrava-headline__eyebrow::before {
	content: "";
	flex: 0 0 auto;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
}

/* 标题块：两行共用这一个标签，字号/行高在这里定；粗细交给行内 span。
   字号优先取后台「标题字号」注入的 --eh-title-size，没填就自动适应。 */
.entrava-headline .entrava-headline__title {
	margin: 0;
	padding: 0;
	font-size: var(--eh-title-size, clamp(28px, 3.6vw, 44px));
	font-weight: 400; /* 兜底：父主题 `.section h2` 的 700 不许漏下来 */
	line-height: 1.18;
	letter-spacing: -0.015em;
	color: inherit;
}

/* 逐行：加粗行 / 细体行各一套，后台两个开关直接对应这两个类 */
.entrava-headline .entrava-headline__line--bold {
	font-weight: 600;
}

.entrava-headline .entrava-headline__line--thin {
	font-weight: 300;
}

/* 摘要正文：跟随正文的字号与颜色，只加行高，不做加粗/细体区分 */
.entrava-headline .entrava-headline__text {
	margin-top: 18px;
	font-size: inherit;
	font-weight: 400;
	line-height: 1.75;
	color: inherit;
}

.entrava-headline .entrava-headline__text p {
	margin: 0 0 12px;
}

.entrava-headline .entrava-headline__text p:last-child {
	margin-bottom: 0;
}

/* 对齐：左对齐是默认，容器上不加类；居中 / 右对齐各一个类，一次管住徽标 / 标题 / 摘要。
   徽标是 flex 布局，text-align 管不到它，必须另给 justify-content，否则圆点会留在左边。 */
.entrava-headline.entrava-headline--align-center {
	text-align: center;
}

.entrava-headline.entrava-headline--align-center .entrava-headline__eyebrow {
	justify-content: center;
}

.entrava-headline.entrava-headline--align-right {
	text-align: right;
}

.entrava-headline.entrava-headline--align-right .entrava-headline__eyebrow {
	justify-content: flex-end;
}

@media (max-width: 767px) {
	.entrava-headline .entrava-headline__eyebrow {
		margin-bottom: 10px;
		font-size: 12px;
		letter-spacing: 0.12em;
	}

	.entrava-headline .entrava-headline__eyebrow::before {
		width: 5px;
		height: 5px;
	}

	.entrava-headline .entrava-headline__title {
		/* 桌面值只在 min-width:768px 里注入，所以这里拿不到就退回 26px；
		   用户在面板里单独设了手机字号时，那条规则会覆盖这个 fallback */
		font-size: var(--eh-title-size, 26px);
		line-height: 1.25;
		letter-spacing: -0.01em;
	}

	.entrava-headline .entrava-headline__text {
		margin-top: 14px;

		/* 折行时尽量不让最后一行只剩一两个词（Chrome 117+ / Safari 17.5+ 生效，其余浏览器直接忽略） */
		text-wrap: pretty;
	}

	/* 摘要里的手动换行只服务桌面排版：
	   后台在摘要 textarea 里敲一次回车，wpautop 就会输出一个 <br />；
	   桌面列宽大，断在句中还算整齐，但手机正文宽度只有 300 多 px，
	   硬断行会让前半句先自然折一次、后半句只剩三五个词单独占一行，看着很碎。
	   手机端把 <br /> 隐藏即可：紧随其后的换行空白会被折叠成一个空格，
	   文字按容器宽度自然折行，不会把单词粘在一起；桌面与平板完全不受影响。 */
	.entrava-headline .entrava-headline__text br {
		display: none;
	}
}


/* ==========================================================================
   [2] entrava-grid · 网格序号卡片
       结构：.entrava-grid
               > .eg-cell                       （重复）
                   > .eg-idx                    （数字序号，或包一个 .eg-idx-icon 图标）
                   > .eg-title
                   > .eg-desc
       变体：v-line（网格线，默认）/ v-space（间距）/ v-card（独立卡片）
             / v-row（行式列表：一行一条 + 右侧按钮，序号与按钮各跨两行）
       CTA：v-row → .eg-cta（右侧方块按钮）；v-line / v-space / v-card → .eg-cta-link
            （格内「文字 + 箭头」）；四种外观共用「内容 → 条目」里的
            链接/文字/新窗口三个字段，留空不输出
       对齐：左对齐为默认；.is-center / .is-right 由后台字段加类（v-row 不输出）
       颜色：--eg-accent 由「序号颜色」注入；--eg-title-color / --eg-desc-color
             默认写死，后台「标题颜色 / 摘要颜色」填了才覆盖
   ========================================================================== */

.entrava-grid,
.entrava-grid * {
	/* 不依赖父主题有没有做过 `* { box-sizing: border-box }` 的重置：
	   少了这一条，格子的 padding 会加到列宽上，整排横向溢出 */
	box-sizing: border-box;
}

.entrava-grid {
	--eg-cols: 3;          /* 由 style() 注入，移动端固定 2 */
	--eg-pad-y: 26px;
	--eg-pad-x: 28px;
	--eg-accent: #e8622c;  /* 后台「序号颜色」留空时的默认值 */
	--eg-line: #e6e8eb;
	--eg-title-color: #1b1b1b;
	--eg-desc-color: #8b909b;

	display: grid;
	grid-template-columns: repeat(var(--eg-cols), minmax(0, 1fr));
	text-align: left;       /* 兜底：不让父主题的对齐规则漏进来 */
}

.entrava-grid.is-center {
	text-align: center;
}

.entrava-grid.is-right {
	text-align: right;
}

.entrava-grid .eg-cell {
	padding: var(--eg-pad-y) var(--eg-pad-x) calc(var(--eg-pad-y) + 4px);
	background: #fff;
	overflow-wrap: break-word;  /* 长型号/长单词在窄列里换行，不撑破格子 */
}

/* 序号：数字走字体，图标走 .eg-idx-icon（inline-block 才能跟随 text-align） */
.entrava-grid .eg-idx {
	display: block;
	margin: 0 0 12px;
	font-size: 13px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: 0.12em;
	color: var(--eg-accent);
	font-variant-numeric: tabular-nums;
}

.entrava-grid .eg-idx-icon {
	display: inline-block;
	font-size: 22px;
	line-height: 1;
	vertical-align: top;
}

/* 用图片当图标时统一尺寸；图片无法跟随「序号颜色」 */
.entrava-grid .eg-idx-icon img {
	display: block;
	width: 22px;
	height: 22px;
	object-fit: contain;
}

.entrava-grid .eg-title {
	margin: 0 0 6px;
	font-size: 16px;
	font-weight: 700;
	line-height: 1.35;
	letter-spacing: -0.005em;
	color: var(--eg-title-color);
}

.entrava-grid .eg-desc {
	margin: 0;
	font-size: 13px;
	line-height: 1.5;
	color: var(--eg-desc-color);
}

/* 变体 A · 网格线：外框由**容器自己的 border** 画，格子只画内部线。
   两个坑：
   1. 外框不能用 `inset box-shadow` —— 内阴影绘制在父元素背景之上、子元素之下，
      格子铺满后白底会把右边和下边那两条阴影盖掉，看着像「没有外框」；
   2. 每行最后一列不画 border-right、最后一行不画 border-bottom，
      否则格子线正好压在容器边框内侧，成为两条贴在一起的线（用户报的「双线」）。
      这两处位置纯 CSS 数不出来（列数 1fr 动态、桌面/手机列数还不同），
      由 PHP 打 is-col-end-* / is-last-row-* 标记。
    3. 容器**要自带白底**：末行不满时（9 条 2 列，第 9 个独占左半），右侧那块
      空位没有格子、只能露出容器背景；不刷白就和格子的 #fff 有色差，
      看着仍像「多一格」。配上「末位格子去掉右边线」，空位就彻底看不出来。 */
   .entrava-grid.v-line {
   border: 1px solid var(--eg-line);
   border-radius: 8px;
   overflow: hidden;
   background: #fff;
   }

.entrava-grid.v-line .eg-cell {
	border-right: 1px solid var(--eg-line);
	border-bottom: 1px solid var(--eg-line);
}

@media (min-width: 768px) {
	.entrava-grid.v-line .eg-cell.is-col-end-desk {
		border-right: 0;
	}

	.entrava-grid.v-line .eg-cell.is-last-row-desk {
		border-bottom: 0;
	}
}

@media (max-width: 767px) {
	.entrava-grid.v-line .eg-cell.is-col-end-mob {
		border-right: 0;
	}

	.entrava-grid.v-line .eg-cell.is-last-row-mob {
		border-bottom: 0;
	}
}

/* 变体 B · 间距：去掉所有线，靠留白分栏 */
.entrava-grid.v-space {
	gap: 34px 30px;
}

.entrava-grid.v-space .eg-cell {
	padding: 0;
	background: transparent;
}

/* 变体 C · 卡片：每格独立描边 + 圆角 */
.entrava-grid.v-card {
	gap: 14px;
}

.entrava-grid.v-card .eg-cell {
	border: 1px solid var(--eg-line);
	border-radius: 8px;
}

/* 变体 D · 行式列表：一行一条 + 右侧按钮（后台「外观样式」选「行式列表」）
   结构完全复用 eg-idx / eg-title / eg-desc，只靠 grid 定位成两行三列：
        [序号]  [标题]  [按钮]
                [摘要]
   序号与按钮各跨两行、摘要与标题左边缘对齐（手机端也是这个排法）。
   列数由 PHP 压成 1、`--eg-cols` 不再注入，所以这里不写列数变量。 */
.entrava-grid.v-row {
	/* 必须显式写 1：`.entrava-grid` 自己的兜底是 `--eg-cols: 3`，
	   PHP 只是「不注入」，不注入 ≠ 变成 1，不写这条会排成 3 列（实测踩过）。 */
	--eg-cols: 1;
	--eg-row-pad-y: 22px;
	gap: 0;
	text-align: left;   /* 行式下对齐强制左对齐，PHP 不会输出 is-center / is-right */
}

.entrava-grid.v-row .eg-cell {
	display: grid;
	grid-template-columns: 54px minmax(0, 1fr) auto;
	grid-template-rows: auto auto;
	column-gap: 22px;
	row-gap: 6px;
	align-items: start;
	padding: var(--eg-row-pad-y) 0 calc(var(--eg-row-pad-y) - 2px);
	background: transparent;
	/* 分隔线跟随标题色：深色页面把标题改成浅色时线自动变淡白，浅色页面则是淡灰。
	   color-mix 不支持的老浏览器退回上一行的 --eg-line，不会没线。 */
	border-bottom: 1px solid var(--eg-line);
	border-bottom-color: color-mix(in srgb, var(--eg-title-color) 16%, transparent);
}

/* 整行可点（<a>）时的默认态重置：不要下划线、不要链接蓝 */
.entrava-grid.v-row a.eg-cell,
.entrava-grid.v-row a.eg-cell:hover,
.entrava-grid.v-row a.eg-cell:focus {
	color: inherit;
	text-decoration: none;
}

.entrava-grid.v-row .eg-idx {
	grid-column: 1;
	grid-row: 1 / 3;
	margin: 0;
	padding-top: 3px;   /* 序号字比标题小，往下推一点才能与标题首行视觉对齐 */
}

.entrava-grid.v-row .eg-title {
	grid-column: 2;
	grid-row: 1;
	margin: 0;
	font-size: 18px;
	line-height: 1.3;
}

.entrava-grid.v-row .eg-desc {
	grid-column: 2;
	grid-row: 2;
}

.entrava-grid.v-row .eg-cta {
	grid-column: 3;
	grid-row: 1 / 3;
	align-self: center;   /* 跨两行垂直居中：对应设计稿里那个与整条居中的方框 */
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-width: 44px;
	height: 44px;
	padding: 0 12px;
	border: 1px solid var(--eg-line);
	border-color: color-mix(in srgb, var(--eg-title-color) 28%, transparent);
	border-radius: 4px;
	color: var(--eg-accent);
	font-size: 13px;
	font-weight: 500;
	line-height: 1;
	white-space: nowrap;
	transition: border-color .2s ease, background-color .2s ease;
}

.entrava-grid.v-row .eg-cta svg {
	width: 16px;
	height: 16px;
	flex: none;
	transition: transform .2s ease;
}

/* 整行 hover：只提亮按钮边框 + 箭头右移，不动行背景（深色页面里整块变色很吵） */
.entrava-grid.v-row a.eg-cell:hover .eg-cta {
	border-color: var(--eg-accent);
}

.entrava-grid.v-row a.eg-cell:hover .eg-cta svg {
	transform: translateX(3px);
}

/* 条目级「文字 + 箭头」链接（2026-11-06）：与行式列表同一套字段，形态换成轻量链接。
   选择器**不再挂 v-line**：网格线 / 间距 / 卡片三种外观共用这一套（客户 2026-11-06
   确认全部放开），行式列表走上面的 .eg-cta 方块按钮，两者不重叠，所以放开到
   `.entrava-grid` 这一层就够，不必复制三份。
   不做方框描边 —— 三列布局下格子只有 ~1/3 宽，方框会把标题和摘要挤成两行；
   也不加下划线，避免和摘要的字重混在一起。inline-flex 是 inline-level，
   所以「对齐方式」的居中/右对齐由父级 text-align 自然带过来，不用单独写规则。 */
.entrava-grid .eg-cta-link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: 14px;
	color: var(--eg-accent);
	font-size: 13px;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
}

.entrava-grid .eg-cta-link svg {
	width: 15px;
	height: 15px;
	flex: none;
	transition: transform .2s ease;
}

.entrava-grid .eg-cta-link:hover {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.entrava-grid .eg-cta-link:hover svg {
	transform: translateX(3px);
}

/* 紧凑密度：与行式列表保持同一节奏（间距收 4px，字号不变） */
.entrava-grid.is-compact .eg-cta-link {
	margin-top: 10px;
}

/* 没有序号 → 收掉第一列；没有按钮 → 收掉第三列；两者都没有 → 单列。
   不收掉的话会留下一个 column-gap 宽的空洞，右边距看着不对。
   注意：只改 `grid-template-columns` 不够 —— 子元素仍写着 `grid-column: 2 / 3`，
   第一列空出来后标题会落到按钮列、按钮跑到隐式第 4 列（实测踩过），
   所以这里必须把子元素一并重定位。 */
.entrava-grid.v-row .eg-cell.is-idx-none {
	grid-template-columns: minmax(0, 1fr) auto;
}

.entrava-grid.v-row .eg-cell.is-idx-none .eg-title,
.entrava-grid.v-row .eg-cell.is-idx-none .eg-desc {
	grid-column: 1;
}

.entrava-grid.v-row .eg-cell.is-idx-none .eg-cta {
	grid-column: 2;
}

.entrava-grid.v-row .eg-cell.is-no-cta {
	grid-template-columns: 54px minmax(0, 1fr);
}

.entrava-grid.v-row .eg-cell.is-idx-none.is-no-cta {
	grid-template-columns: minmax(0, 1fr);
}

/* 密度：紧凑在行式下收行高与字号（用独立变量，不与 grid 那套 --eg-pad-y 打架） */
.entrava-grid.v-row.is-compact {
	--eg-row-pad-y: 16px;
}

.entrava-grid.v-row.is-compact .eg-title {
	font-size: 16px;
}

.entrava-grid.v-row.is-compact .eg-cta {
	min-width: 38px;
	height: 38px;
}

@media (max-width: 767px) {
	.entrava-grid.v-row {
		--eg-row-pad-y: 18px;
	}

	.entrava-grid.v-row .eg-cell {
		grid-template-columns: 40px minmax(0, 1fr) auto;
		column-gap: 14px;
		row-gap: 5px;
	}

	/* 手机上 is-idx-none / is-no-cta 的列定义要重写一遍，否则被上面的 40px 三列覆盖 */
	.entrava-grid.v-row .eg-cell.is-idx-none {
		grid-template-columns: minmax(0, 1fr) auto;
	}

	.entrava-grid.v-row .eg-cell.is-no-cta {
		grid-template-columns: 40px minmax(0, 1fr);
	}

	.entrava-grid.v-row .eg-cell.is-idx-none.is-no-cta {
		grid-template-columns: minmax(0, 1fr);
	}

	.entrava-grid.v-row .eg-title {
		font-size: 16px;
	}

	.entrava-grid.v-row .eg-cta {
		min-width: 36px;
		height: 36px;
		padding: 0 8px;
		border-radius: 3px;
		font-size: 12px;
	}

	.entrava-grid.v-row .eg-cta svg {
		width: 14px;
		height: 14px;
	}
}

/* 密度：紧凑 */
.entrava-grid.is-compact {
	--eg-pad-y: 18px;
	--eg-pad-x: 20px;
}

.entrava-grid.is-compact .eg-idx {
	margin-bottom: 8px;
	font-size: 12px;
}

.entrava-grid.is-compact .eg-title {
	font-size: 15px;
}

/* 按列数微调内边距（data-cols 由 PHP 输出，只影响桌面）：
   4 列收窄避免挤；1 / 2 列格子变宽，内边距跟着放大，否则文字会贴住左边线。 */
@media (min-width: 768px) {
	.entrava-grid[data-cols="4"] {
		--eg-pad-x: 22px;
	}

	.entrava-grid[data-cols="2"] {
		--eg-pad-x: 34px;
	}

	.entrava-grid[data-cols="1"] {
		--eg-pad-x: 38px;
		--eg-pad-y: 30px;
	}
}

/* 移动端：字号与内边距整体收一档 */
@media (max-width: 767px) {
	.entrava-grid {
		--eg-pad-y: 20px;
		--eg-pad-x: 18px;
	}

	.entrava-grid .eg-title {
		font-size: 15px;
	}

	.entrava-grid .eg-desc {
		font-size: 12.5px;
	}

	.entrava-grid.v-space {
		gap: 26px 20px;
	}

	.entrava-grid.v-card {
		gap: 10px;
	}
}


/* ==========================================================================
   [3] entrava-steps · 流程步骤
       结构：.entrava-steps
               > .es-head   > .es-eyebrow / .es-title / .es-lead
               > .es-list   > .es-step
                                > .es-mark > .es-num            （序号圈）
                                > .es-step-title
                                > .es-step-desc
               > .es-foot   > .es-btn / .es-note
       变体：.is-dash（虚线）/ .is-noline（不显示线）/ .is-idx-none（不显示序号）
       列数：--es-cols（由 style() 注入，手机媒体查询覆盖成 1 列）
   ========================================================================== */

.entrava-steps,
.entrava-steps * {
	/* 与网格模块同一条：不依赖父主题有没有做过全局重置 */
	box-sizing: border-box;
}

.entrava-steps {
	--es-cols: 5;
	--es-gap: 34px;          /* 列间距；连接线的右端靠它延伸到下一格 */
	--es-accent: #e8622c;    /* 序号圈描边与数字色（品牌橙，后台可改） */
	--es-line-opacity: .22;  /* 连线默认「跟随正文色的半透明」，深浅背景都能看 */

	text-align: left;        /* 兜底：不让父主题的对齐规则漏进来 */
}

/* ── 标题区 ───────────────────────────────────────────────────────── */
.entrava-steps .es-eyebrow {
	margin: 0 0 14px;
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--es-accent);
}

.entrava-steps .es-title {
	margin: 0 0 16px;
	font-size: clamp(26px, 3.2vw, 40px);
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -.015em;
	color: inherit;
}

.entrava-steps .es-lead {
	margin: 0 0 46px;
	max-width: 620px;
	font-size: 15px;
	font-weight: 400;
	line-height: 1.75;
	color: inherit;
	opacity: .75;            /* 摘要比标题弱一档；后台配了颜色会被 style() 关掉 */
}

/* ── 步骤列表 ─────────────────────────────────────────────────────── */
.entrava-steps .es-list {
	display: grid;
	grid-template-columns: repeat(var(--es-cols), minmax(0, 1fr));
	gap: 0 var(--es-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

.entrava-steps .es-step {
	position: relative;
}

.entrava-steps .es-mark {
	position: relative;
	display: flex;
	align-items: center;
	height: 30px;
	margin-bottom: 18px;
	/* 连接线是绝对定位画的，不靠 flex 的 gap —— 圈与线的距离看下面那条 left */
}

.entrava-steps .es-num {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	border: 1px solid currentColor;
	border-radius: 50%;
	color: var(--es-accent);
	font-size: 11px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: .06em;
	font-variant-numeric: tabular-nums;
}

/* 用图片当图标时统一尺寸 */
.entrava-steps .es-num-icon {
	display: block;
	width: 14px;
	height: 14px;
}

.entrava-steps .es-num-icon img {
	display: block;
	width: 14px;
	height: 14px;
	object-fit: contain;
}

/*
 * 连接线：从序号圈右侧 6px 起，一直画到下一格的圈左边。
 * `left: 36px` = 圈宽 30 + 6 空隙；原先写的 44px（14 空隙）在 PC 上看着离圈太远。
 * `right: calc(--es-gap * -1)` 是负值，正好跨过 grid 的列间距 ——
 * 不这么写的话线会在每格右边缘断掉，看起来是一段一段的。
 */
.entrava-steps .es-step:not(:last-child) .es-mark::after {
	content: "";
	position: absolute;
	left: 36px;
	right: calc(var(--es-gap) * -1);
	top: 50%;
	height: 1px;
	background: currentColor;
	opacity: var(--es-line-opacity);
}

.entrava-steps.is-dash .es-step:not(:last-child) .es-mark::after {
	height: 0;
	background: none;
	border-top: 1px dashed currentColor;
}

.entrava-steps.is-noline .es-step .es-mark::after {
	display: none;
}

/* 每行最后一个：换行处没有「下一个」，线要断在这里（标记由 PHP 按列数打） */
.entrava-steps .es-step.is-col-end .es-mark::after {
	display: none;
}

/* 不显示序号时线从格子左边起，别留出 44px 的空当 */
.entrava-steps.is-idx-none .es-num {
	display: none;
}

.entrava-steps.is-idx-none .es-mark {
	height: 0;
	margin-bottom: 0;
}

.entrava-steps.is-idx-none .es-step:not(:last-child) .es-mark::after {
	left: 0;
}

.entrava-steps .es-step-title {
	margin: 0 0 8px;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.35;
	color: inherit;
}

.entrava-steps .es-step-desc {
	margin: 0;
	font-size: 13px;
	font-weight: 400;
	line-height: 1.6;
	color: inherit;
	opacity: .72;
}

/* ── 底部 CTA ─────────────────────────────────────────────────────── */
.entrava-steps .es-foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 18px;
	margin-top: 50px;
}

.entrava-steps .es-btn {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 14px 22px;
	border-radius: 4px;
	background: var(--es-accent);
	color: #fff;
	font-size: 14px;
	font-weight: 700;
	line-height: 1;
	text-decoration: none;
}

.entrava-steps .es-btn::after {
	content: "→";
	font-weight: 400;
}

.entrava-steps .es-note {
	font-size: 13px;
	color: inherit;
	opacity: .7;
}

/* ── 手机：竖排时间轴（圈在左、竖线连接、文字在右） ───────────────── */
@media (max-width: 767px) {
	/* 注意：`--es-cols: 1` 不写在这里 —— 它由 style() 以 `@[(max-width:767px)]`
	   注入，否则会被后面注入的桌面列数盖掉（同特异性、更靠后）。这里只管布局。 */
	.entrava-steps .es-title {
		font-size: 26px;
	}

	.entrava-steps .es-lead {
		margin-bottom: 34px;
		font-size: 14px;
	}

	.entrava-steps .es-list {
		gap: 0;
	}

	.entrava-steps .es-step {
		padding: 0 0 26px 46px;
	}

	.entrava-steps .es-mark {
		position: absolute;
		left: 0;
		top: 0;
		width: 30px;
		margin: 0;
	}

	/* 横线全部收掉，改画格子的左边一条竖线 */
	.entrava-steps .es-step:not(:last-child) .es-mark::after {
		display: none;
	}

	.entrava-steps .es-step:not(:last-child)::before {
		content: "";
		position: absolute;
		left: 15px;
		top: 34px;
		bottom: 4px;
		width: 1px;
		background: currentColor;
		opacity: var(--es-line-opacity);
	}

	.entrava-steps.is-dash .es-step:not(:last-child)::before {
		width: 0;
		background: none;
		border-left: 1px dashed currentColor;
	}

	.entrava-steps.is-noline .es-step::before {
		display: none;
	}

	.entrava-steps.is-idx-none .es-step {
		padding-left: 0;
	}

	.entrava-steps.is-idx-none .es-step::before {
		display: none;
	}

	.entrava-steps .es-foot {
		margin-top: 30px;
		gap: 14px;
	}

	.entrava-steps .es-btn {
		width: 100%;
		justify-content: center;
	}
}


/* ==========================================================================
   [4] entrava-swp · 幻灯滑块 2（后台显示名，W20）
       结构与父主题 swiper 模块不同：容器是 section 内部的 .esp-swiper，
       由模块自己 trigger('swiper') 初始化（避免被自动初始化接管、分页被写死成圆点）。

       .entrava-swp
         > .esp-swiper.swiper-container
             > .swiper-wrapper
                 > .esp-slide.swiper-slide
                     > .esp-slide-bg  > .esp-video / .esp-bg|img / .esp-mask
                     > .esp-inner     > .esp-eyebrow
                                      > .esp-title > .esp-t (.is-thin / .is-accent)
                                      > .esp-lead
                                      > .esp-ctas > .esp-btn (.is-solid / .is-outline / .is-arrow)
             > .esp-nav.is-prev / .is-next
             > .esp-pager.is-bullets|.is-bar
                 > .esp-dot  |  .esp-bar > .esp-seg > i (.is-done)

       变体：.is-full（桌面 100svh；≤767px 固定 --esp-h）/ .is-normal（按图片高度）
             .align-left|center|right / .valign-top|center|bottom
       变量：--esp-*（style() 注入，全部带兜底）
   ========================================================================== */

.entrava-swp,
.entrava-swp * {
	/* 不依赖父主题有没有做过全局重置 */
	box-sizing: border-box;
}

/* 全屏模式要顶到视口边缘，父主题 section 的容器宽度/内边距在这里让位 */
.entrava-swp-section {
	position: relative;
}

.entrava-swp {
	--esp-accent: #e8622c;              /* 品牌橙：徽标/按钮/分页填充 */
	--esp-accent-text: var(--esp-accent); /* 标题最后一行的强调色，可单独配（不影响按钮） */
	--esp-eyebrow: var(--esp-accent);
	--esp-title-bold: #fff;
	--esp-title-thin: #fff;
	--esp-lead: rgba(255, 255, 255, .82);
	--esp-mask: rgba(0, 0, 0, .32);
	--esp-title-size: clamp(26px, 4vw, 46px);
	--esp-content-w: 640px;
	--esp-btn-radius: 999px;
	--esp-h: 600px;   /* 手机端幻灯高度：不再整屏，否则内容区上下各留一大片空白 */

	position: relative;
	color: #fff;
}

/* ── 轮播容器 ─────────────────────────────────────────────────────── */
.entrava-swp .esp-swiper {
	position: relative;
	width: 100%;
}

.entrava-swp.is-full .esp-swiper {
	height: 100vh;
	height: 100svh;   /* 手机地址栏收放时 100vh 会跳，svh 更稳；不支持则回退上一行 */
}

.entrava-swp.is-normal .esp-swiper {
	height: auto;
}

.entrava-swp .esp-slide {
	position: relative;
	height: 100%;
	overflow: hidden;
}

.entrava-swp.is-normal .esp-slide {
	height: auto;
}

/* ── 背景层 ───────────────────────────────────────────────────────── */
.entrava-swp .esp-slide-bg {
	position: absolute;
	inset: 0;
}

.entrava-swp.is-normal .esp-slide-bg {
	position: relative;
}

/* 层级（2026-11-05 修 bug）：背景图 / 视频 / 遮罩三者都是 absolute，
   原来全都没有 z-index ⇒ 按 DOM 顺序绘制 ⇒ 排在视频后面的 .esp-bg 把视频整个盖住，
   上传了视频也只看得到图。这里显式分层：图 0 < 视频 1 < 遮罩 2 < 内容 3 < 箭头/分页 4。 */
.entrava-swp .esp-bg {
	display: block;
	position: absolute;
	inset: 0;
	z-index: 0;
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
}

.entrava-swp.is-normal .esp-slide-bg > img {
	display: block;
	width: 100%;
	height: auto;
}

.entrava-swp .esp-video {
	position: absolute;
	inset: 0;
	z-index: 1;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.entrava-swp .esp-mask {
	position: absolute;
	inset: 0;
	z-index: 2;
	background: var(--esp-mask);
}

/* 视频幻灯没配图（图只当手机端兜底 / video 的 poster 用）：
   · 定高模式（「全屏高度」关）高度本来靠图片撑开，没图会塌成 0 → 用 16:9 兜底，
     视频才能铺满；全屏模式不命中这条（容器高度已由 100svh / --esp-h 决定）。
   · 深色底兜底：手机端（≤991px）视频被隐藏，没图时不会白底白字。 */
.entrava-swp .esp-slide-bg.is-no-image {
	background: #14100D;
}

.entrava-swp.is-normal .esp-slide-bg.is-video-only {
	aspect-ratio: 16 / 9;
}

/* ── 内容层 ───────────────────────────────────────────────────────── */
.entrava-swp .esp-inner {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 3;   /* 高于视频(1)与遮罩(2)：视频不会盖住文字 */
	display: flex;
	flex-direction: column;
	justify-content: center;
	/* 与全站 .container 完全同宽：750 / 970 / 1200（≥1240 视口），左右各半个 gutter。
	   不要自己写 max-width —— 会和全站容器对不齐（2026-11-05 客户指出）。 */
	width: var(--theme-container-width, 100%);
	max-width: 100%;
	margin: 0 auto;
	padding: 0 calc(var(--theme-gutter, 30px) / 2);
}

.entrava-swp.valign-top .esp-inner {
	justify-content: flex-start;
	padding-top: 140px;
}

.entrava-swp.valign-bottom .esp-inner {
	justify-content: flex-end;
	padding-bottom: 110px;
}

.entrava-swp.align-center .esp-inner {
	align-items: center;
	text-align: center;
}

.entrava-swp.align-center .esp-lead {
	margin-left: auto;
	margin-right: auto;
}

.entrava-swp.align-center .esp-ctas {
	justify-content: center;
}

.entrava-swp.align-right .esp-inner {
	align-items: flex-end;
	text-align: right;
}

.entrava-swp.align-right .esp-ctas {
	justify-content: flex-end;
}

/* ── 文字 ─────────────────────────────────────────────────────────── */
.entrava-swp .esp-eyebrow {
	margin: 0 0 16px;
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--esp-eyebrow);
}

.entrava-swp .esp-title {
	margin: 0 0 18px;
	font-size: var(--esp-title-size);
	font-weight: 700;
	line-height: 1.14;
	letter-spacing: -.018em;
	color: var(--esp-title-bold);
}

/* 三行共用同一个标题标签（层级由模块「标题层级」决定），逐行由 .is-thin / .is-accent 控制，不额外套 div */
.entrava-swp .esp-title .esp-t {
	font-weight: 700;
	color: var(--esp-title-bold);
}

.entrava-swp .esp-title .esp-t.is-thin {
	font-weight: 300;
	color: var(--esp-title-thin);
}

.entrava-swp .esp-title .esp-t.is-accent {
	color: var(--esp-accent-text, var(--esp-accent));
}

.entrava-swp .esp-lead {
	margin: 0 0 34px;
	max-width: var(--esp-content-w);
	font-size: 15px;
	line-height: 1.7;
	color: var(--esp-lead);
}

/* ── CTA ──────────────────────────────────────────────────────────── */
.entrava-swp .esp-ctas {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 14px;
}

.entrava-swp .esp-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 15px 30px;
	border: 1px solid transparent;
	border-radius: var(--esp-btn-radius);
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	transition: background-color .2s ease, border-color .2s ease, color .2s ease, transform .2s ease;
}

.entrava-swp .esp-btn:hover {
	transform: translateY(-1px);
}

.entrava-swp .esp-btn svg {
	width: 14px;
	height: 14px;
	flex: none;
}

/* 形态一：实心 */
.entrava-swp .esp-btn.is-solid {
	background-color: var(--esp-accent);
	border-color: var(--esp-accent);
	color: #fff;
}

.entrava-swp .esp-btn.is-solid:hover {
	filter: brightness(.94);
}

/* 形态二：描边 */
.entrava-swp .esp-btn.is-outline {
	background-color: transparent;
	border-color: rgba(255, 255, 255, .5);
	color: #fff;
}

.entrava-swp .esp-btn.is-outline:hover {
	border-color: #fff;
	background-color: rgba(255, 255, 255, .08);
}

/* 形态三：纯文字箭头（无底色、无边框、无下划线） */
.entrava-swp .esp-btn.is-arrow {
	padding: 15px 4px;
	border: 0;
	border-radius: 0;
	background-color: transparent;
	color: #fff;
}

.entrava-swp .esp-btn.is-arrow svg {
	transition: transform .2s ease;
}

.entrava-swp .esp-btn.is-arrow:hover svg {
	transform: translateX(3px);
}

/* ── 左右箭头 ─────────────────────────────────────────────────────── */
.entrava-swp .esp-nav {
	position: absolute;
	top: 50%;
	z-index: 4;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin-top: -22px;
	padding: 0;
	border: 0;
	background: transparent;
	color: rgba(255, 255, 255, .62);
	cursor: pointer;
	transition: color .2s ease;
}

.entrava-swp .esp-nav:hover {
	color: #fff;
}

.entrava-swp .esp-nav svg {
	width: 26px;
	height: 26px;
}

.entrava-swp .esp-nav.is-prev {
	left: 10px;
}

.entrava-swp .esp-nav.is-next {
	right: 10px;
}

.entrava-swp .esp-nav.swiper-button-disabled {
	opacity: .3;
	cursor: default;
}

/* ── 底部分页 ─────────────────────────────────────────────────────── */
.entrava-swp .esp-pager {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 28px;
	z-index: 4;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	height: 16px;
}

/* ① 圆点 */
.entrava-swp .esp-dot {
	display: block;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background-color: rgba(255, 255, 255, .35);
	cursor: pointer;
	transition: background-color .25s ease, width .25s ease, height .25s ease;
}

.entrava-swp .esp-dot.is-on {
	width: 9px;
	height: 9px;
	background-color: var(--esp-accent);
}

/* ② 分段进度条：视觉 2px 细线，外框 14px 是点击热区（否则点不中）
      段数 = 幻灯片张数，总宽固定 140px */
.entrava-swp .esp-bar {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 140px;
	height: 14px;
	cursor: pointer;
}

.entrava-swp .esp-bar .esp-seg {
	flex: 1 1 0;
	min-width: 0;
	height: 2px;
	border-radius: 2px;
	background-color: rgba(255, 255, 255, .3);
	overflow: hidden;
}

.entrava-swp .esp-bar .esp-seg > i {
	display: block;
	width: 0;
	height: 100%;
	border-radius: 2px;
	background-color: var(--esp-accent);
	transition: opacity .25s ease;
}

/* 已播完的段降一档亮度，与「正在走」的那段区分开 */
.entrava-swp .esp-bar .esp-seg > i.is-done {
	opacity: .45;
}

/* ── 手机 ─────────────────────────────────────────────────────────── */
@media (max-width: 991px) {
	/* 手机端不播视频，只留图片（父主题原生模块同策略） */
	.entrava-swp .esp-video {
		display: none;
	}

	.entrava-swp .esp-nav {
		display: none;
	}
}

@media (max-width: 767px) {
	/* 手机端不整屏：内容块通常只有 300–350px 高，100svh 会在上下各留 200px+ 空白。
	   改成固定高度（--esp-h 可调），桌面与平板仍是 100svh 全屏。 */
	.entrava-swp.is-full .esp-swiper {
		height: var(--esp-h, 600px);
	}

	.entrava-swp .esp-eyebrow {
		margin-bottom: 12px;
		font-size: 11px;
		letter-spacing: .14em;
	}

	.entrava-swp .esp-title {
		margin-bottom: 14px;
	}

	.entrava-swp .esp-lead {
		margin-bottom: 26px;
		font-size: 13px;
		line-height: 1.65;
	}

	.entrava-swp .esp-btn {
		padding: 12px 20px;
		font-size: 13px;
	}

	.entrava-swp .esp-btn.is-arrow {
		padding: 12px 2px;
	}

	.entrava-swp .esp-ctas {
		gap: 10px;
	}

	.entrava-swp .esp-pager {
		bottom: 18px;
	}

	.entrava-swp.valign-top .esp-inner {
		padding-top: 96px;
	}

	.entrava-swp.valign-bottom .esp-inner {
		padding-bottom: 80px;
	}
}


/* ==========================================================================
   [5] entrava-compare · 产品对比表
       结构：.entrava-cmp
               > .ec-scroll > .ec-table         （手机端横向滚动容器）
                   > thead th.ec-col            （列头：.ec-badge / .ec-name / .ec-sub / .ec-cta）
                   > tbody tr.ec-group          （分组行，分隔 ACCESS / HARDWARE 这类）
                   > tbody tr > th.ec-label + td.ec-cell
                   > tfoot                      （表尾统一 CTA，文案与链接都填了才出现）
               > .ec-hint                       （手机端滑动提示，桌面隐藏）

       颜色全部走 CSS 变量，`style()` 只覆盖改过的那几个（模块 id 前缀 #modules-<n>），
       所以同一页两个实例各配各的颜色互不影响；没配的用这里的兜底值。
       列数由 PHP 以 `--ec-cols` 内联注入（2–4），移动端最小宽度用 calc 算。
   ========================================================================== */

/*
 * 自带 box-sizing（C94⑫-a）：不加载父主题做本地预览时默认是 content-box，
 * `.ec-corner` 的 200px + 左右 padding 会直接撑出横向溢出。
 */
.entrava-cmp,
.entrava-cmp * {
	box-sizing: border-box;
}

.entrava-cmp {
	--ec-brand: #ff6200;
	--ec-ink: #1b1b1b;
	--ec-muted: #8b909b;
	--ec-line: #e6e8eb;
	--ec-hl: #e5341f;
	--ec-feat: #fff6ef;
	--ec-group: #8b909b;
	color: var(--ec-ink);
}

/* ── 滚动容器 ─────────────────────────────────────────────────────── */
.entrava-cmp .ec-scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.entrava-cmp .ec-table {
	width: 100%;
	min-width: 0;
	border-collapse: collapse;
	text-align: left;
}

/* ── 列头 ─────────────────────────────────────────────────────────── */
.entrava-cmp .ec-table thead th {
	padding: 20px 18px;
	border-bottom: 1px solid var(--ec-line);
	font-weight: 400;
	vertical-align: top;
}

.entrava-cmp .ec-corner {
	width: 200px;
	padding-left: 0;
	vertical-align: top;
}

.entrava-cmp .ec-col {
	position: relative;
}

/*
 * 推荐列：浅底 + 顶部 3px 品牌条 + 上圆角。
 * 徽标是**线框**（透明底 + 1px 品牌色描边），描边用 inset box-shadow 画，
 * 不用 border —— border 会占盒尺寸，让徽标定位偏移 1px。
 */
.entrava-cmp .ec-col--feat {
	background: var(--ec-feat);
	border-radius: 10px 10px 0 0;
	box-shadow: inset 0 3px 0 var(--ec-brand);
}

.entrava-cmp .ec-badge {
	position: absolute;
	top: 12px;
	right: 12px;
	display: inline-block;
	padding: 3px 9px;
	border-radius: 999px;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ec-brand);
	background: transparent;
	box-shadow: inset 0 0 0 1px var(--ec-brand);
}

/*
 * 序号 / 前缀（2026-11-06）：列标题上方的一行小字，内容完全由后台决定（01 / OPTION A / 任意短文本）。
 * 走「灰小字 + 字距」这一套，和分组标签（ACCESS / HARDWARE）同一视觉语言，不额外加边框，
 * 也**不加 text-transform**（自由文本大写会变味）。
 */
.entrava-cmp .ec-index {
	display: block;
	/* 空序号也要占住一行高度：同表里有的列填了序号、有的没填时，列标题才会齐平 */
	min-height: 1.2em;
	margin-bottom: 6px;
	color: var(--ec-muted);
	font-size: 12px;
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: 0.08em;
}

.entrava-cmp .ec-name {
	display: block;
	margin-bottom: 3px;
	font-size: 18px;
	font-weight: 700;
}

/*
 * 推荐列的名称给徽标让位：徽标是 absolute（不占流），列名一长就会从徽标底下穿过去
 * （2026-11-06 产品模式「ETV-I3 · Fingerprint Smart Lever Lock」折行后压住 RECOMMENDED）。
 * 产品模式已改显示型号（`ETV-I3`），这里再加一道保险：只影响折行点，短标题视觉零变化。
 * 移动端列宽只有 ~157px，让位会把名称挤成多行，故在下面那条媒体查询里归零。
 */
.entrava-cmp .ec-col--feat .ec-name {
	padding-right: 96px;
}

.entrava-cmp .ec-sub {
	display: block;
	margin-bottom: 14px;
	color: var(--ec-muted);
	font-size: 13px;
}

/* ── 按钮（表头 + 表尾共用） ──────────────────────────────────────── */
.entrava-cmp .ec-cta {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 9px 15px;
	border: 1px solid var(--ec-ink);
	border-radius: 6px;
	color: var(--ec-ink);
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}

.entrava-cmp .ec-cta svg {
	width: 15px;
	height: 15px;
	flex: none;
	transition: transform 0.2s;
}

.entrava-cmp .ec-cta:hover {
	background: var(--ec-ink);
	color: #fff;
}

.entrava-cmp .ec-cta:hover svg {
	transform: translateX(3px);
}

.entrava-cmp .ec-cta--solid {
	background: var(--ec-brand);
	border-color: var(--ec-brand);
	color: #fff;
}

.entrava-cmp .ec-cta--solid:hover {
	background: var(--ec-brand);
	border-color: var(--ec-brand);
	color: #fff;
	filter: brightness(0.94);
}

/* ── 表体 ─────────────────────────────────────────────────────────── */
.entrava-cmp .ec-table tbody th,
.entrava-cmp .ec-table tbody td {
	padding: 15px 18px;
	border-bottom: 1px solid var(--ec-line);
	font-size: 14.5px;
	vertical-align: top;
}

.entrava-cmp .ec-table tbody th.ec-label {
	padding-left: 0;
	color: #5c5f66;
	font-weight: 500;
}

.entrava-cmp .ec-cell--feat {
	background: var(--ec-feat);
}

/*
 * 分组行：只在分组名变化时输出一行。
 * 特异性靠「容器 + table + tbody + .ec-group + th」压过上面的 tbody th，
 * 所以这里不需要 !important（父主题表格规则同理）。
 */
.entrava-cmp .ec-table tbody .ec-group th {
	padding: 24px 0 6px;
	border: 0;
	color: var(--ec-group);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

/* ── 单元格内的记号（2026-11-06 起四种） ───────────────────────────── */
/* 飘红：`**文字**`；`.hl` 是 demo 里的旧写法，一起接上（客户照 demo 填却没变红就是这个坑） */
.entrava-cmp .ec-hl,
.entrava-cmp .hl {
	color: var(--ec-hl);
	font-weight: 600;
}

/* 灰色补充说明：`%%文字%%` —— 行内跟排，要换行自己写 <br> */
.entrava-cmp .ec-dim {
	color: var(--ec-muted);
	font-size: 0.92em;
}

.entrava-cmp .ec-yes {
	color: var(--ec-brand);
	font-weight: 600;
}

.entrava-cmp .ec-dash {
	color: #c9ccd2;
}

/*
 * 能力行的第三态：家族有、但基础版没有（只在部分版本里可选）。
 * 与 .ec-yes 的强调色区分开 —— 它是一个「条件成立」，不该和被强调的 Yes 抢注意力；
 * 也不能用 .ec-dash 的浅灰（那等于「没有」）。
 */
.entrava-cmp .ec-opt {
	color: var(--ec-muted);
	font-weight: 600;
}

/* ── 表尾 ─────────────────────────────────────────────────────────── */
.entrava-cmp .ec-table tfoot th,
.entrava-cmp .ec-table tfoot td {
	padding: 20px 18px;
	border: 0;
}

.entrava-cmp .ec-table tfoot th.ec-label {
	padding-left: 0;
	color: var(--ec-ink);
	font-weight: 600;
}

/* ── 手机端滑动提示 ───────────────────────────────────────────────── */
.entrava-cmp .ec-hint {
	display: none;
	margin: 10px 0 0;
	color: var(--ec-muted);
	font-size: 12px;
	letter-spacing: 0.02em;
	text-align: center;
}

/* ── 手机：横向滚动 + 首列吸附 ───────────────────────────────────── */
@media (max-width: 767px) {
	/* 每列 157px + 首列 104px（demo 实测值），列数由 --ec-cols 决定 */
	.entrava-cmp .ec-table {
		min-width: calc(104px + var(--ec-cols, 3) * 157px);
	}

	.entrava-cmp .ec-table thead th {
		padding: 14px 12px;
	}

	.entrava-cmp .ec-table tbody th,
	.entrava-cmp .ec-table tbody td {
		padding: 12px 12px;
		font-size: 13.5px;
	}

	/* 首列吸附：白底 + 一条右阴影当分隔线，否则滚动时会和后面的列糊在一起 */
	.entrava-cmp .ec-corner {
		position: sticky;
		left: 0;
		z-index: 2;
		width: 104px;
		background: #fff;
		box-shadow: 1px 0 0 var(--ec-line);
	}

	.entrava-cmp .ec-table tbody th.ec-label {
		position: sticky;
		left: 0;
		z-index: 1;
		background: #fff;
		box-shadow: 1px 0 0 var(--ec-line);
		font-size: 12.5px;
	}

	/* 移动端圆角会与吸附列打架，去掉 */
	.entrava-cmp .ec-col--feat {
		border-radius: 0;
	}

	.entrava-cmp .ec-index {
		margin-bottom: 4px;
		font-size: 11px;
	}

	/* 窄列不再给徽标让位，否则列名被挤成两三行 */
	.entrava-cmp .ec-col--feat .ec-name {
		padding-right: 0;
	}

	.entrava-cmp .ec-name {
		font-size: 15px;
	}

	.entrava-cmp .ec-sub {
		margin-bottom: 10px;
		font-size: 12px;
	}

	/* 窄列下徽标收到 8.5px + 零字距，否则会和列名叠在一起 */
	.entrava-cmp .ec-badge {
		top: 8px;
		right: 8px;
		padding: 1px 5px;
		font-size: 8.5px;
		letter-spacing: 0;
	}

	.entrava-cmp .ec-cta {
		padding: 7px 10px;
		font-size: 11.5px;
	}

	.entrava-cmp .ec-hint {
		display: block;
	}
}


/* ==========================================================================
   [6] entrava-ns · 数字滚动 2（后台显示名，W20）
       结构：.entrava-ns
               > .ns-item                    （重复）
                   > .ns-figure > .ns-num / .ns-unit
                   > .ns-body   > .ns-label / .ns-desc
       变体：网格线 line / 间距 space / 卡片 card / 一行一条 row，
              四种**都按断点拆成 -desk 与 -mob 两套**（v-line-desk / v-line-mob …），
              桌面与手机可各选一种外观；row 在该端强制 1 列（PHP 注入列数）
       方向：默认竖排（数字在上）；横排（数字在左、文字在右）按断点拆成
              .is-inline-desk / .is-inline-mob（桌面与手机可各设一套，C118）；
              对齐同理：.is-center-desk / .is-right-desk / .is-center-mob / .is-right-mob
       变量：--ns-cols 由 style() 注入；--ns-num / --ns-text-size /
              --ns-label-size / --ns-desc-size 四个字号**各自独立**（客户要求，
              不做比例推导）；--ns-text-size 只在「数值填了短语」时生效
              （`.ns-num.is-text`，仅普通模式）；
              颜色留空 ⇒ 跟随版块文字色（C95），深底浅底都不用配
   ========================================================================== */

.entrava-ns,
.entrava-ns * {
	box-sizing: border-box;
}

.entrava-ns {
	--ns-cols: 3;
	--ns-num: 52px;
	--ns-text-size: 20px;     /* 「数值」填文本时用（客户 11-06：数字字号与文本字号分开） */
	--ns-label-size: 12px;
	--ns-desc-size: 13px;
	--ns-accent: #e8622c;
	--ns-pad-y: 26px;
	--ns-gap-x: 26px;         /* 网格线多列时，竖线右侧的内边距 */
	--ns-gap-x-mob: 20px;     /* 1.108：手机多列 + 长文本时 16px 会让文字贴住右列 */
	--ns-num-color: inherit;  /* 留空跟随版块：深底白字，浅底深字 */
	--ns-line: color-mix(in srgb, currentColor 16%, transparent);

	display: grid;
	grid-template-columns: repeat(var(--ns-cols), minmax(0, 1fr));
	text-align: left;
}

/* 所有数据项的数值都不合法时不留下一根孤零零的底线 */
.entrava-ns:empty {
	display: none;
}

/* 末行不足列数时，最后一项跨列占满（客户 11-06 拍板，1.108）。
   跨度由 PHP 按各端列数算好后用 --ns-span-desk / --ns-span-mob 传进来；
   默认 1 = 不拉伸（`grid-column: span 1` 就是普通占位，无需额外开关）。 */
@media (min-width: 768px) {
	.entrava-ns .ns-item:last-child {
		grid-column: span var(--ns-span-desk, 1);
	}
}

@media (max-width: 767px) {
	.entrava-ns .ns-item:last-child {
		grid-column: span var(--ns-span-mob, 1);
	}
}

/* 对齐：桌面 / 手机各一套，**一律挂断点后缀**（is-center-desk / is-center-mob）。
   写成不带断点的基础类，手机设了居中会把桌面也一起带过去（客户 11-06 报的就是
   「改移动端同步影响 PC」，方向字段同理）。 */
@media (min-width: 768px) {
	.entrava-ns.is-center-desk {
		text-align: center;
	}

	.entrava-ns.is-right-desk {
		text-align: right;
	}
}

@media (max-width: 767px) {
	.entrava-ns.is-center-mob {
		text-align: center;
	}

	.entrava-ns.is-right-mob {
		text-align: right;
	}
}

.entrava-ns .ns-item {
	padding: var(--ns-pad-y) 0;
	min-width: 0;
	overflow-wrap: break-word;   /* 长标签在窄列里换行，不撑破格子 */
}

.entrava-ns .ns-figure {
	display: flex;
	align-items: baseline;
	gap: 3px;
	color: var(--ns-num-color);
}

@media (min-width: 768px) {
	.entrava-ns.is-center-desk .ns-figure {
		justify-content: center;
	}

	.entrava-ns.is-right-desk .ns-figure {
		justify-content: flex-end;
	}
}

@media (max-width: 767px) {
	.entrava-ns.is-center-mob .ns-figure {
		justify-content: center;
	}

	.entrava-ns.is-right-mob .ns-figure {
		justify-content: flex-end;
	}
}

.entrava-ns .ns-num {
	font-size: var(--ns-num);
	font-weight: 700;
	line-height: 1;
	letter-spacing: -.03em;
	font-variant-numeric: tabular-nums;   /* 滚动时数字不左右跳 */
	font-feature-settings: "tnum" 1;
}

/* 数值位填的是短语（仅普通模式）：走独立字号 --ns-text-size，允许折行。
   等宽数字对文本没意义，还会把字母间距拉怪，所以这里把它关掉。 */
.entrava-ns .ns-num.is-text {
	font-size: var(--ns-text-size);
	line-height: 1.2;
	letter-spacing: 0;
	font-variant-numeric: normal;
	font-feature-settings: normal;
	overflow-wrap: break-word;
}

/* 单位取数字字号的 42%：唯一仍然「按比例」的地方，避免为一个后缀多开一个字段 */
.entrava-ns .ns-unit {
	font-size: calc(var(--ns-num) * .42);
	font-weight: 600;
	letter-spacing: -.01em;
	color: var(--ns-accent);
}

.entrava-ns .ns-label {
	margin: 12px 0 0;
	font-size: var(--ns-label-size);
	font-weight: 700;
	letter-spacing: .16em;
	line-height: 1.3;
	color: var(--ns-accent);
}

.entrava-ns.is-upper .ns-label {
	text-transform: uppercase;
}

.entrava-ns .ns-desc {
	margin: 6px 0 0;
	font-size: var(--ns-desc-size);
	line-height: 1.55;
	/* 跟随**版块**文字色而不是数字色：改了数字颜色不该把描述一起染色 */
	color: inherit;
	opacity: .62;
}

/* 横排：数字在左、标签+描述在右，两列垂直居中。
   同样按断点分两套（is-inline-desk / is-inline-mob）——「桌面横排、手机竖排」
   这种组合必须能单独成立。横排的断点下 PHP 不输出该断点的居中/右对齐类。 */
@media (min-width: 768px) {
	.entrava-ns.is-inline-desk .ns-item {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		align-items: center;
		column-gap: 20px;
	}

	.entrava-ns.is-inline-desk .ns-body {
		min-width: 0;
	}

	.entrava-ns.is-inline-desk .ns-label {
		margin-top: 0;
	}
}

@media (max-width: 767px) {
	.entrava-ns.is-inline-mob .ns-item {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		align-items: center;
		column-gap: 14px;
	}

	.entrava-ns.is-inline-mob .ns-body {
		min-width: 0;
	}

	.entrava-ns.is-inline-mob .ns-label {
		margin-top: 0;
	}
}

/* —— 外观变体：桌面 / 手机各一套（`style` 字段带 mobile，两端可各选一种）——
   类名一律带断点后缀（v-line-desk / v-line-mob …），与方向、对齐同一个思路（C118）：
   手机想用「一行一条 + 横排」省版面、桌面仍用「网格线 + 3 列」，两者互不影响。
   竖线挂在「本行非第一项」上（PHP 按各端列数标 is-div-desk / is-div-mob），
   这样第一列天然贴左边缘 —— 用 :first-child 会漏掉 3、5、7 这些同列项。 */
@media (min-width: 768px) {
	/* A 网格线：每项顶线 + 容器底线 + 列间竖线 */
	.entrava-ns.v-line-desk {
		border-bottom: 1px solid var(--ns-line);
	}

	.entrava-ns.v-line-desk .ns-item {
		border-top: 1px solid var(--ns-line);
	}

	.entrava-ns.v-line-desk .ns-item.is-div-desk {
		border-left: 1px solid var(--ns-line);
		padding-left: var(--ns-gap-x);
	}

	/* B 间距：一根线都不出，靠留白分栏 */
	.entrava-ns.v-space-desk {
		column-gap: 34px;
		row-gap: 30px;
	}

	.entrava-ns.v-space-desk .ns-item {
		padding: 0;
	}

	/* C 卡片：每项独立描边 + 圆角 */
	.entrava-ns.v-card-desk {
		gap: 14px;
	}

	.entrava-ns.v-card-desk .ns-item {
		border: 1px solid var(--ns-line);
		border-radius: 10px;
		padding: 22px 24px;
	}

	/* D 一行一条：行间横线（列数由 PHP 显式注入 1，见 style()） */
	.entrava-ns.v-row-desk {
		border-bottom: 1px solid var(--ns-line);
	}

	.entrava-ns.v-row-desk .ns-item {
		border-top: 1px solid var(--ns-line);
		padding: 20px 0;
	}
}

@media (max-width: 767px) {
	.entrava-ns {
		--ns-pad-y: 20px;
	}

	/* A 网格线 */
	.entrava-ns.v-line-mob {
		border-bottom: 1px solid var(--ns-line);
	}

	.entrava-ns.v-line-mob .ns-item {
		border-top: 1px solid var(--ns-line);
	}

	.entrava-ns.v-line-mob .ns-item.is-div-mob {
		border-left: 1px solid var(--ns-line);
		padding-left: var(--ns-gap-x-mob);
	}

	/* B 间距（手机留白收一档） */
	.entrava-ns.v-space-mob {
		column-gap: 20px;
		row-gap: 24px;
	}

	.entrava-ns.v-space-mob .ns-item {
		padding: 0;
	}

	/* C 卡片（手机内边距收一档） */
	.entrava-ns.v-card-mob {
		gap: 10px;
	}

	.entrava-ns.v-card-mob .ns-item {
		border: 1px solid var(--ns-line);
		border-radius: 10px;
		padding: 18px;
	}

	/* D 一行一条 */
	.entrava-ns.v-row-mob {
		border-bottom: 1px solid var(--ns-line);
	}

	.entrava-ns.v-row-mob .ns-item {
		border-top: 1px solid var(--ns-line);
		padding: 16px 0;
	}
}
