/* 36Isthmus 开机动画（2026-10-02）
 *
 * 画面是渲好的片子：/kboot/boot.mp4（scripts/boot-film.js 逐帧渲的
 * three.js + 泛光镜头：两块板块之间一条正在成形的连接，接上之后跑起双向报文）。
 * 这一层 CSS 只负责承载它：铺满、压暗、起字标、收尾。
 *
 * 三条硬约束（和 AXIS 那一版同源）：
 *
 * 1. **动画只走 CSS keyframes + animation-delay，不跑 rAF。** 页面在底下加载，
 *    主线程被占满时 rAF 会被饿到肉眼可见。视频解码不占主线程，这一层也只让
 *    动画时钟驱动。JS 只做三件事：建节点、催一次播放、调度退出。
 *
 * 2. 时序全部由 --kb-* 驱动，改时间只改一处。
 *
 * 3. 片子放不出来（离线、解码器不支持、自动播放被拦）时画面必须仍然成立：
 *    poster 是片子的**最后一帧**（落定之后的画面），不是黑屏。
 *
 * 命名空间统一用 kb-（kiosk boot），避开站上已有的 .boot / .stage。
 */

:root {
	--kb-bg: #0b0918;                 /* 和片子的底色同一个值 */
	--kb-ink: #fafafd;                /* 站点 --color-text-light */
	--kb-dim: #a19add;                /* 站点 --color-plum-dark-2 */
	--kb-plum: #c1bbf6;               /* 站点 --color-plum */

	/* 时序对齐片子的四拍（片长 4.4s）：点火 0.0-0.42s、引线 0.34-1.70s、
	   落定 1.70-2.45s、通流 2.35-4.4s。字标在"落定"之后起，退场排在片子放完之后。
	   ⚠️ 片子换了长度，这三条**必须跟着改** —— 改漏了字标会在片子还没落定时就浮出来。 */
	--kb-t-word: 2900ms;
	--kb-t-tagline: 3140ms;
	--kb-t-exit: 4560ms;
}

/* 盖子：JS 还没 append 覆盖层时，靠这个伪元素挡住页面，避免闪一下真实内容。
 * 盖子和覆盖层分开管：退出时要先摘盖子类再收虹膜，否则收拢时露出的是黑盖子。 */
html.kb-run::before {
	content: '';
	position: fixed;
	inset: 0;
	z-index: 2147483600;
	background: var(--kb-bg);
}

html.kb-run,
html.kb-run body {
	overflow: hidden !important;
}

/* 覆盖层本体。JS 运行时 append，退出时 remove。
 *
 * 底图是片的最后一帧：调 play() 之后 <video> 会撤掉自己的 poster，
 * 而首帧要等片子下下来才解码出来，这段时间元素是透明的 ——
 * 网络慢一点就是先黑一秒再出画面。把最后一帧铺在底下，片子一出来就盖住它。 */
.kboot {
	position: fixed;
	inset: 0;
	z-index: 2147483601;
	background: var(--kb-bg) url('/kboot/boot-poster.jpg') center / cover no-repeat;
	color: var(--kb-ink);
	overflow: hidden;
	/* 虹膜收拢的载体 */
	clip-path: inset(0);
	-webkit-tap-highlight-color: transparent;
}

