/*
 * 区块公共骨架 —— 三个古腾堡区块（付费墙 / 积分内容 / 授权卡）共用（底座公共资源）。
 *
 * ## 它解决什么问题
 *
 * 本次改造前，三个扩展各写一套区块样式：
 *   · ext-pay/assets/block-editor.css    36 行
 *   · ext-points/assets/block-editor.css 63 行
 *   · ext-license                        **完全没有编辑器样式**
 * 前两者结构几乎相同（虚线边框 + 灰色头部 + 标题 + 提示），只差类名前缀；
 * 而前台三份样式表连变量体系都不统一 —— license.css 用 70 处 CSS 变量、
 * points.css 用 17 处、pay.css **一处都没有（全硬编码色值）**。
 *
 * 后果是同一种「锁住的区块」在三个地方长得不一样，改一处忘另两处是常态。
 *
 * ## 用法
 *
 * 各扩展的区块根容器挂 `.wxas-block`（编辑器与前台共用同一套骨架），
 * 再追加自己的修饰类：
 *
 * ```html
 * <div class="wxas-block wxas-block--pay">        <!-- 付费墙 -->
 * <div class="wxas-block wxas-block--points">     <!-- 积分内容 -->
 * <div class="wxas-block wxas-block--license">    <!-- 授权卡 -->
 * ```
 *
 * ## 两条硬约束（改本文件前必读）
 *
 * ① **只放跨扩展共用的骨架**，不放任何一方的业务样式。
 *    业务样式留在各自扩展的 CSS 里，用 `--wxas-*` 变量取色。
 *
 * ② **禁止裸标签选择器**。编辑器里同一页会渲染多种区块，
 *    `div { ... }` 这类写法会污染其它区块。一切作用域挂在 `.wxas-block` 下。
 *
 * ## 主题
 *
 * 主色由各扩展覆盖 `--wxas-accent` 决定（付费墙 = WP 蓝、积分 = 微信绿、
 * 授权 = 跟随站点主题）。其余变量取站点主题的 preset 变量，
 * 取不到时回退到中性灰，因此换主题不会让区块变成不可读的颜色。
 *
 * 深色模式**只在本文件覆盖一次变量**，三方自动继承 ——
 * 这是把变量收敛到这里的主要收益：分散在三份文件里，
 * 改一处忘另一处就会出现「两个区块深色正常、一个刺眼」。
 */

