/**
 * polaris/float-bar + polaris/float-bar-item 样式 —— 前台 + 编辑器共用。
 * (子块的样式并在这里,和 tabs/tab 一样,子块目录下没有自己的 style.css。)
 *
 * 三条贯穿全文的约定,改动前先读:
 *
 * 1. **默认值一律写在 :where() 里。** 背景、文字色、圆角、内边距这几项同时也是原生
 *    「样式」面板的地盘(block.json 的 supports.color / spacing / border),WP 会往
 *    wrapper 上挂 .has-*-background-color 这类类,或者直接写 inline style。用
 *    :where() 把默认值的特异性压到 0,用户一设就赢,不需要打 !important 战争。
 *
 * 2. **不用 [hidden] / display:none 做进出场。** display 不可过渡,一切显隐都靠
 *    opacity + visibility + transform 三件套,visibility 同时负责把隐藏状态挡在
 *    Tab 序列和读屏之外(单纯 opacity:0 是"看不见但仍可聚焦",键盘用户会掉进
 *    一个不存在的按钮里)。
 *
 * 3. **移动端断点固定 782px,和 polaris/nav 的抽屉断点对齐。** 故意不做成可配:
 *    导航已经变汉堡菜单了而悬浮条还立在右侧,比"断点不够灵活"糟得多。
 *    view.js 里也硬编码了同一个数字(找 MOBILE_BREAKPOINT),两处要一起改。
 */

/* ═══════════════════════════════════════════
   外层容器 —— 桌面态定位
   ───────────────────────────────────────────
   position:fixed 极易被祖先链上的 transform/filter/will-change 劫持(变成相对那个
   祖先定位,悬浮条直接飞走)。这个块的正常归宿是页脚模板部件,没法要求每个站的
   页脚都干净,所以 view.js 启动时会把整个节点 portal 到 <body> 下 —— 下面这些
   定位规则的前提是"父元素就是 body"。
═══════════════════════════════════════════ */
.polaris-float-bar {
	position: fixed;
	z-index: var( --polaris-z-float-bar, 9000 );
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var( --polaris-fb-gap, 0 );
	/* 进出场滑动与"垂直居中"共用 transform,拆成两个变量各管一轴,互不覆盖。 */
	transform: translate( var( --polaris-fb-tx, 0 ), var( --polaris-fb-ty, 0 ) );
	transition: opacity 240ms ease, transform 240ms ease, visibility 240ms;
}

