@charset "UTF-8";
/**
 * 在线预约表单 · 人机验证与提交反馈
 *
 * 主样式表是 site.css（原站视觉 1:1 保留），本文件只提供 site.css 里没有的
 * 自研部件样式：
 *   · 三种人机验证（手滑滑块 / 数字求和 / 点选文字）
 *   · 提交结果提示条（成功 / 重复 / 限流 / 拦截）
 *   · 蜜罐字段
 *
 * 选择器一律带 .zj- 前缀，不覆盖 site.css 的任何规则。
 * 唯一例外是 `#zj-booking-form` 前缀的「字段高度」一节 —— site.css 里 Astra 的
 * input padding 会把输入框撑到 51px，必须用更高特异度才能压回来（详见该节注释）。
 */

:root {
	--zj-navy-900: #152f45;
	--zj-navy-800: #1c3a52;
	--zj-navy-700: #24486a;
	--zj-gold-600: #b08c50;
	--zj-gold-500: #c9a266;
	--zj-gold-100: #f6eedd;
	--zj-ink: #1d2a35;
	--zj-body: #47555f;
	--zj-mute: #8494a0;
	--zj-line: #e5eaee;
	--zj-radius-sm: 10px;
	--zj-danger: #c0392b;
	--zj-shadow-sm: 0 1px 2px rgba(21, 47, 69, .05), 0 3px 10px rgba(21, 47, 69, .05);
	--zj-shadow-md: 0 6px 22px rgba(21, 47, 69, .10);
	--zj-ease: cubic-bezier(.22, .61, .36, 1);
}

/* ------------------------------------------------------------------ *
 * 字段高度：五个输入框统一到 40px，与「点击提交预约」按钮等高
 *
 * 病根在 site.css。Astra 有一条
 *     input[type="text"], input[type="tel"], …, textarea { padding: 14px 21px }
 *     —— 特异度 (0,1,1)
 * 压过 Elementor 原生的
 *     .elementor-field-textual { padding: 5px 14px; min-height: 40px }
 *     —— 特异度 (0,1,0)
 * 于是同一张表单里冒出三种高度：
 *     提交按钮 40px ／ 下拉框 44px ／ 输入框 51px
 * 框比按钮还高，5 个框排下来更是厚重。
 *
 * 修法就照 Elementor 那行原样写（min-height:40px 本来就是它定的），
 * 用 `#zj-booking-form` 把特异度提到 (1,1,0) 压回去。
 * 只作用于本表单，站内其它 input（搜索框等）不受任何影响；
 * site.css 一个字未改。
 * ------------------------------------------------------------------ */
#zj-booking-form .elementor-field-textual {
	line-height: 1.4;
	min-height: 40px;
	padding: 5px 14px;
}

/* 下拉框的高度另有一处不同：它的 line-height 被继承成 1.75（18px → 31.5px），
   单靠 min-height 压不住，得把行高也一起写死。字号保持原样不动。 */
#zj-booking-form select.elementor-field-textual {
	line-height: 1.4;
}

/* ------------------------------------------------------------------ *
 * 字段纵向节奏：每一项的上下空间再收一收
 *
 * 甲方：「每个表单项的上下空间也有点高了，再小一些」
 *
 * 实测改前一项的纵向构成（手机 / 桌面一致，共 82px）：
 *   标签块        32px   ← 字号 18px 不动，行高被 body 继承成 1.75（31.5px）
 *   字段框        40px
 *   组间外边距    10px   ← post-17.css 的 .elementor-field-group{margin-bottom:10px}
 *   （文本框 / 电话框另多 7px —— input 自带 margin-top:7px，
 *     下拉框没有，所以同一张表里两种节奏，这里一并拉齐）
 *
 * 三处一起收：
 *   标签行高   31.5 → 23.4px（1.3，字号 18px 一个字没动）
 *   input 上距 7 → 0px（文本框与下拉框对齐）
 *   组间外边距 10 → 8px（.elementor-form-fields-wrapper 的 -10px 同步改 -8px，
 *                        否则表单底部会多出 2px 不平衡）
 *
 * 都挂在 #zj-booking-form 下，站内其它表单与别的 input 不受影响。 */
#zj-booking-form .elementor-field-label {
	line-height: 1.3;
}

#zj-booking-form .elementor-field-group .elementor-field-textual {
	margin-top: 0;
}

#zj-booking-form .elementor-field-group {
	margin-bottom: 8px;
}

#zj-booking-form .elementor-form-fields-wrapper {
	margin-bottom: -8px;
}

/* 提交结果提示 */
.zj-booking-notice {
	padding: 14px 18px;
	border-radius: var(--zj-radius-sm);
	font-size: 14.5px;
	margin-bottom: 18px;
	animation: zj-fade-slide .4s var(--zj-ease-out);
}