.wxas-block {
	/* 圆角与内距：三处统一，避免「同一页两个锁面板圆角不一样」。 */
	--wxas-radius: 14px;
	--wxas-radius-sm: 8px;
	--wxas-panel-padding: 22px;

	/* 主色：各扩展覆盖它作为主题色。默认跟站点主题，再退化为中性灰。 */
	--wxas-accent: var(--wp--preset--color--primary, #2271b1);

	/* 前景 / 底色：同样优先取站点主题变量，保证与站点风格一致。 */
	--wxas-fg: var(--wp--preset--color--contrast, #1e1e1e);
	--wxas-fg-muted: var(--wp--preset--color--contrast-2, #646970);
	--wxas-surface: var(--wp--preset--color--base, #fff);
	--wxas-surface-2: var(--wp--preset--color--base-2, #f6f7f7);
	--wxas-border: var(--wp--preset--color--contrast-3, #c3c4c7);

	box-sizing: border-box;
	color: var(--wxas-fg);
}

.wxas-block *,
.wxas-block *::before,
.wxas-block *::after {
	box-sizing: border-box;
}

/* ── 头部：图标 + 标题 + 右侧元信息 ───────────────────────────── */

.wxas-block__head {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	padding: 10px 12px;
	background: var(--wxas-surface-2);
	border-bottom: 1px solid var(--wxas-border);
	border-radius: var(--wxas-radius) var(--wxas-radius) 0 0;
	font-size: 13px;
	line-height: 1.6;
}

.wxas-block__icon {
	flex: 0 0 auto;
	font-size: 16px;
	line-height: 1;
}

.wxas-block__title {
	font-weight: 500;
	color: var(--wxas-fg);
}

/*
 * 右侧元信息（区块标识、价格等）。
 * `margin-left:auto` 让它靠右；`user-select:all` 让点一下整段选中 ——
 * 区块标识是排查问题的钥匙，必须让人能一眼抄下来（沿用 ext-points 的既有做法）。
 */
.wxas-block__meta {
	margin-left: auto;
	color: var(--wxas-fg-muted);
	font-size: 12px;
	font-family: Consolas, Monaco, monospace;
	user-select: all;
}

.wxas-block__hint {
	font-size: 12px;
	color: var(--wxas-fg-muted);
}

/* ── 正文区 ────────────────────────────────────────────────── */

.wxas-block__body {
	padding: 12px;
}

/* 编辑器里正文容器不能塌陷，否则站长以为区块是空的。 */
.wxas-block__body > .block-editor-inner-blocks {
	padding: 4px 0;
}

.wxas-block__body .wp-block {
	min-height: 24px;
}

/* ── 编辑器态（虚线外框）与前台态（实线卡片）─────────────────── */

/*
 * 编辑器里给虚线外框，一眼区分「这是区块边界，不是最终样式」。
 * 前台用实线卡片，与站点内容融为一体。
 *
 * ⚠️ 类名用 `--editor` / `--front` 修饰，而不是靠父级猜 ——
 *    编辑器与前台是两个独立的 CSS 上下文，靠祖先选择器判断不可靠。
 */
.wxas-block--editor {
	border: 1px dashed var(--wxas-border);
	border-radius: var(--wxas-radius-sm);
	background: var(--wxas-surface);
}

.wxas-block--front {
	border: 1px solid var(--wxas-border);
	border-radius: var(--wxas-radius);
	background: var(--wxas-surface);
	overflow: hidden;
}

/*
 * 前台面板：内距统一走变量，三处不再各写 18px / 20px / 22px。
 */
.wxas-block__panel {
	padding: var(--wxas-panel-padding);
}

/* 管理员提示条（复用提示、配置错误提示共用）。 */
.wxas-block__admin-note,
.wxas-pay-notice--reuse {
	margin: 0 0 10px;
	padding: 8px 12px;
	border-left: 3px solid var(--wxas-accent);
	background: var(--wxas-surface-2);
	color: var(--wxas-fg-muted);
	font-size: 12px;
	line-height: 1.6;
}

/* 三处共用的强调色按钮（授权 / 积分 / 付费墙的次要操作）。 */
.wxas-block__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	min-height: 36px;
	padding: 0 16px;
	border: 1px solid var(--wxas-accent);
	border-radius: var(--wxas-radius-sm);
	background: var(--wxas-surface);
	color: var(--wxas-accent);
	font-size: 13px;
	line-height: 1;
	cursor: pointer;
}

.wxas-block__btn:hover {
	background: var(--wxas-accent);
	color: #fff;
}

/*
 * ── 深色模式：只覆盖变量，三方自动继承 ────────────────────────
 *
 * ⚠️⚠️ 必须**同时**覆盖两种信号，缺一种就会有一处不对：
 *
 *   ① 前台：跟系统偏好 → `@media (prefers-color-scheme: dark)`
 *   ② 编辑器：古腾堡用**类**切换明暗，与系统偏好无关 →
 *      `.is-dark-theme`（这是编辑器界面的既定类名，不是我们发明的）
 *
 *   只写 ① 的话，系统是浅色的站长在编辑器里切到深色界面时，
 *   区块会保持浅色变量 —— 表现为「编辑器里区块白得刺眼」，
 *   而前台一切正常。这个症状很容易被误判成主题插件的问题。
 *
 * 取色思路：不引第三方深色库，直接用站点主题在深色下的 preset 变量；
 * 取不到时回退到中性深灰 —— 保证在任何主题下都可读，而不是好看。
 */
@media (prefers-color-scheme: dark) {
	.wxas-block {
		--wxas-fg: var(--wp--preset--color--contrast, #f0f0f1);
		--wxas-fg-muted: var(--wp--preset--color--contrast-2, #a7aaad);
		--wxas-surface: var(--wp--preset--color--base, #1e1e1e);
		--wxas-surface-2: var(--wp--preset--color--base-2, #2c2c2c);
		--wxas-border: var(--wp--preset--color--contrast-3, #3c3c3c);
	}
}

/* 编辑器深色界面（古腾堡的 .is-dark-theme，与系统偏好无关）。 */
.is-dark-theme .wxas-block {
	--wxas-fg: #f0f0f1;
	--wxas-fg-muted: #a7aaad;
	--wxas-surface: #1e1e1e;
	--wxas-surface-2: #2c2c2c;
	--wxas-border: #3c3c3c;
}

/* ══════════════════════════════════════════════════════════════════════════
 *  第二层：前台「解锁卡片」共享组件
 * ══════════════════════════════════════════════════════════════════════════
 *
 * 三个区块在**前台**的未解锁态长得一样：一张卡片，头部一个图标 + 标题，
 * 正文里给「怎么解锁」的步骤，底部一个主操作 + 一句说明。
 * 差别只有配色与文案。
 *
 * 因此这里定义**一套**组件，用三个修饰类给主题：
 *
 *   .wxas-lock--points   积分查看（微信绿）
 *   .wxas-lock--verify   验证码查看（蓝）
 *   .wxas-lock--pay      支付查看（暖琥珀 + 绿色价格）
 *
 * 三份扩展样式表只负责覆盖主题变量，不再各写布局 —— 这是「样式复用」
 * 的落点。改布局只改这里一处。
 *
 * ## 多端适配（移动优先）
 *
 * 结构按**单手操作**设计：
 *   · 窄屏：所有内容**单列纵向堆叠**，主按钮**占满整行**（拇指易点）
 *   · ≥640px：二维码列与说明列**并排**，按钮回到自适应宽度
 * 断点只有一个（640px），与设计稿的 `sm:` 一致。不引入多档断点 ——
 * 三档以上会让「哪个宽度长什么样」无法在脑子里复现，改起来必错。
 *
 * ⚠️ 触摸目标不小于 44px（`--wxas-lock-tap`）：这是可点区的最小尺寸，
 *    不是审美选择。二维码失效后盖在码上的刷新按钮（图标形态）也按
 *    44px 圆来画，见 `assets/qrbox.css` 的 `.wxas-qrbox__btn--icon`。
 *
 * ⚠️ 深色模式要同时覆盖 `prefers-color-scheme` 与 `.is-dark-theme`，
 *    理由见文件顶部「深色模式要覆盖两种信号」。
 */

.wxas-lock {
	/* 结构令牌（三方共用，改这里即改三处） */
	--wxas-lock-radius: 16px;
	--wxas-lock-radius-sm: 10px;
	--wxas-lock-gap: 20px;
	--wxas-lock-pad: 20px;
	--wxas-lock-tap: 44px;

	/*
	 * 卡片与正文之间的**纵向**外边距。三个扩展都只用这一个值 ——
	 * 它在 blocks.css 里定义一次，三处 `margin: var(...)` 引用，
	 * 想统一调间距只改这里。
	 */
	--wxas-lock-outer: 1.5em;

	/*
	 * 二维码列宽度。
	 *
	 * 158px = 码盒 154（128 + 12×2 内距 + 1×2 边框）+ 左右各 2px 呼吸。
	 *
	 * ⚠️ 这里**不再**为右下角刷新图标预留外溢位 —— 该图标已取消，
	 *    刷新入口收进「码失效后的覆盖层」里，不再有元素溢到盒子外面。
	 *    于是三个区块共用同一个值（原先积分要单独窄 8px）。
	 */
	--wxas-lock-side-w: 158px;

	/* 前景色阶（slate 系，与设计稿一致） */
	--wxas-lock-fg: #334155;
	--wxas-lock-fg-strong: #1e293b;
	--wxas-lock-fg-muted: #94a3b8;

	/* 卡片阴影：两层叠加，近距一层压边、远距一层给浮起感 */
	--wxas-lock-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.04), 0 1px 3px 0 rgba(0, 0, 0, 0.02);

	/*
	 * 语义色（成功 / 失败）与骨架底色。
	 *
	 * ⚠️ 这几个**必须做成变量**，不能由各扩展写死：
	 *    深色模式下 #047857 / #dc2626 这类浅背景专用色会变成低对比的
	 *    暗块，提示读不清。做成变量后由本文件在深色块里统一覆盖一次，
	 *    三处扩展自动跟随。
	 */
	--wxas-lock-ok-fg: #047857;
	--wxas-lock-ok-border: rgba(5, 150, 105, 0.35);
	--wxas-lock-danger-fg: #dc2626;
	--wxas-lock-danger-border: rgba(220, 38, 38, 0.35);
	/*
	 * 失败提示的底色。
	 *
	 * ⚠️ 不用 `color-mix()` —— 它在旧版 Safari / Firefox 上不被支持，
	 *    一旦不被支持整条声明会被丢弃，失败提示就退回默认灰底，
	 *    而「醒目」正是这条的需求。显式给 rgba 最稳。
	 */
	--wxas-lock-danger-bg: rgba(220, 38, 38, 0.07);
	--wxas-lock-skeleton-1: #eef1f5;
	--wxas-lock-skeleton-2: #f6f8fa;
	--wxas-lock-qr-bg: #fff;

	/*
	 * 二维码方框的**边框色**。
	 *
	 * ⚠️ 刻意与主题色解耦，用中性灰而不是 `--wxas-lock-icon-border`。
	 *    原因：卡片底色本身就是浅色调（#f4f8fc / #f4faf7），
	 *    再叠一层同色系的淡边框（#bfdbfe / #fde68a），对比度低到
	 *    **看不出二维码有独立方框** —— 用户实测反馈「二维码、提示词、
	 *    倒计时像在同一个框里」，根因就在这里。
	 *    中性灰在任何色调的卡片上都能拉出边界。
	 */
	--wxas-lock-qr-border: #e2e8f0;

	/*
	 * 头部与正文之间的分割线。
	 *
	 * ⚠️ 也刻意比 `--wxas-lock-soft-border` 深一档。
	 *    soft-border 是给「胶囊描边」用的（要弱），拿去做分割线会
	 *    几乎看不见 —— 用户反馈「标题下方与主体的分割线不清晰」。
	 */
	--wxas-lock-divider: #cbd5e1;

	/* 主题默认值 = 积分（微信绿）。三个修饰类各自覆盖这一组。 */
	--wxas-lock-bg: #f4faf7;
	--wxas-lock-border: #d1fae5;
	--wxas-lock-accent: #07c160;
	--wxas-lock-accent-strong: #06ad56;
	--wxas-lock-icon-bg: #fffbeb;
	--wxas-lock-icon-fg: #d97706;
	--wxas-lock-icon-border: #fde68a;
	--wxas-lock-soft-bg: rgba(255, 255, 255, 0.8);
	--wxas-lock-soft-border: #d1fae5;
	--wxas-lock-step-bg: #d1fae5;
	--wxas-lock-step-fg: #047857;

	box-sizing: border-box;
	position: relative;
	overflow: hidden;
	padding: var(--wxas-lock-pad);
	border: 1px solid var(--wxas-lock-border);
	border-radius: var(--wxas-lock-radius);
	background: var(--wxas-lock-bg);
	color: var(--wxas-lock-fg);
	font-size: 13px;
	line-height: 1.6;
}

.wxas-lock *,
.wxas-lock *::before,
.wxas-lock *::after {
	box-sizing: border-box;
}

/* 右上角的柔光装饰（设计稿里的 blur 光斑）。纯装饰，不参与布局。 */
.wxas-lock .wxas-lock__glow {
	position: absolute;
	top: -64px;
	right: -64px;
	width: 144px;
	height: 144px;
	border-radius: 50%;
	background: var(--wxas-lock-step-bg);
	opacity: 0.5;
	filter: blur(48px);
	pointer-events: none;
}

/* ── 主题修饰 ─────────────────────────────────────────────── */

/*
 * ⚠️ 积分主题是 `.wxas-lock` 的**默认值**（上面那组），但这里仍然
 *    显式再声明一次。
 *
 * 原因不是为了改值，而是为了**可发现性**与**可覆写**：
 *    · 站长想改积分模块的绿色，第一反应是搜 `--points`；
 *      只靠「默认值」的话他找不到任何可改的地方。
 *    · 断言与文档都以「三个修饰类」为准，少一个会让
 *      「三处主题一一对应」这条规则出现例外。
 */
.wxas-lock--points {
	--wxas-lock-bg: #f4faf7;
	--wxas-lock-border: #d1fae5;
	--wxas-lock-accent: #07c160;
	--wxas-lock-accent-strong: #06ad56;
	--wxas-lock-icon-bg: #fffbeb;
	--wxas-lock-icon-fg: #d97706;
	--wxas-lock-icon-border: #fde68a;
	--wxas-lock-soft-border: #d1fae5;
	--wxas-lock-step-bg: #d1fae5;
	--wxas-lock-step-fg: #047857;
	/* 绿卡上的分割线：比卡底色深一档，肉眼可辨又不抢戏。 */
	--wxas-lock-divider: #a7f3d0;
}

.wxas-lock--verify {
	--wxas-lock-bg: #f4f8fc;
	--wxas-lock-border: #e2e8f0;
	--wxas-lock-accent: #2563eb;
	--wxas-lock-accent-strong: #1d4ed8;
	--wxas-lock-icon-bg: #eff6ff;
	--wxas-lock-icon-fg: #2563eb;
	--wxas-lock-icon-border: #bfdbfe;
	--wxas-lock-soft-border: #dbeafe;
	--wxas-lock-step-bg: #d1fae5;
	--wxas-lock-step-fg: #047857;
	--wxas-lock-divider: #cbd5e1;
}

.wxas-lock--pay {
	--wxas-lock-bg: #faf7f2;
	--wxas-lock-border: rgba(253, 230, 138, 0.6);
	--wxas-lock-accent: #d97706;
	--wxas-lock-accent-strong: #b45309;
	--wxas-lock-icon-bg: #fffbeb;
	--wxas-lock-icon-fg: #d97706;
	--wxas-lock-icon-border: #fde68a;
	--wxas-lock-soft-border: #fef3c7;
	--wxas-lock-step-bg: #fef3c7;
	--wxas-lock-step-fg: #b45309;
	/* 暖卡上的分割线：#fef3c7 几乎与卡底同色，必须再深两档。 */
	--wxas-lock-divider: #fcd34d;
}

/* 价格恒为微信绿，不跟随主题 —— 这是「钱」的颜色，跨模块要一致。 */
.wxas-lock .wxas-lock__price {
	display: flex;
	align-items: baseline;
	gap: 2px;
	color: #07c160;
	font-weight: 800;
	letter-spacing: -0.02em;
}

.wxas-lock .wxas-lock__price-symbol {
	font-size: 12px;
	font-weight: 600;
}

.wxas-lock .wxas-lock__price-value {
	font-size: 28px;
	line-height: 1.1;
}

/* ── 头部 ─────────────────────────────────────────────────── */

.wxas-lock .wxas-lock__head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	padding-bottom: 10px;
	margin-bottom: 14px;
	/*
	 * 分割线用 `--wxas-lock-divider`（比 soft-border 深一档），
	 * 而不是 soft-border —— 后者是为胶囊描边设计的弱色，
	 * 拿来做分割线几乎看不见（取暖卡上 #fef3c7 与卡底 #faf7f2 几乎同色）。
	 *
	 * ⚠️ 这个边框要**显式写**：一旦某处给 `__head` 设了 `border: 0`
	 *    （例如主题重置），短写属性会覆盖长写属性，分割线会整条消失。
	 */
	border: 0;
	border-bottom: 1px solid var(--wxas-lock-divider, #cbd5e1);
}

.wxas-lock .wxas-lock__head-main {
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
}

.wxas-lock .wxas-lock__icon {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	border: 1px solid var(--wxas-lock-icon-border);
	border-radius: 8px;
	background: var(--wxas-lock-icon-bg);
	color: var(--wxas-lock-icon-fg);
}

.wxas-lock__icon svg {
	width: 14px;
	height: 14px;
}

/*
 * 卡片标题。
 *
 * ══════════════════════════════════════════════════════════════════════════
 *  ⚠️⚠️ 标题**不再使用 `<h2>` 等 H 标签**，改前必读
 * ══════════════════════════════════════════════════════════════════════════
 *
 *  这里曾经踩过两次坑，最终改为**不用标题标签**：
 *
 *  第一次：标题写 `<h2 class="wxas-lock__title">`。WordPress 主题普遍用
 *  后代选择器给标题下样式（`.entry-content h2`、`.post-content h2`，
 *  特异性 (0,1,1)），压过单类选择器 (0,1,0)。表现是字号被放到 24~32px、
 *  字体换成衬线体、上下 margin 撑开 —— 整块卡片被顶得不成样子。
 *
 *  第二次：靠「选择器提升一级 + 写全排版属性」对抗。在多数主题下有效，
 *  但这是**对抗**而非**规避** —— 主题只要用 `!important`、
 *  或用 `#content .entry-content h2` 这类更高特异性的写法，仍会穿透。
 *  用户实测反馈「区块标题不要使用 H 字号标记，会和主题的 H 标记冲突」，
 *  判断正确。
 *
 *  最终做法：模板改用 `<div class="wxas-lock__title">`。
 *
 *    · 主题所有 `h1~h6` 规则**根本不会命中** —— 这是结构性规避，
 *      不依赖特异性博弈，也不怕 `!important`。
 *    · 语义与无障碍不受损：本区块的标题层级由所在文章的 H 结构决定，
 *      面板内部这句「本段内容需要 N 积分查看」是**说明**而非章节标题，
 *      用 div 反而更准确（它不该出现在文档大纲里）。
 *
 *  ⚠️ 下面这些属性仍然**全部保留**：一道防线。若将来有人把模板改回
 *     `<h2>`（例如为了 SEO），这些规则能顶上；但它们不再是被依赖的机制。
 *
 *  ⚠️ 同类元素（`__link` 是 a、`__btn` 是 button、`__code` 是 input）
 *     无法改用 div —— 它们本来就有语义。那些只能靠「提升特异性 + 写全属性」
 *     防御，见各自规则。
 */
.wxas-lock .wxas-lock__title {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	color: var(--wxas-lock-fg-strong);
	/* 跟卡片正文的字体，不跟主题的标题字体。 */
	font-family: inherit;
	font-size: 14px;
	font-weight: 700;
	font-style: normal;
	line-height: 1.5;
	letter-spacing: -0.01em;
	text-transform: none;
	text-decoration: none;
	text-shadow: none;
	/* 长道具名不许撑破卡片。 */
	overflow-wrap: anywhere;
}

/* 标题里的数字（积分数）—— 同样要压住主题对 `b`/`strong` 的着色。 */
.wxas-lock .wxas-lock__title b {
	color: var(--wxas-lock-accent);
	font-family: inherit;
	font-size: inherit;
	font-weight: 800;
	line-height: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
}

/* ── 胶囊：当前积分 / 倒计时 / 支付状态 ────────────────────── */

.wxas-lock .wxas-lock__pill {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 6px;
	padding: 3px 10px;
	border: 1px solid var(--wxas-lock-soft-border);
	border-radius: 999px;
	background: var(--wxas-lock-soft-bg);
	color: var(--wxas-lock-fg);
	font-size: 12px;
	font-weight: 500;
	white-space: nowrap;
}

.wxas-lock__pill b {
	color: var(--wxas-lock-fg-strong);
	font-weight: 600;
}

/* 倒计时用等宽字，数字跳动时宽度不变，不会左右抖。 */
.wxas-lock .wxas-lock__pill--mono {
	font-family: Consolas, Monaco, monospace;
	font-size: 11px;
}

.wxas-lock .wxas-lock__dot {
	flex: 0 0 auto;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--wxas-lock-accent);
}

/* ── 正文：窄屏单列 → ≥640px 双列 ─────────────────────────── */

.wxas-lock .wxas-lock__body {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: var(--wxas-lock-gap);
}

.wxas-lock .wxas-lock__side {
	display: flex;
	flex-direction: column;
	align-items: center;
	/*
	 * ⚠️ `justify-content: center` 是必需的，不是可选。
	 *
	 * 窄屏下 `.wxas-lock__body` 是 `align-items: stretch`，会把本列
	 * **拉到与右列等高**；默认的 `flex-start` 于是把「码 + 提示词 + 倒计时」
	 * 顶到上方，三者之间被拉开一大段空白，看起来像散落在卡片里。
	 * 用户反馈「提示词与二维码居中」，指的就是这一组应当作为**整体**居中。
	 */
	justify-content: center;
	gap: 10px;
	flex: 0 0 auto;
}

/*
 * 倒计时胶囊：把 qrbox.css 给的 `margin-top: .5rem` 归零。
 *
 * ⚠️ 不归零的话，它与本列的 `gap: 10px` 会**叠加**成 18px ——
 *    「码 → 提示词」是 10px、「提示词 → 倒计时」却是 18px，
 *    同一列里两段间距不一致，肉眼能看出来但很难说出哪里别扭。
 *    统一交给 gap 控制。
 */
.wxas-lock .wxas-lock__side .wxas-qrbox__countdown {
	margin-top: 0;
}

.wxas-lock .wxas-lock__main {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	/*
	 * ⚠️ 用 `flex-start` 而不是 `space-between`。
	 *
	 *  `space-between` 会把**剩余空间均匀分摊到每一段之间**，于是
	 *  「步骤框 → 等待支付」这类本该紧凑的相邻项被撑开一大段。
	 *  左列（码 + 倒计时）比右列内容高时余量最明显 —— 业务方反馈的
	 *  「『等待支付』与上面说明部分距离太大」就是这个。
	 *
	 *  改用 `flex-start` 后段落之间恒为 `gap`；页脚由自身的
	 *  `margin-top: auto` 顶到底部（见 `.wxas-lock__foot`），
	 *  于是**只有「最后一段 → 页脚」**这一段承担剩余空间，
	 *  正文各段始终紧凑。
	 */
	justify-content: flex-start;
	gap: 12px;
	min-width: 0;
}

/* ── 步骤列表 ─────────────────────────────────────────────── */

.wxas-lock .wxas-lock__steps {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 12px;
	border: 1px solid var(--wxas-lock-soft-border);
	border-radius: var(--wxas-lock-radius-sm);
	background: var(--wxas-lock-soft-bg);
	color: var(--wxas-lock-fg);
	font-size: 12px;
}

.wxas-lock .wxas-lock__step {
	display: flex;
	align-items: flex-start;
	gap: 8px;
}

.wxas-lock .wxas-lock__step-no {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 16px;
	height: 16px;
	margin-top: 2px;
	border-radius: 50%;
	background: var(--wxas-lock-step-bg);
	color: var(--wxas-lock-step-fg);
	font-size: 10px;
	font-weight: 600;
}

.wxas-lock .wxas-lock__step-text {
	min-width: 0;
	overflow-wrap: anywhere;
}

.wxas-lock__step-text b {
	color: var(--wxas-lock-fg-strong);
	font-weight: 600;
}

/* 站长填的「试读」摘要。可能含任意正文标签，故只做最大宽度约束。 */
.wxas-lock .wxas-lock__teaser {
	color: var(--wxas-lock-fg);
	font-size: 13px;
	overflow-wrap: anywhere;
}

.wxas-lock__teaser > :first-child {
	margin-top: 0;
}

.wxas-lock__teaser > :last-child {
	margin-bottom: 0;
}

/* ── 6 位验证码输入 ───────────────────────────────────────── */

.wxas-lock .wxas-lock__codes {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: 8px;
	/*
	 * 单格宽度 = (320 − 5×8) ÷ 6 ≈ 46.7px。
	 *
	 * ⚠️ 原先写 260px（单格 ≈ 36.7px），手指在手机上点空率偏高 ——
	 *    用户反馈「验证码输入框太小」。加到 320px 后仍在 375px 机型的
	 *    可用宽度内（正文两侧各 16px 内距 → 343px），不必再收窄。
	 *    `max-width: 100%` 是给更窄的设备兜底，防止格子被挤出卡片。
	 */
	max-width: 100%;
	width: 320px;
}

.wxas-lock .wxas-lock__code {
	width: 100%;
	aspect-ratio: 1 / 1;
	padding: 0;
	border: 1px solid #e2e8f0;
	border-radius: 10px;
	background: #fff;
	color: var(--wxas-lock-fg-strong);
	font-family: Consolas, Monaco, monospace;
	font-size: 18px;
	font-weight: 700;
	text-align: center;
	/*
	 * ⚠️ 防主题：主题对 `input` 通常设 padding / height / box-shadow /
	 *    appearance。`min-width: 0` 尤其必要 —— 主题常给 input 一个
	 *    最小宽度，六格在窄屏下会被撑出卡片。
	 */
	line-height: 1.2;
	min-width: 0;
	box-shadow: none;
	outline: none;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.wxas-lock .wxas-lock__code:focus {
	border-color: var(--wxas-lock-accent);
	box-shadow: 0 0 0 2px rgba(7, 193, 96, 0.2);
}

/*
 * 隐藏数字输入框的步进箭头。
 * 小屏上它们会挤占输入位，且这几格只填一位数字，用不到。
 */
.wxas-lock__code::-webkit-outer-spin-button,
.wxas-lock__code::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

/* ── 二维码区（复用 assets/qrbox.css 的覆盖层契约）─────────── */

/*
 * ⚠️ 二维码的**全部**样式都在这一节里，两处带码的区块
 *    （验证码查看 / 支付查看）不再各写一份。
 *
 *    第一版把这几条留在扩展 CSS 里（`.wxas-content-lock__qr-img`
 *    与 `.wxas-paywall__qr-img` 各一遍），结果两处尺寸与圆角靠人工同步 ——
 *    这正是「两个区块的二维码不一样」的成因。收敛到此处后，
 *    改一次即改两处。
 */
.wxas-lock__qr {
	position: relative;
	/*
	 * 内距 12px —— 给白卡留一圈呼吸，让二维码不贴边。
	 *
	 * ⚠️ 变量全部带 fallback：授权卡（ext-license）也用这几个类，
	 *    但它的根节点不是 `.wxas-lock`，取不到那组变量。
	 *    没有 fallback 的话 `background` 会因取值失败而整体失效 ——
	 *    二维码盒子变成透明，在深色主题下直接看不清。
	 *
	 * ⚠️ 边框用**中性灰** `--wxas-lock-qr-border` 而不是主题色
	 *    `--wxas-lock-icon-border`：卡片底色本身就是浅色调，
	 *    同色系淡边框拉不出边界，用户会认为「二维码没有独立方框」。
	 *    再叠一层浅阴影，让白卡从彩色卡片上「浮」起来。
	 */
	padding: 12px;
	border: 1px solid var(--wxas-lock-qr-border, #e2e8f0);
	border-radius: 12px;
	background: var(--wxas-lock-qr-bg, #fff);
	box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 4px 12px -6px rgba(15, 23, 42, 0.16);
}

/* 码盒：既是骨架的容器，也是 JS 注入图片的容器（128×128）。 */
.wxas-lock__qr-img {
	position: relative;
	width: 128px;
	height: 128px;
}

/*
 * 注入的二维码图。
 *
 * ⚠️ 用 `.wxas-lock__qr-img > img` 而不是某个具体类名：
 *    图片是扩展 JS 用 `createElement('img')` 建的，类名由各扩展自己定
 *    （见两个 JS 的 renderQr）。用后代选择器就不必让 JS 记住共享类名，
 *    也不会因为 JS 改名而让样式静默走失。
 *
 * ⚠️ 必须显式写死 `width/height`：主题普遍有
 *    `.entry-content img { max-width:100%; height:auto }`（特异性 0,1,1），
 *    不压住它，二维码会被拉成非正方形 —— 而**非正方形的小程序码扫不出**。
 */
.wxas-lock__qr-img > img {
	display: block;
	width: 128px;
	height: 128px;
	border-radius: 8px;
	object-fit: cover;
}

/* 取码前的占位骨架。尺寸必须与上面的图**逐像素相同**，否则码到位时会跳一下。 */
.wxas-lock__qr-skeleton {
	display: block;
	width: 128px;
	height: 128px;
	border-radius: 8px;
	background: linear-gradient(
		90deg,
		var(--wxas-lock-skeleton-1, #eef1f5) 25%,
		var(--wxas-lock-skeleton-2, #f6f8fa) 37%,
		var(--wxas-lock-skeleton-1, #eef1f5) 63%
	);
	background-size: 400% 100%;
	animation: wxas-lock-skeleton 1.4s ease infinite;
}

@keyframes wxas-lock-skeleton {
	0% {
		background-position: 100% 50%;
	}

	100% {
		background-position: 0 50%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.wxas-lock__qr-skeleton {
		animation: none;
	}
}

/* ── 操作区 ───────────────────────────────────────────────── */

.wxas-lock .wxas-lock__actions {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 10px;
}

/*
 * 主按钮。
 *
 * ⚠️ `min-height: var(--wxas-lock-tap)` 不是审美 —— 44px 是可点区的下限。
 *    窄屏下 `width: 100%`：单手拇指扫过整行都能点到，比居中的小按钮好按。
 */
.wxas-lock .wxas-lock__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	width: 100%;
	min-height: var(--wxas-lock-tap);
	padding: 10px 20px;
	border: 0;
	border-radius: 12px;
	background: var(--wxas-lock-accent);
	color: #fff;
	/*
	 * ⚠️ 这几条是防主题的，不是排版偏好：
	 *    主题普遍有 `button { font-family; text-transform; box-shadow }`，
	 *    只写 font-size 的话按钮会带着主题的字体与投影，与设计稿不符。
	 */
	font-family: inherit;
	font-size: 14px;
	font-weight: 500;
	line-height: 1.2;
	letter-spacing: normal;
	text-transform: none;
	text-decoration: none;
	text-shadow: none;
	box-shadow: none;
	cursor: pointer;
	transition: background-color 0.15s, box-shadow 0.15s, transform 0.1s;
}

.wxas-lock .wxas-lock__btn:hover {
	background: var(--wxas-lock-accent-strong);
}

.wxas-lock .wxas-lock__btn:active {
	transform: scale(0.98);
}

.wxas-lock .wxas-lock__btn:disabled {
	opacity: 0.6;
	cursor: default;
	transform: none;
}

.wxas-lock__btn svg {
	width: 16px;
	height: 16px;
}

/* 次级入口（去积分商城）。文字链接，不与主按钮抢注意力。 */
.wxas-lock .wxas-lock__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 36px;
	padding: 4px 8px;
	color: var(--wxas-lock-accent);
	/*
	 * ⚠️ 防主题：主题对 `a` 通常有 color / text-decoration / background
	 *    三重规则，只覆盖 color 会让链接带着下划线与链接底色。
	 */
	font-family: inherit;
	font-size: 12px;
	font-weight: 500;
	line-height: 1.5;
	text-align: center;
	text-decoration: none;
	text-transform: none;
	background: none;
	border: 0;
}

.wxas-lock .wxas-lock__link:hover {
	text-decoration: underline;
}

/* 状态区（等待支付中… / 解锁失败提示）。aria-live 由模板声明。 */
.wxas-lock .wxas-lock__status {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	align-self: flex-start;
	padding: 3px 10px;
	border: 1px solid var(--wxas-lock-soft-border);
	border-radius: 999px;
	background: var(--wxas-lock-soft-bg);
	color: var(--wxas-lock-fg-muted);
	font-size: 12px;
}

/*
 * 空状态行：**占位但不可见**。
 *
 * ══════════════════════════════════════════════════════════════════════════
 *  ⚠️ 这里必须用 `visibility`，不能写 `display: none`
 * ══════════════════════════════════════════════════════════════════════════
 *
 *  `display: none` 的元素**不占位**。状态行一出现就突然占位、吃掉一块
 *  空间，下方所有元素随之位移 —— 业务方反馈的「出现提示后按钮会往上
 *  移动」就是这个（积分区块的按钮排在状态行**上方**）。
 *
 *  改成 `visibility: hidden` 后，它**始终占位**（高度、宽度都不变），
 *  提示出现或消失都不引起任何位移。代价是空态留下一小块不可见区域 ——
 *  但它本来就在「按钮」与「页脚说明」之间，视觉上是正常的呼吸间距。
 *
 *  ⚠️ 主列已改用 `justify-content: flex-start`（原先 `space-between`），
 *    位移的**主因**已消除；这里保留 `visibility` 作为第二道保险 ——
 *    列高变化还会牵动左列 `justify-content: center` 的居中位置。
 */
.wxas-lock .wxas-lock__status:empty {
	visibility: hidden;
}

/*
 * 状态语义色。
 *
 * ⚠️ 放在共享层（原先分散在 content.css / pay.css），三个区块共用一套：
 *    积分「积分不足」的提示也用同一套视觉，不必再写第三份。
 */
.wxas-lock .wxas-lock__status.is-ok {
	border-color: var(--wxas-lock-ok-border, rgba(5, 150, 105, 0.35));
	color: var(--wxas-lock-ok-fg, #047857);
}

.wxas-lock .wxas-lock__status.is-err {
	border-color: var(--wxas-lock-danger-border, rgba(220, 38, 38, 0.35));
	color: var(--wxas-lock-danger-fg, #dc2626);
	/* 失败提示要醒目：底色带一点红，别只是一行小字。 */
	background: var(--wxas-lock-danger-bg, rgba(220, 38, 38, 0.07));
	font-weight: 600;
}

/*
 * 失败提示文字前的感叹号图标。
 *
 * ⚠️ 用**伪元素**而不是插 `<span>`：三个区块的 say() 都用
 *    `status.textContent = text` 写文案，任何真实子元素都会被整段清掉 ——
 *    真插一个图标，第一次写文案时它就消失了，而且不报错。
 *    （与 `.is-waiting::before` 的转圈同一个道理。）
 *
 * ⚠️ `background` 不能写 `currentColor`：同一条规则里 `color` 已改成白色，
 *    currentColor 会解析成白 → 白底白字。必须显式取 danger 变量。
 */
.wxas-lock .wxas-lock__status.is-err::before {
	content: "!";
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--wxas-lock-danger-fg, #dc2626);
	color: #fff;
	font-size: 10px;
	font-weight: 800;
	line-height: 1;
}

/*
 * ── 「等待支付中…」前的转圈图标 ──────────────────────────────
 *
 * ⚠️ 用**伪元素**而不是插一个 `<span>`：
 *    pay.js 的 `say()` 用 `status.textContent = text` 写入文案，
 *    任何真实子元素都会被它整段清掉 —— 真插一个 <span>，
 *    第一次写文案时转圈就消失了，而且没有任何报错。
 *    伪元素不占 DOM，不受影响。
 *
 * ⚠️ 状态胶囊是 `inline-flex` + `gap`，伪元素会**自动成为第一个
 *    flex item** 并与文字保持 6px 间距，不必额外调 margin。
 *
 * 触发条件是 `is-waiting`（由 pay.js 的 `say( text, 'waiting' )` 加上）。
 * 其它状态（ok / err / 无修饰）不转圈 —— 只有「正在等一个会自己变化的
 * 结果」才需要动效；成功与失败是终态，转圈反而暗示「还没完」。
 */
.wxas-lock .wxas-lock__status.is-waiting::before {
	content: "";
	flex: 0 0 auto;
	width: 11px;
	height: 11px;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	opacity: 0.7;
	animation: wxas-lock-spin 0.8s linear infinite;
}

@keyframes wxas-lock-spin {
	to {
		transform: rotate(360deg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.wxas-lock .wxas-lock__status.is-waiting::before {
		animation: none;
	}
}

/* ── 页脚说明 ─────────────────────────────────────────────── */

/*
 * 页脚说明：始终贴在卡片底部。
 *
 * `margin-top: auto` 吃掉主列的剩余空间 —— 这是把 `space-between`
 * 换掉之后**唯一**负责撑开的一段（理由见 `.wxas-lock__main`）。
 */
.wxas-lock .wxas-lock__foot {
	margin-top: auto;
	display: flex;
	align-items: center;
	gap: 6px;
	padding-top: 2px;
	color: var(--wxas-lock-fg-muted);
	font-size: 11px;
}

/*
 * 码下方（`.wxas-lock__side` 列内）的页脚说明。
 *
 * 积分区块把页脚从右列移到了**码的下方**（业务方要求），此时它不能再用
 * 那条 `margin-top: auto` ——
 *
 *   ⚠️ `__side` 是 `justify-content: center` 的纵向 flex。列内一旦出现
 *      auto 外边距，剩余空间会被它**整段吃掉**，`center` 当场失效：
 *      「码 + 说明」被推到列顶，下方留一大片空白。
 *
 * 因此这里归零并显式居中 —— 与码下方的倒计时（`.wxas-qrbox__countdown`）
 * 同一套对齐：列内水平居中（`__side` 的 `align-items: center`）+ 多行文字
 * 居中对齐（`text-align: center`）。限时模式的文案较长，在 158px 的窄列里
 * 会折成两行，这是预期行为。
 *
 * ⚠️ **顺序要紧**：本规则必须排在 `.wxas-lock .wxas-lock__foot` **之后**。
 *    两者特异性相同（都是 0,2,0），靠先后定胜负。
 */
.wxas-lock__side .wxas-lock__foot {
	margin-top: 0;
	justify-content: center;
	text-align: center;
}

.wxas-lock__foot svg {
	flex: 0 0 auto;
	width: 12px;
	height: 12px;
}

/* ── 已解锁态（正文容器）──────────────────────────────────── */

.wxas-lock .wxas-lock__unlocked {
	border-color: var(--wxas-lock-soft-border);
}

.wxas-lock .wxas-lock__badge {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	margin-bottom: 10px;
	padding: 2px 10px;
	border-radius: 999px;
	background: var(--wxas-lock-step-bg);
	color: var(--wxas-lock-step-fg);
	font-size: 11px;
	font-weight: 600;
}

/* ══════════════════════════════════════════════════════════════════════════
 *  多端适配：≥640px 时二维码列与说明列并排
 * ══════════════════════════════════════════════════════════════════════════
 *
 * 只用一个断点（640px），与设计稿的 `sm:` 对齐。理由见文件顶部。
 * 窄屏不写任何 media query —— 移动优先，默认样式就是窄屏的样子。
 */
@media (min-width: 640px) {
	.wxas-lock .wxas-lock__body {
		flex-direction: row;
		align-items: stretch;
	}

	/*
	 * 二维码列宽度见 `--wxas-lock-side-w`（默认 158px，三个区块共用）。
	 */
	.wxas-lock .wxas-lock__side {
		width: var(--wxas-lock-side-w, 158px);
	}

	.wxas-lock .wxas-lock__actions {
		flex-direction: row;
		align-items: center;
		flex-wrap: wrap;
	}

	.wxas-lock .wxas-lock__btn {
		width: auto;
	}

	.wxas-lock .wxas-lock__link {
		width: auto;
	}

	.wxas-lock .wxas-lock__price-value {
		font-size: 30px;
	}
}

/* ── 深色模式 ─────────────────────────────────────────────── */

@media (prefers-color-scheme: dark) {
	.wxas-lock {
		--wxas-lock-bg: #1b1f24;
		--wxas-lock-border: #2e343c;
		--wxas-lock-fg: #cbd5e1;
		--wxas-lock-fg-strong: #f1f5f9;
		--wxas-lock-fg-muted: #7c8794;
		--wxas-lock-soft-bg: rgba(255, 255, 255, 0.04);
		--wxas-lock-soft-border: #2e343c;
		--wxas-lock-icon-bg: rgba(255, 255, 255, 0.06);
		--wxas-lock-step-bg: rgba(255, 255, 255, 0.12);
		--wxas-lock-ok-fg: #6ee7b7;
		--wxas-lock-ok-border: rgba(110, 231, 183, 0.35);
		--wxas-lock-danger-fg: #fca5a5;
		--wxas-lock-danger-border: rgba(252, 165, 165, 0.35);
		--wxas-lock-danger-bg: rgba(252, 165, 165, 0.14);
		--wxas-lock-skeleton-1: #23282e;
		--wxas-lock-skeleton-2: #2c3239;
		--wxas-lock-qr-border: #39414b;
		--wxas-lock-divider: rgba(255, 255, 255, 0.16);
	}

	/* 二维码白底在深色下保留 —— 微信要扫的是深色码，翻成深底会扫不出。 */
	.wxas-lock__qr {
		border-color: #3c444e;
	}

	.wxas-lock .wxas-lock__code {
		border-color: #2e343c;
		background: #1b1f24;
	}
}

.is-dark-theme .wxas-lock {
	--wxas-lock-bg: #1b1f24;
	--wxas-lock-border: #2e343c;
	--wxas-lock-fg: #cbd5e1;
	--wxas-lock-fg-strong: #f1f5f9;
	--wxas-lock-fg-muted: #7c8794;
	--wxas-lock-soft-bg: rgba(255, 255, 255, 0.04);
	--wxas-lock-soft-border: #2e343c;
	--wxas-lock-icon-bg: rgba(255, 255, 255, 0.06);
	--wxas-lock-step-bg: rgba(255, 255, 255, 0.12);
	--wxas-lock-ok-fg: #6ee7b7;
	--wxas-lock-ok-border: rgba(110, 231, 183, 0.35);
	--wxas-lock-danger-fg: #fca5a5;
	--wxas-lock-danger-border: rgba(252, 165, 165, 0.35);
	--wxas-lock-danger-bg: rgba(252, 165, 165, 0.14);
	--wxas-lock-skeleton-1: #23282e;
	--wxas-lock-skeleton-2: #2c3239;
	--wxas-lock-qr-border: #39414b;
	--wxas-lock-divider: rgba(255, 255, 255, 0.16);
}

/* ── 降低动效偏好 ─────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	.wxas-lock .wxas-lock__btn,
	.wxas-lock .wxas-lock__code {
		transition: none;
	}

	.wxas-lock .wxas-lock__btn:active {
		transform: none;
	}
}
