/**
 * 科技感特效层。
 *
 * 三条铁律：
 *
 *   1. 特效永远是增强层，不承载任何内容。
 *      所有文字与图片在 JS 执行前已完整存在于 HTML 中。
 *      关掉 JS，页面内容 100% 完整可见可用。
 *
 *   2. 不影响 LCP 元素。
 *      首屏主图独立渲染，特效在 LCP 完成后才初始化。
 *
 *   3. 总预算 25KB（gzip），不引入任何第三方动画库。
 *
 * 本文件中的效果绝大部分是零 JS 成本的纯 CSS 实现 ——
 * 滚动驱动动画跑在合成器线程，不阻塞主线程。
 */

/* ══════════════════════════════════════════════════════
 * 滚动视差
 *
 * 使用原生 animation-timeline: scroll()。
 * 相比 JS 监听 scroll 事件手动计算位移，原生方案由浏览器
 * 在合成器线程驱动 —— 主线程繁忙时依然流畅，且完全不占
 * JS 预算。
 * ══════════════════════════════════════════════════════ */

@supports (animation-timeline: scroll()) {
	/*
	 * 首屏背景以低于滚动速度移动，产生纵深感。
	 *
	 * 位移量刻意保守（12%）——过大的视差在长页面中会让
	 * 图片过早离开视口，露出底部空白。
	 */
	.mf-hero__media {
		animation: mf-parallax linear both;
		animation-timeline: view();
		animation-range: entry 0% exit 100%;
	}

	@keyframes mf-parallax {
		from {
			transform: translateY(-6%) scale(1.08);
		}
		to {
			transform: translateY(6%) scale(1.08);
		}
	}

	/*
	 * 首屏内容随滚动淡出。
	 * 让视线自然过渡到下方内容，而非生硬地被推走。
	 */
	.mf-hero__content {
		animation: mf-hero-fade linear both;
		animation-timeline: view();
		animation-range: exit 0% exit 70%;
	}

	@keyframes mf-hero-fade {
		from {
			opacity: 1;
			transform: translateY(0);
		}
		to {
			opacity: 0;
			transform: translateY(-2rem);
		}
	}

	/*
	 * 顶部进度条。
	 * 阅读位置的可视化，长页面中给出明确的进度感知。
	 */
	.mf-progress {
		position: fixed;
		inset-inline: 0;
		top: 0;
		height: 2px;
		z-index: calc(var(--mf-z-header) + 1);
		background: linear-gradient(
			to right,
			var(--mf-accent-dim),
			var(--mf-accent)
		);
		transform-origin: 0 50%;
		animation: mf-progress linear both;
		animation-timeline: scroll(root block);
	}

	@keyframes mf-progress {
		from { transform: scaleX(0); }
		to { transform: scaleX(1); }
	}
}

/*
 * 不支持滚动驱动动画的浏览器隐藏进度条。
 * 用 JS 模拟会引入 scroll 监听与布局读取，代价不划算。
 */
@supports not (animation-timeline: scroll()) {
	.mf-progress {
		display: none;
	}
}

/* ══════════════════════════════════════════════════════
 * 网格微光
 *
 * 纯 CSS 的科技感底纹：细网格上缓慢流过的光带。
 * 使用 @property 注册自定义属性，使角度可被平滑插值 ——
 * 未注册的自定义属性无法参与过渡，只会跳变。
 * ══════════════════════════════════════════════════════ */

@property --mf-sweep {
	syntax: "<angle>";
	initial-value: 0deg;
	inherits: false;
}