.zj-notice-ok {
	background: #eef8f0;
	border: 1px solid #bfe3c8;
	color: #2e7d43;
}

.zj-notice-spam,
.zj-notice-error,
.zj-notice-err {
	background: #fdf1f0;
	border: 1px solid #f0c8c5;
	color: #b23c39;
}

/* 蜜罐 */
.zj-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}


/* ==================================================================
 * 15. 人机验证组件（预约表单防刷）
 *
 * 三种形态共用 .zj-cap 外壳，靠 data-zj-cap 区分：
 *   slider 手滑滑块 / math 数字求和 / click 点选文字
 * 交互状态类：is-drag（拖动中）、is-ok（通过）、is-shake（点错）
 * ================================================================== */

.zj-cap {
	--zj-cap-h: 48px;
	/* 与上一项的间距随字段节奏一起收：22 → 16（配合组间距 10→8，上方净留白 30 → 24px） */
	margin: 16px 0 6px;
	/*
	 * 宽度兜底：site.css 里 Elementor 的 .elementor-field-group 是 display:flex，
	 * 验证组件作为它的直接子元素，不给宽度就会被 flex 压成 2px —— 滑块只剩一条缝。
	 * 三种验证形态（滑块 / 算术 / 点选）都以 .zj-cap 为外壳，这里统一撑满。
	 */
	width: 100%;
	min-width: 0;
	flex: 1 1 auto;
	box-sizing: border-box;
}

/* ---------------- 手滑滑块 ---------------- */

.zj-cap-slider {
	position: relative;
	height: var(--zj-cap-h);
	border: 1px solid var(--zj-line);
	border-radius: 999px;
	background: #eef3f7;
	overflow: hidden;
	user-select: none;
	-webkit-user-select: none;
	-webkit-touch-callout: none;
	-webkit-tap-highlight-color: transparent;
	/* 触摸落在滑块上时必须原地被吃掉：不许页面滚动、不许下拉刷新、
	   不许横向翻页。少了这两行，手机上滑动会变成「翻页」把网页划走。 */
	touch-action: none;
	overscroll-behavior: contain;
}

.zj-cap-rail {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

.zj-cap-fill {
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: var(--zj-w, 0px);
	background: linear-gradient(90deg, rgba(201, 162, 102, .12), rgba(201, 162, 102, .34));
	transition: width .2s var(--zj-ease);
}

.zj-cap-slider.is-drag .zj-cap-fill {
	transition: none;
}

.zj-cap-tip {
	position: relative;
	font-size: 13px;
	letter-spacing: .04em;
	color: var(--zj-mute);
	transition: opacity .2s;
}

.zj-cap-ok-tip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--zj-navy-700);
}

.zj-cap-ok-tip svg {
	width: 18px;
	height: 18px;
}

.zj-cap-slider .zj-cap-ok-tip {
	position: absolute;
	opacity: 0;
	transition: opacity .25s;
}

.zj-cap.is-ok .zj-cap-tip {
	opacity: 0;
}

.zj-cap.is-ok .zj-cap-ok-tip {
	opacity: 1;
}

.zj-cap-knob {
	position: absolute;
	top: 4px;
	left: 4px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: calc(var(--zj-cap-h) - 8px);
	height: calc(var(--zj-cap-h) - 8px);
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: #fff;
	color: var(--zj-gold-600);
	box-shadow: var(--zj-shadow-sm);
	cursor: grab;
	touch-action: none;
	transform: translateX(var(--zj-x, 0px));
	transition: transform .2s var(--zj-ease), box-shadow .2s, background .2s;
}

.zj-cap-knob svg {
	width: 15px;
	height: 15px;
	opacity: .55;
}

.zj-cap-knob svg + svg {
	margin-left: -6px;
}

.zj-cap-slider.is-drag .zj-cap-knob {
	cursor: grabbing;
	transition: none;
	box-shadow: var(--zj-shadow-md);
}

.zj-cap.is-ok .zj-cap-knob {
	background: var(--zj-navy-800);
	color: #fff;
	cursor: default;
}

.zj-cap.is-ok .zj-cap-knob svg {
	opacity: 0;
}

/* ---------------- 数字求和 ---------------- */

.zj-cap-math {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 12px;
}

.zj-cap-badge {
	padding: 5px 11px;
	border-radius: 999px;
	background: var(--zj-gold-100);
	color: var(--zj-gold-600);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .06em;
}

.zj-cap-eq {
	font-size: 18px;
	font-weight: 700;
	letter-spacing: .06em;
	color: var(--zj-navy-900);
}