/* 片子铺满整屏。cover 而不是 contain：这一层是全屏片头，不出现信箱黑边。 */
.kb-film {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* 压暗层：中下方渐深，给字标一块底；四周轻微暗角，把视线收回画面中心。 */
.kb-scrim {
	position: absolute;
	inset: 0;
	background:
		radial-gradient(54% 48% at 50% 54%, rgba(11, 9, 24, 0) 0%, rgba(11, 9, 24, 0.42) 100%),
		linear-gradient(180deg, rgba(11, 9, 24, 0.55) 0%, rgba(11, 9, 24, 0) 24%, rgba(11, 9, 24, 0.12) 56%, rgba(11, 9, 24, 0.86) 100%);
}

/* ── 字标 ──────────────────────────────────────────────────────────────────
 * 用**站点自己的字标图**（/assets/wordmark.png，tools/make-wordmark.js 用原站字体渲的），
 * 拿 mask 上色 —— 比重新排字更稳：字体没加载完也不会先闪一下系统字体，
 * 而且字形和站头那个一模一样。 */
.kb-word {
	position: absolute;
	left: 0;
	right: 0;
	top: 76%;
	margin: 0 auto;
	width: clamp(210px, 24vw, 390px);
	height: clamp(24px, 2.8vw, 46px);
	background: var(--kb-ink);
	-webkit-mask: url('/assets/wordmark.png') center / contain no-repeat;
	mask: url('/assets/wordmark.png') center / contain no-repeat;
	opacity: 0;
	animation: kb-word-in 640ms cubic-bezier(0.2, 0.7, 0.2, 1) var(--kb-t-word) forwards;
}
@keyframes kb-word-in {
	from { opacity: 0; transform: translateY(10px) scale(0.985); }
	to { opacity: 1; transform: translateY(0) scale(1); }
}

.kb-tagline {
	position: absolute;
	left: 0;
	right: 0;
	top: calc(76% + clamp(30px, 3.6vw, 54px));
	text-align: center;
	font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
	font-size: clamp(9px, 0.8vw, 12px);
	letter-spacing: 0.28em;
	text-transform: uppercase;
	color: var(--kb-dim);
	opacity: 0;
	animation: kb-tag-in 520ms ease-out var(--kb-t-tagline) forwards;
}
@keyframes kb-tag-in {
	to { opacity: 0.78; }
}
/* 窄屏：cover 会把画面裁到只剩中间一条，这条副标题会压在连接上，而且字一多也不好看 */
@media (max-width: 700px) {
	.kb-tagline { display: none; }
}

/* 跳过提示：右下角，暗到不打扰，但找得到 */
.kb-skip {
	position: absolute;
	right: clamp(16px, 2.4vw, 34px);
	bottom: clamp(16px, 2.4vw, 30px);
	font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
	font-size: 10px;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--kb-dim);
	opacity: 0;
	animation: kb-skip 500ms ease-out 1100ms forwards;
}
@keyframes kb-skip {
	to { opacity: 0.42; }
}

/* ── 退出：虹膜收拢到一条缝，再由一条发光缝线收掉 ──────────────────────────
 *
 * **退出由 CSS 的 animation-delay 触发，不由 JS 的 setTimeout 触发。**
 * 踩过的坑（AXIS 那一版）：JS 里 setTimeout 加 .kb-out，实测 t=2500ms 时退场
 * 根本还没开始 —— 主线程被页面加载占满，setTimeout 迟到两百多毫秒。
 * 交给动画时钟就不会被饿到。JS 只负责到点摘盖子类、移除节点。 */
.kboot {
	animation: kb-iris 520ms cubic-bezier(0.7, 0, 0.3, 1) var(--kb-t-exit) forwards;
}
@keyframes kb-iris {
	to {
		clip-path: inset(49.9% 0 49.9% 0);
	}
}
/* 跳过：把延迟压掉立即收，其余不变 */
.kboot.kb-skip {
	animation-delay: 0ms;
}

/* 缝线：虹膜收到最窄时那条亮线 */
.kboot::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	height: 2px;
	transform: translateY(-50%);
	background: linear-gradient(90deg, transparent, var(--kb-plum), #fff, var(--kb-plum), transparent);
	box-shadow: 0 0 24px 6px rgba(193, 187, 246, 0.5);
	opacity: 0;
	animation: kb-seam 520ms ease-out var(--kb-t-exit) forwards;
}
.kboot.kb-skip::after {
	animation-delay: 0ms;
}
@keyframes kb-seam {
	0% { opacity: 0; }
	62% { opacity: 0; }
	88% { opacity: 1; }
	100% { opacity: 0.9; }
}

/* 减动效：整层不出现（闸门脚本会直接不加载，这里是第二道保险） */
@media (prefers-reduced-motion: reduce) {
	.kboot { display: none !important; }
	.kb-film { display: none !important; }
}