.mf-techgrid {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

/* 网格线本身。 */
.mf-techgrid::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -2;
	background-image:
		linear-gradient(var(--mf-line) 1px, transparent 1px),
		linear-gradient(90deg, var(--mf-line) 1px, transparent 1px);
	background-size: 72px 72px;
	/*
	 * 径向遮罩让网格向边缘淡出，避免生硬的截断边界。
	 */
	-webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 40%, #000 20%, transparent 78%);
	mask-image: radial-gradient(ellipse 80% 60% at 50% 40%, #000 20%, transparent 78%);
	opacity: 0.5;
}

/* 扫过的光带。 */
.mf-techgrid::after {
	content: "";
	position: absolute;
	inset: -50%;
	z-index: -1;
	/*
	 * 多段渐变让光带边缘柔和过渡。
	 *
	 * 单段 conic-gradient 的扇形边界过于锐利，在深色背景上
	 * 会呈现为一个突兀的三角形，看起来像渲染错误而非光效。
	 * 逐级递减的透明度模拟真实光线的衰减。
	 */
	background: conic-gradient(
		from var(--mf-sweep),
		transparent 0deg,
		rgba(200, 169, 106, 0.02) 14deg,
		rgba(200, 169, 106, 0.05) 30deg,
		rgba(200, 169, 106, 0.03) 48deg,
		rgba(200, 169, 106, 0.01) 66deg,
		transparent 84deg,
		transparent 360deg
	);
	/*
	 * 径向遮罩使光带向外淡出，与网格的遮罩范围一致 ——
	 * 两者边界不重合时会露出光带的直线切边。
	 */
	-webkit-mask-image: radial-gradient(ellipse 60% 50% at 50% 45%, #000 10%, transparent 72%);
	mask-image: radial-gradient(ellipse 60% 50% at 50% 45%, #000 10%, transparent 72%);
	filter: blur(24px);
	animation: mf-sweep 18s linear infinite;
	pointer-events: none;
}

@keyframes mf-sweep {
	to {
		--mf-sweep: 360deg;
	}
}

/* ══════════════════════════════════════════════════════
 * 磁吸光标
 *
 * 元素向光标轻微偏移，产生被吸引的错觉。
 * 位移由 JS 写入自定义属性，此处只负责应用变换 ——
 * 分离关注点使 JS 部分保持极简。
 * ══════════════════════════════════════════════════════ */

[data-mf-magnetic] {
	transform: translate3d(
		var(--mf-magnet-x, 0),
		var(--mf-magnet-y, 0),
		0
	);
	transition: transform var(--mf-duration) var(--mf-ease-spring);
	will-change: transform;
}

/* 触屏设备无光标，禁用磁吸避免无谓的计算与合成层。 */
@media (hover: none), (pointer: coarse) {
	[data-mf-magnetic] {
		transform: none;
		will-change: auto;
	}
}

/* ══════════════════════════════════════════════════════
 * 数字滚动
 *
 * HTML 中直接写最终值，JS 只是从 0 播放到该值。
 * 关掉 JS 时数字照常显示 —— 这是「特效不承载内容」
 * 的具体体现。
 * ══════════════════════════════════════════════════════ */

.mf-stat {
	display: flex;
	flex-direction: column;
	gap: var(--mf-space-2);
}

/*
 * 统计区布局。
 *
 * 自动填充而非固定列数 —— 条目数量随站点内容变化，
 * 硬编码列数会在只有两三项时留下尴尬的空隙。
 */
.mf-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: var(--mf-space-12) var(--mf-space-8);
	padding-block: var(--mf-space-8);
}

.mf-stat__value {
	font-family: var(--mf-font-display);
	font-size: var(--mf-text-3xl);
	font-weight: var(--mf-weight-light);
	line-height: 1;
	color: var(--mf-accent);
	/* 等宽数字防止播放过程中的宽度抖动。 */
	font-variant-numeric: tabular-nums;
}

.mf-stat__label {
	font-size: var(--mf-text-xs);
	letter-spacing: var(--mf-tracking-widest);
	text-transform: uppercase;
	color: var(--mf-text-faint);
}

/* ══════════════════════════════════════════════════════
 * 粒子背景
 *
 * 唯一有实际性能代价的特效，仅用于首页首屏。
 * Canvas 由 JS 创建并插入，因此默认不存在于 DOM 中 ——
 * 降级时不留任何痕迹。
 * ══════════════════════════════════════════════════════ */

.mf-particles {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	opacity: 0;
	transition: opacity 1.6s var(--mf-ease);
}

.mf-particles[data-ready="true"] {
	opacity: 1;
}

/* ══════════════════════════════════════════════════════
 * 页面转场
 *
 * View Transitions API 由浏览器原生驱动，零 JS 成本。
 * 不支持的浏览器直接跳转，无任何降级代码。
 * ══════════════════════════════════════════════════════ */

@view-transition {
	navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
	animation-duration: 320ms;
	animation-timing-function: var(--mf-ease);
}

/* 作品图在页面间保持连续，形成放大进入的效果。 */
.mf-card__media img {
	view-transition-name: var(--mf-vt-name, none);
}

/* ══════════════════════════════════════════════════════
 * 减弱动效
 *
 * 全部特效在此统一关闭。
 * 前庭功能障碍者会因过度动效产生真实的生理不适 ——
 * 这不是可选的润色，是必须提供的降级路径。
 * ══════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
	.mf-hero__media,
	.mf-hero__content,
	.mf-progress {
		animation: none !important;
		transform: none !important;
		opacity: 1 !important;
	}

	.mf-techgrid::after {
		animation: none;
		opacity: 0.3;
	}

	[data-mf-magnetic] {
		transform: none !important;
		transition: none;
	}

	.mf-particles {
		display: none;
	}

	@view-transition {
		navigation: none;
	}
}