.zj-cap-input {
	width: 120px;
	height: 46px;
	padding: 0 14px;
	border: 1px solid var(--zj-line);
	border-radius: var(--zj-radius-sm);
	background: #fff;
	color: var(--zj-ink);
	font-size: 16px;
	transition: border-color .18s, box-shadow .18s;
}

.zj-cap-input:focus {
	outline: 0;
	border-color: var(--zj-gold-500);
	box-shadow: 0 0 0 3px rgba(201, 162, 102, .18);
}

/* ---------------- 点选文字 ---------------- */

.zj-cap-click .zj-cap-tip {
	margin: 0 0 13px;
	font-size: 14px;
	color: var(--zj-body);
}

.zj-cap-click .zj-cap-tip b {
	display: inline-block;
	min-width: 32px;
	margin: 0 3px;
	padding: 2px 8px;
	border-radius: 7px;
	background: var(--zj-gold-100);
	color: var(--zj-navy-900);
	font-weight: 700;
	text-align: center;
}

.zj-cap-click .zj-cap-tip i {
	font-style: normal;
	color: var(--zj-mute);
}

.zj-cap-tiles {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}

.zj-cap-tile {
	position: relative;
	width: 52px;
	height: 52px;
	padding: 0;
	border: 1px solid var(--zj-line);
	border-radius: 12px;
	background: #fff;
	color: var(--zj-navy-900);
	font-size: 20px;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	transition: transform .16s var(--zj-ease), border-color .16s, box-shadow .16s, background .16s;
}

.zj-cap-tile:hover {
	transform: translateY(-2px);
	border-color: var(--zj-gold-500);
	box-shadow: var(--zj-shadow-sm);
}

.zj-cap-tile.is-picked {
	background: var(--zj-navy-800);
	border-color: var(--zj-navy-800);
	color: #fff;
	transform: none;
}

.zj-cap-tile.is-picked::after {
	content: attr(data-step);
	position: absolute;
	top: -7px;
	right: -7px;
	width: 19px;
	height: 19px;
	border-radius: 50%;
	background: var(--zj-gold-500);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	line-height: 19px;
	text-align: center;
}

.zj-cap-click .zj-cap-ok-tip {
	opacity: 0;
	transition: opacity .25s;
}

.zj-cap-click.is-ok .zj-cap-ok-tip {
	opacity: 1;
}

.zj-cap.is-ok .zj-cap-tiles {
	pointer-events: none;
}

/* ---------------- 抖动反馈 ---------------- */

@keyframes zj-cap-shake {
	0%, 100% { transform: translateX(0); }
	20% { transform: translateX(-6px); }
	40% { transform: translateX(6px); }
	60% { transform: translateX(-4px); }
	80% { transform: translateX(4px); }
}

.zj-cap.is-shake {
	animation: zj-cap-shake .4s var(--zj-ease);
}

/* 滑到一半松手时的反馈：抖的是滑块本身，不是整块验证区 */
.zj-cap-slider.is-shake {
	animation: zj-cap-shake .4s var(--zj-ease);
}

@media (max-width: 767px) {
	.zj-cap {
		--zj-cap-h: 46px;
	}

	.zj-cap-tile {
		width: 46px;
		height: 46px;
		font-size: 18px;
	}

	.zj-cap-input {
		width: 100px;
		height: 44px;
	}
}


/* ------------------------------------------------------------------ *
 * 字段级错误提示
 *
 * 提交被挡回来时，光有一条「此字段必填」的横幅是不够的 —— 客户得知道
 * 是哪一栏。这里给出红框 + 字段正下方的红字，配合 JS 的滚动定位。
 * 用 !important 是因为 Elementor 的字段样式优先级很高。
 * ------------------------------------------------------------------ */
.zj-field-error > .elementor-field-textual,
.zj-field-error .elementor-field-textual,
.zj-field-error .zj-cap-slider {
	border-color: var(--zj-danger, #d9534f) !important;
}

.zj-field-error > .elementor-field-textual,
.zj-field-error .elementor-field-textual {
	background-color: #fffafa !important;
}

.zj-field-error .elementor-field-label {
	color: var(--zj-danger, #d9534f);
}

.zj-field-msg {
	margin-top: 6px;
	font-size: 13px;
	line-height: 1.55;
	color: var(--zj-danger, #d9534f);
}

/* ------------------------------------------------------------------ *
 * 提交结果提示条（现在位于提交按钮下方）
 * ------------------------------------------------------------------ */
.zj-booking-result {
	margin-top: 18px;
}

.zj-booking-result:empty {
	display: none;
}

.zj-booking-result .zj-booking-notice {
	margin-bottom: 0;
}

.zj-booking-result .zj-booking-notice + .zj-booking-notice {
	margin-top: 12px;
}