:where( .polaris-float-bar ) {
	background: var( --wp--preset--color--ink-25, rgba( 0, 0, 0, 0.28 ) );
	color: var( --wp--preset--color--on-primary, #fff );
	border-radius: 999px;
	padding: 0.375rem;
}

/* 背景模糊(毛玻璃)。只有条的背景色半透明时才看得出来 —— 不透明的背景后面没有
   东西可透。-webkit- 前缀是 Safari 需要的,到现在仍未去前缀。 */
.polaris-float-bar.has-backdrop-blur {
	-webkit-backdrop-filter: blur( var( --polaris-fb-backdrop-blur, 8px ) );
	backdrop-filter: blur( var( --polaris-fb-backdrop-blur, 8px ) );
}

.polaris-float-bar.is-side-right {
	right: var( --polaris-fb-offset-side, 1rem );
}
.polaris-float-bar.is-side-left {
	left: var( --polaris-fb-offset-side, 1rem );
}

/* 垂直三档。middle 是默认值,也是避开右下角在线客服浮窗的第一道手段。 */
.polaris-float-bar.is-align-middle {
	top: 50%;
	--polaris-fb-ty: -50%;
}
.polaris-float-bar.is-align-bottom {
	bottom: var( --polaris-fb-offset-bottom, 1rem );
}
.polaris-float-bar.is-align-custom {
	top: var( --polaris-fb-offset-top, 20vh );
}

/* ── 整条的显示时机 ──
   is-visibility-scrolled:默认藏起来,view.js 滚过阈值后加 .is-shown。
   收起时往贴边方向滑出一点,方向跟着 side 镜像。 */
.polaris-float-bar.is-visibility-scrolled {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}
.polaris-float-bar.is-visibility-scrolled.is-side-right {
	--polaris-fb-tx: 1rem;
}
.polaris-float-bar.is-visibility-scrolled.is-side-left {
	--polaris-fb-tx: -1rem;
}
.polaris-float-bar.is-visibility-scrolled.is-shown {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	--polaris-fb-tx: 0;
}

.polaris-float-bar__list {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var( --polaris-fb-gap, 0 );
}

/* ═══════════════════════════════════════════
   单格:触发器 + 图标
═══════════════════════════════════════════ */
.polaris-float-bar__item {
	position: relative; /* 展开面板的定位基准 */
	display: flex;
}

.polaris-float-bar__trigger,
.polaris-float-bar__top {
	position: relative;
	z-index: 1; /* 盖在卡片式面板之上,免得二维码卡的边缘压到圆钮上 */
	box-sizing: border-box;
	width: var( --polaris-fb-size, 3.25rem );
	height: var( --polaris-fb-size, 3.25rem );
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 0;
	/* 默认 50% = 圆钮。给一个具体长度(0 / 8px …)就变成方格或圆角方块 —— 整条的
	   形态由「条自身的圆角」和这个值一起决定:胶囊条配圆钮、方条配方格。 */
	border-radius: var( --polaris-fb-item-radius, 50% );
	background: transparent;
	color: inherit;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 180ms ease, color 180ms ease;
}
.polaris-float-bar__trigger:focus-visible,
.polaris-float-bar__top:focus-visible {
	outline: 2px solid var( --wp--preset--color--on-primary, #fff );
	outline-offset: -3px;
}

/* 悬停高亮:只在真正有悬停能力的指针下生效。触屏上 :hover 会"粘住"(点完一直保持
   高亮直到点别处),用 @media (hover: hover) 挡掉比事后用 JS 清除干净得多。 */
@media ( hover: hover ) {
	.polaris-float-bar__item:hover > .polaris-float-bar__trigger {
		background: var( --polaris-fb-hover-bg, var( --wp--preset--color--primary, #2563eb ) );
		color: var( --polaris-fb-hover-fg, var( --wp--preset--color--on-primary, #fff ) );
	}
}
/*
 * 键盘展开用 :has(:focus-visible),**不能**用 :focus-within。
 *
 * 桌面端点一下电话那种 <a>,焦点会留在链接上(tel: 不导航离开页面),:focus-within
 * 于是一直成立 —— 鼠标移开了胶囊还张着,再也收不回去(实测踩过)。:focus-visible
 * 只在键盘导航时匹配,鼠标点击不匹配,正好把这两种情况分开:键盘 Tab 过来照常展开,
 * 鼠标点完移开就收。
 *
 * 不支持 :has() 的浏览器会整条忽略 = 键盘用户看不到展开的号码,但链接照样能 Tab 到、
 * 能激活,而号码本来就拼在触发器的 aria-label 里,读屏不受影响。
 */
.polaris-float-bar__item:has( :focus-visible ) > .polaris-float-bar__trigger,
.polaris-float-bar__item.is-open > .polaris-float-bar__trigger {
	background: var( --polaris-fb-hover-bg, var( --wp--preset--color--primary, #2563eb ) );
	color: var( --polaris-fb-hover-fg, var( --wp--preset--color--on-primary, #fff ) );
}

.polaris-float-bar__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: var( --polaris-fb-typography-font-size, 1.35rem );
	line-height: 1;
}
.polaris-float-bar__icon svg {
	width: 1em;
	height: 1em;
	display: block;
}
.polaris-float-bar__icon img {
	width: 1.35em;
	height: 1.35em;
	object-fit: contain;
	display: block;
}
/* 自定义 SVG 的分项着色:没设的那一项保留 SVG 自带配色。跳过 fill="none",
   线框图标才不会被填成一块色饼(和 polaris/tabs 的图标着色是同一套规则)。 */
.polaris-float-bar__icon.is-fill-tinted svg :not( [fill="none"] ) {
	fill: var( --polaris-icon-fill );
}
.polaris-float-bar__icon.is-stroke-tinted svg :not( [stroke="none"] ) {
	stroke: var( --polaris-icon-stroke );
}

/* 桌面端不显示文字标签(条就那么窄),但标签始终留在 DOM 里 —— 触发器可能没有
   别的可读文本,留着读屏也拿得到内容。移动端横条才把它显示出来。 */
.polaris-float-bar__label {
	display: none;
}

/* 分隔线:两格之间一道细线,默认跟着当前文字色淡化,不写死颜色。 */
.polaris-float-bar.has-divider .polaris-float-bar__item + .polaris-float-bar__item::after {
	content: "";
	position: absolute;
	top: 0;
	left: 22%;
	right: 22%;
	height: 1px;
	background: var( --polaris-fb-divider, color-mix( in srgb, currentColor 30%, transparent ) );
	pointer-events: none;
}

/* ═══════════════════════════════════════════
   展开面板
   ───────────────────────────────────────────
   这里只剩卡片式的两种:
     is-panel-qr     二维码卡片,浮在条外侧。
     is-panel-custom 内嵌任意区块的卡片,几何同上。

   文字档位**不在这里** —— 它没有独立的面板层,那串字长在触发器身上、靠触发器自己
   变长来展开(见下面「文字档位」那一节)。
═══════════════════════════════════════════ */
.polaris-float-bar__panel {
	position: absolute;
	top: 50%;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transform: translate( var( --polaris-fb-slide, 0.5rem ), -50% );
	transition: opacity 200ms ease, transform 200ms ease, visibility 200ms;
}
.polaris-float-bar.is-side-left .polaris-float-bar__panel {
	--polaris-fb-slide: -0.5rem;
}

/* 展开条件三选一:悬停(仅限有悬停能力的指针)/ 键盘聚焦到格内 / JS 点击开合。 */
@media ( hover: hover ) {
	.polaris-float-bar__item:hover > .polaris-float-bar__panel {
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
		--polaris-fb-slide: 0px;
		--polaris-fb-slide-y: 0px;
	}
}
.polaris-float-bar__item:has( :focus-visible ) > .polaris-float-bar__panel,
.polaris-float-bar__item.is-open > .polaris-float-bar__panel {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	--polaris-fb-slide: 0px;
	--polaris-fb-slide-y: 0px;
}

/* 文字档位没有独立面板层,展开与否是格子上的两个变量说了算(见下面「文字档位」那节)。
   触发条件与上面的面板完全一致,单独列一遍是因为变量要落在格子上、不是面板上。 */
@media ( hover: hover ) {
	.polaris-float-bar__item:hover {
		--polaris-fb-text-open: var( --polaris-fb-text-w, max-content );
		--polaris-fb-text-opacity: 1;
	}
}
.polaris-float-bar__item:has( :focus-visible ),
.polaris-float-bar__item.is-open {
	--polaris-fb-text-open: var( --polaris-fb-text-w, max-content );
	--polaris-fb-text-opacity: 1;
}

/* 移动端专用的「动作面板」:桌面端不存在(号码长在触发器身上),只有窄屏横条才由
   下面的媒体查询把它变成 sheet。理由见 float-bar-item/render.php 里的说明。 */
.polaris-float-bar__panel.is-panel-action {
	display: none;
}

/* ═══════════════════════════════════════════
   文字档位:格子自己变长,不是叠一层
   ───────────────────────────────────────────
   以前这是一颗绝对定位的药丸垫在圆钮底下,图标钉死不动、文字从它背后抽出来。现在
   改成**触发器本身**就是那颗药丸:它绝对定位、锚在贴边那一侧,宽度随内部文字的列宽
   从 0fr 长到 1fr。因为锚点在贴边那侧,变长的方向必然朝屏幕内侧,图标(在药丸的
   另一端)就被推着一起移动,文字在图标内侧一格一格露出来。

   为什么锁死外层格子的尺寸:整条是 flex column + align-items:center,让格子跟着变宽
   会把整条撑宽、其余格子全部重新居中。所以尺寸留在格子上,生长交给里面那颗绝对定位
   的药丸,条的版式纹丝不动。

   顺带去掉了一个老包袱:药丸和圆钮不再是两个需要"拼接对齐"的元素(以前靠触发器的
   z-index 把药丸的一端盖住来伪装成一体),现在本来就是同一个元素,不存在拼歪。
═══════════════════════════════════════════ */
.polaris-float-bar__item.has-panel-text {
	box-sizing: border-box;
	width: var( --polaris-fb-size, 3.25rem );
	height: var( --polaris-fb-size, 3.25rem );
	flex: none;
}
.polaris-float-bar__item.has-panel-text > .polaris-float-bar__trigger {
	position: absolute;
	top: 0;
	width: auto;
	min-width: var( --polaris-fb-size, 3.25rem );
	justify-content: flex-start;
	/* 用胶囊圆角而不是每格圆角:50% 落在一个变长的盒子上会得到橄榄球,而 999px 在
	   正方形上看起来就是正圆 —— 折叠态和展开态因此能共用同一个值。 */
	border-radius: var( --polaris-fb-pill-radius, 999px );
	transition: background-color 180ms ease, color 180ms ease;
}
/* 贴右侧:锚右边缘,向左长,图标在药丸左端、文字在图标右侧。 */
.polaris-float-bar.is-side-right .polaris-float-bar__item.has-panel-text > .polaris-float-bar__trigger {
	right: 0;
	left: auto;
}
/* 贴左侧:整个镜像 —— 锚左边缘向右长,图标换到药丸右端(row-reverse),文字在图标左侧。 */
.polaris-float-bar.is-side-left .polaris-float-bar__item.has-panel-text > .polaris-float-bar__trigger {
	left: 0;
	right: auto;
	flex-direction: row-reverse;
}
/* 图标固定成一个与格子等大的方框:折叠时药丸宽度 = 这个方框 = 一颗正圆,图标天然
   居中;展开后它保持原尺寸待在药丸端头,不会被文字挤扁。 */
.polaris-float-bar__item.has-panel-text > .polaris-float-bar__trigger > .polaris-float-bar__icon {
	flex: none;
	width: var( --polaris-fb-size, 3.25rem );
	height: var( --polaris-fb-size, 3.25rem );
}

/*
 * 展开靠的是一个**具体的 px 宽度**,由 view.js 量出文字的自然宽度后写进
 * --polaris-fb-text-w(挂在格子上)。
 *
 * 为什么不用流行的 grid 0fr→1fr 那套:那个技巧要求 grid 容器有确定宽度,而这里的
 * 药丸必须由内容撑开(shrink-to-fit 的绝对定位盒子)。实测在这种容器里,fr 轨道
 * 一律收敛到 min-content —— `1fr`、`0fr`、`minmax(0,1fr)` 量出来都是 0,只有
 * `max-content` 能撑开,而 max-content 是不可动画的关键字。所以这条路根本走不通,
 * 只能由 JS 提供那个数(量内容的自然尺寸本来就是 CSS 做不到的事,和条高
 * --polaris-fb-h 是同一类问题)。
 *
 * JS 没跑起来时回退到 max-content:宽度依然正确,只是没有过渡、直接跳变。
 */
.polaris-float-bar__text {
	width: var( --polaris-fb-text-open, 0px );
	overflow: hidden;
	transition: width 260ms ease;
}
.polaris-float-bar__text-inner {
	display: block;
	white-space: nowrap;
	font-size: var( --polaris-fb-typography-font-size, var( --wp--preset--font-size--md, 1rem ) );
	font-weight: var( --polaris-fb-typography-font-weight, 600 );
	line-height: var( --polaris-fb-typography-line-height, 1 );
	opacity: var( --polaris-fb-text-opacity, 0 );
	transition: opacity 180ms ease;
}
/* 内侧留白靠向文字那一端,贴哪边就往哪边镜像。 */
.polaris-float-bar.is-side-right .polaris-float-bar__text-inner {
	padding-left: 0.15rem;
	padding-right: 1.35rem;
}
.polaris-float-bar.is-side-left .polaris-float-bar__text-inner {
	padding-right: 0.15rem;
	padding-left: 1.35rem;
}

/* ── 二维码 / 自定义卡片 ──
   宽度、内边距、圆角、区块间距、配色都逐格可调,由 float-bar-item/render.php 把
   对应属性写成这些自定义属性挂在面板自己身上;留空就落到这里的默认值。
   配色那两项与父块设在条上的同名变量重名是有意的 —— 条上那份是全局默认,面板上
   这份是单点覆盖,继承规则本身就是 fallback,不需要再套一层 var()。 */
.polaris-float-bar__panel.is-panel-qr,
.polaris-float-bar__panel.is-panel-custom {
	display: flex;
	flex-direction: column;
	gap: var( --polaris-fb-panel-gap, 0.5rem );
	box-sizing: border-box;
	width: var( --polaris-fb-panel-w, auto );
	max-width: min( 20rem, calc( 100vw - 2rem ) );
	padding:
		var( --polaris-fb-panel-pad-top, 0.75rem )
		var( --polaris-fb-panel-pad-right, 0.75rem )
		var( --polaris-fb-panel-pad-bottom, 0.75rem )
		var( --polaris-fb-panel-pad-left, 0.75rem );
	border-radius: var( --polaris-fb-panel-radius, 12px );
	background: var( --polaris-fb-panel-bg, var( --wp--preset--color--base, #fff ) );
	color: var( --polaris-fb-panel-fg, var( --wp--preset--color--ink-85, rgba( 0, 0, 0, 0.85 ) ) );
	box-shadow: 0 12px 32px rgba( 0, 0, 0, 0.18 );
}
/* 二维码是一张方图配一行说明,居中才好看;自定义面板装的是任意区块(段落、表单、
   按钮…),那些东西按自己的对齐方式排,强行居中反而处处要覆盖。 */
.polaris-float-bar__panel.is-panel-qr {
	align-items: center;
	text-align: center;
}
.polaris-float-bar__panel.is-panel-custom {
	align-items: stretch;
}
/* 只有真的设了「区块间距」才接管子块的原生外边距 —— 否则 gap 和 margin 会叠加,
   调出来的数值和看到的间距对不上。 */
.polaris-float-bar__panel.is-panel-custom.has-panel-gap > * {
	margin-block: 0;
}
.polaris-float-bar.is-side-right .polaris-float-bar__panel.is-panel-qr,
.polaris-float-bar.is-side-right .polaris-float-bar__panel.is-panel-custom {
	right: calc( 100% + 0.625rem );
}
.polaris-float-bar.is-side-left .polaris-float-bar__panel.is-panel-qr,
.polaris-float-bar.is-side-left .polaris-float-bar__panel.is-panel-custom {
	left: calc( 100% + 0.625rem );
}

/* 二维码面板的宽度**只**跟着二维码本身走(Inspector 里那档没有「宽度」设置):
   width:max-content 让面板正好裹住图片,max-width 是防止把二维码调得比屏幕还宽时
   顶出视口 —— 那时图片的 max-width:100% 会把它收回面板内,不会溢出。 */
.polaris-float-bar__panel.is-panel-qr {
	width: max-content;
	max-width: calc( 100vw - 2rem );
}
.polaris-float-bar__qr {
	display: block;
	width: var( --polaris-fb-qr-size, 9rem );
	max-width: 100%;
	height: auto;
	border-radius: var( --polaris-fb-qr-radius, 4px );
}
.polaris-float-bar__qr-caption {
	font-size: var( --wp--preset--font-size--sm, 0.875rem );
	line-height: 1.35;
}
.polaris-float-bar__panel.is-panel-custom > :first-child {
	margin-top: 0;
}
.polaris-float-bar__panel.is-panel-custom > :last-child {
	margin-bottom: 0;
}

/* ═══════════════════════════════════════════
   返回顶部
   ───────────────────────────────────────────
   不是子块,是父块的内置能力,固定钉在条的末端。它有独立于整条的显示阈值:整条
   可以一直在,返回顶部只在滚下去之后才冒出来。收起时 visibility:hidden 一并把它
   挡在 Tab 序列外,render.php 里的 aria-hidden/tabindex=-1 是同一件事的初始状态,
   view.js 会随显隐同步这两个属性。
═══════════════════════════════════════════ */
.polaris-float-bar__top {
	background: var( --polaris-fb-top-bg, var( --wp--preset--color--primary, #2563eb ) );
	color: var( --polaris-fb-top-fg, var( --wp--preset--color--on-primary, #fff ) );
	opacity: 0;
	visibility: hidden;
	transform: scale( 0.8 );
	/*
	 * 收起时必须真正**不占位**。visibility:hidden 只是看不见,盒子还在,条的底部会
	 * 空出一格,阈值没到之前那一块灰色悬在那儿很突兀。
	 * display:none 不能过渡,所以改成把高度收到 0 + overflow:hidden —— 高度是
	 * --polaris-fb-size 这个确定值,0 ↔ 确定值之间可以正常过渡。
	 */
	height: 0;
	min-height: 0;
	overflow: hidden;
	/* 格与格之间设了间距时,收起态还会剩下一份 gap 的空隙,用负外边距抵掉。 */
	margin-block-start: calc( -1 * var( --polaris-fb-gap, 0px ) );
	transition: height 220ms ease, margin-block-start 220ms ease, opacity 200ms ease,
		transform 200ms ease, visibility 200ms, background-color 180ms ease;
}
.polaris-float-bar__top.is-shown {
	height: var( --polaris-fb-size, 3.25rem );
	margin-block-start: 0;
	opacity: 1;
	visibility: visible;
	transform: none;
}
@media ( hover: hover ) {
	.polaris-float-bar__top:hover {
		background: var( --polaris-fb-hover-bg, var( --wp--preset--color--primary-hover, #1d4ed8 ) );
	}
}

/* ═══════════════════════════════════════════
   移动端(≤782px,与 polaris/nav 抽屉同断点)
   ───────────────────────────────────────────
   --polaris-fb-h 由 view.js 测出横条实际高度后写到 <html> 上,只服务于**条外面**的
   两件事:给 <body> 补底部留白、把第三方客服浮窗抬到条上方。条自己内部的元素
   (sheet、返回顶部圆钮)一律用 bottom:calc(100% + …) 相对整条定位,不读这个变量。

   **不要**在用到它的地方再加一次 env(safe-area-inset-bottom):横条自己的
   padding-bottom 里已经含了安全区,而 offsetHeight 把 padding 算在内,重复加会
   凭空多出一截留白。
═══════════════════════════════════════════ */
@media screen and ( max-width: 782px ) {

	.polaris-float-bar.is-mobile-hide {
		display: none;
	}

	/* 「保持侧边竖排」形态沿用桌面那套几何,但卡片式面板是往条的外侧展开的,窄屏上
	   一张 20rem 的二维码卡会直接顶出屏幕左边。这里按视口宽度收一道上限——只有这
	   一处需要,底部横条形态的 sheet 本来就是按 left/right 拉伸的。 */
	.polaris-float-bar.is-mobile-rail .polaris-float-bar__panel.is-panel-qr,
	.polaris-float-bar.is-mobile-rail .polaris-float-bar__panel.is-panel-custom {
		max-width: calc( 100vw - var( --polaris-fb-size, 3.25rem ) - 2.5rem );
	}

	.polaris-float-bar.is-mobile-bar {
		top: auto;
		bottom: 0;
		left: 0;
		right: 0;
		--polaris-fb-tx: 0;
		--polaris-fb-ty: 0;
		flex-direction: row;
		align-items: stretch;
		gap: 0;
	}
	:where( .polaris-float-bar.is-mobile-bar ) {
		border-radius: 0;
		/* iOS 全面屏:底部 home indicator 会压住最后一行,安全区内边距不能省。 */
		padding: 0 0 env( safe-area-inset-bottom, 0px );
	}
	/* 收起态改成向下滑出,不再沿用桌面的左右滑。 */
	.polaris-float-bar.is-mobile-bar.is-visibility-scrolled {
		--polaris-fb-ty: 100%;
	}
	.polaris-float-bar.is-mobile-bar.is-visibility-scrolled.is-shown {
		--polaris-fb-ty: 0;
	}

	.is-mobile-bar .polaris-float-bar__list {
		flex-direction: row;
		align-items: stretch;
		width: 100%;
		gap: 0;
	}
	.is-mobile-bar .polaris-float-bar__item {
		flex: 1 1 0;
		min-width: 0; /* flex 子项默认 min-width:auto,长标签会把某一格顶宽、挤掉其它格 */
		/* 关掉格子的定位基准,好让里面的 sheet 改为相对**整条**定位、横铺满屏
		   (见下面 sheet 那段的注释)。 */
		position: static;
	}
	.is-mobile-bar .polaris-float-bar__item.is-hidden-mobile {
		display: none;
	}
	.is-mobile-bar .polaris-float-bar__trigger {
		width: 100%;
		height: auto;
		min-height: 3.25rem;
		flex-direction: column;
		gap: 0.2rem;
		padding: 0.5rem 0.25rem;
		border-radius: 0;
	}
	.is-mobile-bar .polaris-float-bar__icon {
		font-size: var( --polaris-fb-typography-font-size, 1.25rem );
	}
	.is-mobile-bar.has-mobile-labels .polaris-float-bar__label {
		display: block;
		max-width: 100%;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		font-size: var( --polaris-fb-typography-font-size, 0.6875rem );
		font-weight: var( --polaris-fb-typography-font-weight, 400 );
		line-height: var( --polaris-fb-typography-line-height, 1.2 );
	}
	/* 横条里分隔线要转 90 度。竖排那版是格子上的绝对定位伪元素,而横条里格子已经
	   position:static、伪元素会改为相对整条定位(四条线全挤到最左边),所以这里
	   换成边框实现,不再用伪元素。 */
	.polaris-float-bar.is-mobile-bar.has-divider .polaris-float-bar__item + .polaris-float-bar__item::after {
		content: none;
	}
	.polaris-float-bar.is-mobile-bar.has-divider .polaris-float-bar__item + .polaris-float-bar__item {
		border-left: 1px solid var( --polaris-fb-divider, color-mix( in srgb, currentColor 30%, transparent ) );
	}

	/* 文字在横条上没有意义:一格宽度装不下号码,而点下去本来就是直接拨号。
	   同时把桌面那套「格子锁尺寸 + 药丸绝对定位」整个撤掉 —— 横条里每格是等分的
	   flex 项,触发器要回到正常文档流铺满格子。 */
	.polaris-float-bar.is-mobile-bar .polaris-float-bar__text {
		display: none;
	}
	.polaris-float-bar.is-mobile-bar .polaris-float-bar__item.has-panel-text {
		width: auto;
		height: auto;
		flex: 1 1 0;
	}
	.polaris-float-bar.is-mobile-bar .polaris-float-bar__item.has-panel-text > .polaris-float-bar__trigger {
		position: static;
		/* width/min-width 也得在这里重申一遍:桌面那条 .has-panel-text > .trigger 是
		   (0,3,0),压得过通用的 .is-mobile-bar .trigger (0,2,0),不覆盖的话触发器会
		   停在 52px、在等分格子里偏向一侧(实测踩过)。 */
		width: 100%;
		min-width: 0;
		justify-content: center;
	}
	.polaris-float-bar.is-mobile-bar .polaris-float-bar__item.has-panel-text > .polaris-float-bar__trigger > .polaris-float-bar__icon {
		width: auto;
		height: auto;
	}

	/* 二维码 / 自定义面板 → 从横条上方升起的 sheet(hover 气泡在触屏上没有意义)。
	   选择器里带上 .is-side-* 不是啰嗦:桌面那两条镜像规则
	   (.polaris-float-bar.is-side-right .polaris-float-bar__panel.is-panel-qr 之类)
	   是 (0,4,0),不带侧边类的写法只有 (0,3,0),会被它们的 right:calc(100% + …)
	   压住,sheet 直接被挤成一条 24px 的窄缝(实测踩过)。 */
	.polaris-float-bar.is-mobile-bar.is-side-right .polaris-float-bar__panel.is-panel-qr,
	.polaris-float-bar.is-mobile-bar.is-side-right .polaris-float-bar__panel.is-panel-custom,
	.polaris-float-bar.is-mobile-bar.is-side-right .polaris-float-bar__panel.is-panel-action,
	.polaris-float-bar.is-mobile-bar.is-side-left .polaris-float-bar__panel.is-panel-qr,
	.polaris-float-bar.is-mobile-bar.is-side-left .polaris-float-bar__panel.is-panel-custom,
	.polaris-float-bar.is-mobile-bar.is-side-left .polaris-float-bar__panel.is-panel-action {
		/*
		 * 这里**必须**是 absolute,不能是 fixed。整条身上一直挂着 transform(进出场
		 * 滑动和垂直居中共用它),而带 transform 的祖先会成为后代 fixed 元素的包含块
		 * ——position:fixed 于是不再相对视口定位,left/right 全部相对整条计算,
		 * sheet 被挤成一条窄缝(实测:351px 变成 24px)。
		 * 改成 absolute 之后语义反而更直白:格子已经 position:static,包含块就是
		 * 整条本身,而横条形态下整条本来就横铺满屏 —— 相对它定位 = 相对屏幕定位,
		 * 且不用再依赖 --polaris-fb-h 去反推自己该离底部多远。
		 */
		position: absolute;
		top: auto;
		left: 0;
		right: 0;
		bottom: 100%; /* 100% = 整条自身高度,即严丝合缝地坐在横条上沿 */
		width: auto;
		max-width: none;
		/*
		 * 必须压过触发器和「返回顶部」(它们是 z-index:1)。移动端的返回顶部是绝对定位
		 * 浮在横条上方的圆钮,正好落在 sheet 升起的那片区域里,不抬高就会被它盖住一角。
		 */
		z-index: 2;
		/* 贴着横条无缝相连,底部这两个圆角留着会在接缝处露出横条背景的尖角。 */
		border-bottom-left-radius: 0;
		border-bottom-right-radius: 0;
		/* 阴影翻到朝上:向下那一半会被紧贴的横条整个挡住,只剩一道脏边。 */
		box-shadow: 0 -6px 24px rgba( 0, 0, 0, 0.18 );
		transform: translateY( var( --polaris-fb-slide-y, 0.75rem ) );
	}

	/* 动作面板:窄屏横条下才现身,外观沿用卡片式面板那一套,里面是一个真正的链接。 */
	.polaris-float-bar.is-mobile-bar .polaris-float-bar__panel.is-panel-action {
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		padding: 0.5rem 0.75rem;
		border-top-left-radius: var( --polaris-fb-panel-radius, 12px );
		border-top-right-radius: var( --polaris-fb-panel-radius, 12px );
		background: var( --polaris-fb-panel-bg, var( --wp--preset--color--base, #fff ) );
		color: var( --polaris-fb-panel-fg, var( --wp--preset--color--ink-85, rgba( 0, 0, 0, 0.85 ) ) );
		text-align: center;
	}
	/* 链接撑满整张卡片:手机上点击目标越大越好,别让人去戳那一行小字。 */
	.polaris-float-bar__action {
		display: block;
		padding: 0.5rem 0;
		color: inherit;
		font-size: var( --polaris-fb-typography-font-size, var( --wp--preset--font-size--md, 1rem ) );
		font-weight: var( --polaris-fb-typography-font-weight, 600 );
		line-height: 1.3;
		text-decoration: none;
		word-break: break-all;
	}

	/* 返回顶部脱离横条,单独浮在横条上方靠边处 —— 塞进横条里会挤掉一格联系方式。
	   同上,用 absolute 相对整条定位,不用 fixed(理由见上面那段注释)。 */
	.is-mobile-bar .polaris-float-bar__top {
		position: absolute;
		bottom: calc( 100% + 1rem );
		width: 2.75rem;
		height: 2.75rem;
		box-shadow: 0 6px 20px rgba( 0, 0, 0, 0.22 );
	}
	.is-mobile-bar.is-side-right .polaris-float-bar__top {
		right: 1rem;
		left: auto;
	}
	.is-mobile-bar.is-side-left .polaris-float-bar__top {
		left: 1rem;
		right: auto;
	}
	.is-mobile-bar .polaris-float-bar__top .polaris-float-bar__icon {
		font-size: var( --polaris-fb-typography-font-size, 1.25rem );
	}

	/* 底部横条会盖住页脚最后一段内容。由 view.js 给 <body> 加类 + 写 --polaris-fb-h,
	   这里把留白补上(只有 bar 形态需要:rail 形态贴在侧边、hide 形态压根不显示)。 */
	body.has-polaris-float-bar {
		padding-bottom: var( --polaris-fb-h, 3.5rem );
	}

	/* ── 第三方在线客服浮窗避障 ──
	   tawk.to / Crisp / Intercom 这类默认都钉在右下角,和底部横条正面撞车。做法是
	   把它们抬到横条上方,**不是**去比 z-index 谁大 —— tawk 的 z-index 在 20 亿量级,
	   比赢了的结果是聊天窗口被我们盖住,更糟。

	   只匹配 body 的直接子元素:这些工具的容器都挂在 body 下,而容器内部往往还有一堆
	   自己绝对定位的元素,用后代选择器一并命中会把人家内部布局搅乱。

	   内置清单必然会漏(客服工具太多、类名还会变版本),所以父块 Inspector 里另有一个
	   「额外避障选择器」输入框,由 view.js 拼成同样的规则注入 <head>。 */
	body.has-polaris-float-bar.polaris-fb-avoid-chat > [id^="tawk"],
	body.has-polaris-float-bar.polaris-fb-avoid-chat > iframe[src*="tawk.to"],
	body.has-polaris-float-bar.polaris-fb-avoid-chat > iframe[title*="chat" i],
	body.has-polaris-float-bar.polaris-fb-avoid-chat > .crisp-client,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > .intercom-lightweight-app,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > #intercom-container,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > #chat-widget-container,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > .zsiq_floatmain,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > #zsiqwidget,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > #meiqia-container,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > .drift-frame-controller,
	body.has-polaris-float-bar.polaris-fb-avoid-chat > #hubspot-messages-iframe-container {
		bottom: calc( var( --polaris-fb-h, 3.5rem ) + var( --polaris-fb-avoid-gap, 12px ) ) !important;
	}
}

/* ═══════════════════════════════════════════
   全局收尾
═══════════════════════════════════════════ */
@media ( prefers-reduced-motion: reduce ) {
	.polaris-float-bar,
	.polaris-float-bar__panel,
	.polaris-float-bar__trigger,
	.polaris-float-bar__text,
	.polaris-float-bar__text-inner,
	.polaris-float-bar__top {
		transition: none !important;
	}
}

@media print {
	.polaris-float-bar {
		display: none !important;
	}
	body.has-polaris-float-bar {
		padding-bottom: 0 !important;
	}
}


/* ═══════════════════════════════════════════
   编辑器专属
   ───────────────────────────────────────────
   画布里就是**前台那一条本身**,不再另画一份克隆,也不再有右侧的面板编辑栏:
   每一格就是真正的 polaris/float-bar-item 区块,「自定义区块」面板里的内容直接在
   浮出来的那张卡片上编辑。

   为什么绕了一圈回到这里:最早那版也是直接用 InnerBlocks,但子块当时渲染的是
   「图标 + 名称」的宽行,把圆角胶囊撑成了一个大椭圆。问题从来不在 InnerBlocks,
   在于子块画的结构和前台不一样。现在子块的 useBlockProps 就落在
   .polaris-float-bar__item 上、内部结构与 render.php 逐一对应,编辑器额外挂上来的
   .wp-block / .block-editor-block-list__block 只是同一个元素上多几个类,不增加层级,
   把它们自带的外边距和宽度限制中和掉就够了。
═══════════════════════════════════════════ */

/*
 * 最外层容器背着原生「样式」面板挂上来的 has-*-background-color 和 inline style
 * (必须留在这里,块选中和拖拽都认这个元素),但它只是布局壳子,不该真的被涂上
 * 条的背景 —— 那些视觉属性由 edit.js 复制一份给里面那条真正的 .polaris-float-bar。
 * 这里的 !important 是冲着 has-* 预设类去的:它们和 .polaris-float-bar-editor 同为
 * (0,1,0),而全局样式表与块样式表谁在后面并不稳定,不加就是在赌加载顺序。
 */
.polaris-float-bar-editor {
	background: none !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	padding: 0 !important;
	color: inherit !important;
}

/* 页脚模板部件的只读预览里彻底不占位(编辑普通页面时画布底部那段)。真要改这条
   工具条就进页脚模板部件编辑,那时它照常显示。判据在 edit.js 里(祖先链有没有
   core/template-part),不是 WP 的 is-editing-disabled —— 那个类在正文块上也会出现。 */
.polaris-float-bar-editor.is-hidden-in-part {
	display: none;
}

/* 收起态:一条小标签。这个块通常摆在页脚模板部件里,展开着的话每编辑一个普通页面
   都会在画布底部带出一整块无关的悬浮条预览。点击它就是选中块,展开交给 WP 原生的
   选中态,不另外维护开关(与 polaris/modal 的收起态同一套做法和同一套观感)。 */
.polaris-float-bar-editor__collapsed {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	width: fit-content;
	padding: 0.35em 0.75em;
	border: 1px dashed var( --wp--preset--color--ink-25, rgba( 0, 0, 0, 0.2 ) );
	border-radius: 6px;
	background: var( --wp--preset--color--ink-2, rgba( 0, 0, 0, 0.02 ) );
	font-size: 0.8125rem;
	color: var( --wp--preset--color--ink-65, rgba( 0, 0, 0, 0.65 ) );
	cursor: pointer;
}
.polaris-float-bar-editor__collapsed-icon {
	font-size: 1em;
	line-height: 1;
}

.polaris-float-bar-editor__col-title {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5rem;
	margin-bottom: 0.5rem;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var( --wp--preset--color--ink-65, rgba( 0, 0, 0, 0.65 ) );
}
.polaris-float-bar-editor__col-hint {
	font-size: 0.6875rem;
	font-weight: 400;
	color: var( --wp--preset--color--ink-45, rgba( 0, 0, 0, 0.45 ) );
}

/* ── 舞台 ──
   模拟一小块「页面」,条按 side 贴在对应一侧。overflow 保持 visible:展开面板是绝对
   定位的,浮出舞台之外正是它在前台的样子;编辑自定义面板时也需要这份溢出空间。 */
.polaris-float-bar-editor__stage {
	position: relative;
	display: flex;
	min-height: 18rem;
	border: 1px solid var( --wp--preset--color--ink-15, rgba( 0, 0, 0, 0.12 ) );
	border-radius: 10px;
	background:
		repeating-linear-gradient( 45deg,
			rgba( 0, 0, 0, 0.02 ) 0 6px,
			transparent 6px 12px );
	/*
	 * 舞台就是"那块屏幕"的替身,所以「距屏幕左/右边距」这类设置直接兑现成舞台自己的
	 * 内边距 —— 条离舞台边框多远,前台就离视口边缘多远,改了立刻能看见。
	 * (预览里的条是 position:relative 摆在舞台中的,前台那套 right/bottom/top 偏移
	 * 在它身上不起作用,所以必须由舞台这一层来表达。)
	 * 这几个变量由 edit.js 挂在舞台上,不是挂在条上。
	 */
	padding: var( --polaris-fb-stage-pad-top, 1.5rem )
		var( --polaris-fb-stage-pad-right, 1.5rem )
		var( --polaris-fb-stage-pad-bottom, 1.5rem )
		var( --polaris-fb-stage-pad-left, 1.5rem );
}
.polaris-float-bar-editor__stage.is-side-right {
	justify-content: flex-end;
}
.polaris-float-bar-editor__stage.is-side-left {
	justify-content: flex-start;
}
/* 垂直三档同样要在舞台上体现,否则「底部对齐」在预览里看不出任何区别。 */
.polaris-float-bar-editor__stage.is-align-middle {
	align-items: center;
}
.polaris-float-bar-editor__stage.is-align-bottom {
	align-items: flex-end;
}
.polaris-float-bar-editor__stage.is-align-custom {
	align-items: flex-start;
}

.polaris-float-bar-editor__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem;
	margin-top: 0.625rem;
}

/* 把前台那套「钉在视口上」的定位中和掉,其余(配色/圆角/圆钮/胶囊几何)原样沿用。 */
.polaris-float-bar.is-preview {
	position: relative;
	inset: auto;
	z-index: auto;
	transform: none;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: none;
}

/*
 * 中和编辑器给每个区块挂的默认版式。.wp-block 会给块加上外边距和内容区宽度上限,
 * 落在格子上就会把条撑开、把圆角撑歪 —— 这正是最早那版变成大椭圆的原因之一。
 */
.polaris-float-bar.is-preview .polaris-float-bar__item {
	margin: 0 !important;
	max-width: none !important;
}
.polaris-float-bar.is-preview .polaris-float-bar__trigger {
	cursor: pointer;
}

/* 选中这一格、或光标落在它的自定义面板内部时,面板常驻展开 —— 否则根本没法编辑
   一个 visibility:hidden 的东西。两个类都要认:.has-child-selected 漏了的话,
   一点进面板里的段落,面板就当场收起来。 */
.polaris-float-bar.is-preview .polaris-float-bar__item.is-selected > .polaris-float-bar__panel,
.polaris-float-bar.is-preview .polaris-float-bar__item.has-child-selected > .polaris-float-bar__panel {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	z-index: 2; /* 压过旁边格子悬停时弹出的面板 */
	--polaris-fb-slide: 0px;
	--polaris-fb-slide-y: 0px;
}
.polaris-float-bar.is-preview .polaris-float-bar__item.is-selected > .polaris-float-bar__trigger,
.polaris-float-bar.is-preview .polaris-float-bar__item.has-child-selected > .polaris-float-bar__trigger {
	background: var( --polaris-fb-hover-bg, var( --wp--preset--color--primary, #2563eb ) );
	color: var( --polaris-fb-hover-fg, var( --wp--preset--color--on-primary, #fff ) );
	box-shadow: 0 0 0 2px var( --wp--admin-theme-color, #3858e9 );
}
/* 文字档位同理:选中即展开,好让人在编辑器里直接看到展开后的长度。 */
.polaris-float-bar.is-preview .polaris-float-bar__item.is-selected,
.polaris-float-bar.is-preview .polaris-float-bar__item.has-child-selected {
	/* 编辑器里没有 view.js,回退到 max-content —— 宽度依然准确,只是不做过渡。
	   画布要的是"展开后长什么样",不是那 260ms 的动画。 */
	--polaris-fb-text-open: max-content;
	--polaris-fb-text-opacity: 1;
}

/*
 * 正在编辑某一格时,关掉其它格子的「悬停即展开」。
 * 面板都挂在各自格子的垂直中线上,而一张二维码卡有近 200px 高、格子才 52px ——
 * 鼠标从工具栏移过去的路上扫过任何一格,它的面板就会盖住你正在编辑的那张卡片。
 * 没在编辑时(什么都没选中)悬停预览照常,那正是这个预览最有用的地方。
 *
 * 用 :has() 而不是由父块 edit() 打一个状态类:实测父块的 edit() **不会**因为选中态
 * 变化而重新渲染(useSelect 里 hasSelectedInnerBlock 的值确实变了,但组件没有重跑),
 * 所以任何"由父块算出来再挂上去"的状态类都会是死的。而 .is-selected /
 * .has-child-selected 是编辑器自己挂在每个区块上的,永远是新鲜的 —— 直接拿它们
 * 反查父级,不依赖我们自己的渲染时机。
 *
 * 万一浏览器不支持 :has(),整条规则被忽略 = 退回"一直可悬停展开",是旧行为,
 * 不会把编辑器搞坏。
 */
.polaris-float-bar.is-preview:has( .polaris-float-bar__item.is-selected, .polaris-float-bar__item.has-child-selected )
	.polaris-float-bar__item:not( .is-selected ):not( .has-child-selected ):hover > .polaris-float-bar__panel {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}
/* 文字档位没有面板层,同一条抑制要落到那两个变量上。 */
.polaris-float-bar.is-preview:has( .polaris-float-bar__item.is-selected, .polaris-float-bar__item.has-child-selected )
	.polaris-float-bar__item:not( .is-selected ):not( .has-child-selected ):hover {
	--polaris-fb-text-open: 0px;
	--polaris-fb-text-opacity: 0;
}

/* 自定义面板在编辑器里即使还是空的也要占住位置,否则没有地方可以插入第一个区块。 */
.polaris-float-bar.is-preview .polaris-float-bar__panel.is-panel-custom {
	min-width: 12rem;
	min-height: 3rem;
	text-align: initial;
}

/* Inspector 里的小字说明(与 polaris/modal 共用同一个类名约定) */
.polaris-inspector-hint {
	margin: 0.5rem 0 0;
	font-size: 0.75rem;
	color: var( --wp--preset--color--ink-65, rgba( 0, 0, 0, 0.65 ) );
}

/* ═══════════════════════════════════════════
   Inspector:四边内边距控件
   ───────────────────────────────────────────
   库内 tabs / search / nav-item / carousel 各块共用这一套类名和外观(标题行 =
   标签 + 重置 + 链接开关;链接时一个输入框,解除后 4 个输入分成两行两列)。
   这里再写一份而不是指望别的块的 style.css:组件开关允许站点单独禁用某个块,
   被禁用的块样式表不会入队,借来的样式会突然消失。
═══════════════════════════════════════════ */
.polaris-pad-control {
	margin-bottom: 16px;
}
.polaris-pad-control__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 8px;
}
.polaris-pad-control__actions {
	display: flex;
	align-items: center;
	gap: 2px;
}
/* 链接/断链是描边 SVG:强制 fill:none 避免被填成实心(重置是字体图标,不受影响) */
.polaris-pad-control__actions .components-button svg {
	fill: none !important;
	stroke: currentColor;
}
.polaris-pad-control__label {
	font-size: 11px;
	font-weight: 500;
	text-transform: uppercase;
	color: #1e1e1e;
}
/* 解除链接后 4 个输入,每行 2 个 */
.polaris-pad-control__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 8px;
}

/* Inspector:两个相关字段并排一行(「每格大小」+「格与格间距」)。
   align-items:start 是必要的 —— 两个 UnitControl 的高度可能因帮助文字而不等,
   拉伸对齐会把矮的那个撑变形。 */
.polaris-fb-field-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: start;
	gap: 8px;
	margin-bottom: 16px;
}
/* 控件自带 16px 下边距,和这一行自己的 16px 叠起来就是 32px —— 下一个字段会比别处
   多空出一倍。行内清零,由行统一负责间距。 */
.polaris-fb-field-row > .components-base-control {
	margin-bottom: 0;
}
/* 阈值这类只有一种单位的输入:单位做成输入框后缀,不再挂在标签里写「(px)」。 */
.polaris-fb-unit-suffix {
	padding-right: 8px;
	font-size: 13px;
	color: #757575;
}
