/* ==========================================================================
   main.css — 设计令牌 / 全局重置 / 通用组件
   风格约束：扁平。零圆角、零阴影。层级只靠「1px 描边 + 色块」表达。
   浅色/暗色双主题，颜色一律走下面的 CSS 变量，不要在组件里写死色值。
   本文件在 prism.css 之前加载；圆角/阴影靠 !important 兜底覆盖第三方样式。
   ========================================================================== */

/* ---------- 设计令牌 ---------- */
:root {
	/* 告诉浏览器本页是浅色：表单控件、滚动条、系统 UI 会跟着走。
	   暗色下由下面的 [data-theme="dark"] / 媒体查询改写成 dark。 */
	color-scheme: light;

	/* 主色 */
	--c-primary: #e06c75;
	--c-primary-dark: #c66169;
	--c-primary-soft: #fdf2f3;

	/* 中性色阶 */
	--c-title: #111111;
	--c-text: #3d3d3d;
	--c-muted: #999999;
	--c-faint: #bbbbbb;
	--c-bg: #ffffff;
	--c-surface: #fafafa;
	--c-border: #e5e5e5;
	--c-border-strong: #d2d2d2;

	/* 这三处原先散着字面色值（#fbfbfb / rgba 白 / hero 渐变），
	   提成变量是为了让暗色能跟着一起换，不必在暗色里逐条覆盖字面色。 */
	--c-code-bg: #fbfbfb;
	--c-nav-glass: rgba(255, 255, 255, .72);
	--c-hero-veil: linear-gradient(to bottom,
		rgba(255, 255, 255, 0) 0%,
		rgba(255, 255, 255, .35) 40%,
		rgba(255, 255, 255, .8) 100%);

	/* 代码语法着色。浅色这一组取的就是 prism.css 默认主题的原值，
	   收进变量只是为了让暗色能整组替换；色调和明暗无关的那几个
	   （注释、标点）在暗色里会略微提亮，保证压在深底上还看得清。 */
	--sx-comment: #708090;
	--sx-punct: #999999;
	--sx-number: #990055;
	--sx-string: #669900;
	--sx-operator: #9a6e3a;
	--sx-keyword: #0077aa;
	--sx-func: #dd4a68;
	--sx-special: #ee9900;

	/* 尺寸 */
	--nav-h: 56px;
	--wrap: 1080px;
	--gap: 16px;

	/* 字体 */
	--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
		"Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
	--font-mono: Consolas, Monaco, "Courier New", "Courier", monospace;
}

/* ---------- 暗色令牌 ----------
   同一组取值写两遍，必须同步修改，原因是选择器没法「或」：
     · :root[data-theme="dark"]  —— 用户手动切到暗色（存 localStorage）
     · @media prefers-color-scheme: dark —— 跟随系统，且 JS 未启用时也生效
   之所以不用更省事的 light-dark()：它要 Chrome 123+ / Safari 17.5+，
   不支持时整组颜色会失效、页面直接变透明底黑字，宁可多写一份。

   配色原则：主色保持不变（品牌色不因主题漂移），中性色整体反相，
   层级仍只靠 1px 描边。--c-primary-dark 在浅色下是「更深的强调色」，
   到了暗色要反过来变成「更亮的强调色」，否则压在深底上会糊。 */
:root[data-theme="dark"] {
	color-scheme: dark;
	--c-primary-dark: #f0818a;
	--c-primary-soft: #2b1f22;
	--c-title: #e8eaed;
	--c-text: #c2c6cc;
	--c-muted: #8b9099;
	--c-faint: #6b7078;
	--c-bg: #16181d;
	--c-surface: #1e2127;
	--c-border: #2c3037;
	--c-border-strong: #3a3f47;
	--c-code-bg: #1b1e24;
	--c-nav-glass: rgba(22, 24, 29, .72);
	--c-hero-veil: linear-gradient(to bottom,
		rgba(22, 24, 29, 0) 0%,
		rgba(22, 24, 29, .45) 40%,
		rgba(22, 24, 29, .85) 100%);
	--sx-comment: #7f848e;
	--sx-punct: #9aa0a6;
	--sx-number: #d19a66;
	--sx-string: #98c379;
	--sx-operator: #56b6c2;
	--sx-keyword: #c678dd;
	--sx-func: #61afef;
	--sx-special: #e06c75;
}

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		color-scheme: dark;
		--c-primary-dark: #f0818a;
		--c-primary-soft: #2b1f22;
		--c-title: #e8eaed;
		--c-text: #c2c6cc;
		--c-muted: #8b9099;
		--c-faint: #6b7078;
		--c-bg: #16181d;
		--c-surface: #1e2127;
		--c-border: #2c3037;
		--c-border-strong: #3a3f47;
		--c-code-bg: #1b1e24;
		--c-nav-glass: rgba(22, 24, 29, .72);
		--c-hero-veil: linear-gradient(to bottom,
			rgba(22, 24, 29, 0) 0%,
			rgba(22, 24, 29, .45) 40%,
			rgba(22, 24, 29, .85) 100%);
		--sx-comment: #7f848e;
		--sx-punct: #9aa0a6;
		--sx-number: #d19a66;
		--sx-string: #98c379;
		--sx-operator: #56b6c2;
		--sx-keyword: #c678dd;
		--sx-func: #61afef;
		--sx-special: #e06c75;
	}
}

/* ---------- 扁平化强制规则（唯一样板开关） ----------
   放在 reset 之后，靠 !important 覆盖 prism、font-awesome 等第三方自带圆角/阴影。 */
*,
*::before,
*::after {
	border-radius: var(--radius, 0) !important;
	box-shadow: none !important;
}

/* ---------- 重置 ---------- */
* {
	margin: 0;
	padding: 0;
	border: 0;
	box-sizing: border-box;
	-webkit-tap-highlight-color: transparent;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
	min-height: 100%;
	font-family: var(--font-sans);
	font-size: 15px;
	line-height: 1.7;
	color: var(--c-text);
	background: var(--c-bg);
	overflow-wrap: break-word;
	word-break: break-word;
}

h1, h2, h3, h4, h5, h6 {
	color: var(--c-title);
	font-weight: 600;
	line-height: 1.4;
}

a {
	color: var(--c-primary);
	text-decoration: none;
	transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}

a:hover {
	color: var(--c-primary-dark);
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

/* 正文的 ul/ol 保留浏览器默认圆点，并给 1.4em 缩进。
   主题自带的列表不要圆点，见下面那条。 */
ul, ol {
	padding-left: 1.4em;
}

/* 上面的 * 重置清了 margin/padding/border，但 list-style 不在其列，
   所以主题自带的这些 ul 都会带上浏览器默认的 disc 圆点，而它们是
   纯边框分隔的扁平样式，不该有圆点。

   必须逐个类名列出，不能写成 ul { list-style: none }：
   文章正文（.post-content / .rich）里的 ul/ol 仍需要圆点和缩进。
   新增主题列表时记得把类名加进来，verify_lists.py 会检查这一条。
   .cloud / .home-cloud 是标签云的外壳和条目容器（blocks.css），
   .home-archive / .home-archive-months 是首页归档速览（index.css）——
   三个类名都出现在同一个 ul 上，所以要全列，漏一个就多出一排圆点。 */
.post-list,
.archive-list,
.cat-list,
.friend-list,
.fact-list,
.contact-list,
.icon-links,
.side-tags,
.side-stats,
.stat-list,
.cloud,
.home-cloud,
.home-archive,
.home-archive-months {
	list-style: none;
	padding-left: 0;
}

table {
	border-collapse: collapse;
	width: 100%;
}

code, pre, kbd, samp {
	font-family: var(--font-mono);
	font-size: .92em;
}

hr {
	height: 1px;
	background: var(--c-border);
	border: 0;
	margin: 2rem 0;
}

::selection {
	background: var(--c-primary);
	color: #fff;
}

/* ---------- 滚动条：细、扁平、不隐藏 ---------- */
::-webkit-scrollbar {
	width: 8px;
	height: 8px;
}

::-webkit-scrollbar-track {
	background: var(--c-surface);
}

::-webkit-scrollbar-thumb {
	background: var(--c-border-strong);
}

::-webkit-scrollbar-thumb:hover {
	background: var(--c-faint);
}

/* ---------- 布局容器 ---------- */
.wrap {
	width: 100%;
	max-width: var(--wrap);
	margin: 0 auto;
	padding: 0 20px;
}

/* 给固定导航留出空间 */
#content {
	padding-top: var(--nav-h);
	min-height: calc(100vh - 160px);
}

/* ---------- 通用组件 ---------- */

/* 页面标题：左竖线 + 中英副标题 */
.page-head {
	margin: 40px 0 24px;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--c-border);
}

.page-head h1 {
	font-size: 26px;
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 10px;
}

.page-head h1::before {
	content: "";
	display: inline-block;
	width: 3px;
	height: 1em;
	background: var(--c-primary);
	transform: translateY(.12em);
}

.page-head h1 .en {
	font-size: 13px;
	font-weight: 400;
	color: var(--c-muted);
	letter-spacing: .06em;
	text-transform: uppercase;
}

.page-head .desc {
	margin-top: 10px;
	font-size: 14px;
	color: var(--c-muted);
}

/* ---------- 卡片基元 ----------
   全站只有一种卡片：1px 描边 + 白底，标题栏 = 浅色底 + 3px 主色强调条。
   侧栏名片、目录、关于页的每一块都走这套，避免每页各写一份近似的样式，
   也就不会出现「有的框有标题栏、有的没有」这种不统一。 */
.card {
	border: 1px solid var(--c-border);
	background: var(--c-bg);
}

.card-body {
	padding: 16px 14px;
}

/* 卡片 / 区块标题。flex:0 0 auto 是给 .toc-box 用的：
   那里标题是 flex 子项，不能被下面的目录内容挤扁。 */
.box-title {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 10px 14px;
	font-size: 13px;
	font-weight: 600;
	color: var(--c-title);
	background: var(--c-surface);
	border-bottom: 1px solid var(--c-border);
}

/* 强调条：与 .page-head h1、.section-title、.rich h2 的左竖线同一套语言。 */
.box-title::before {
	content: "";
	flex-shrink: 0;
	width: 3px;
	height: 13px;
	background: var(--c-primary);
}

.box-title i {
	font-size: 12px;
	color: var(--c-muted);
}

/* 标题栏右端的英文小字，用来平衡左重右空的标题行。 */
.box-title .en {
	margin-left: auto;
	font-size: 11px;
	font-weight: 400;
	color: var(--c-muted);
	letter-spacing: .08em;
	text-transform: uppercase;
}

/* 方形图标按钮组：侧栏名片与关于页共用，保证社交入口长得一样。 */
.icon-links {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.icon-links a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	font-size: 14px;
	color: var(--c-muted);
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	transition: all .15s ease;
}

.icon-links a:hover {
	color: #fff;
	background: var(--c-primary);
	border-color: var(--c-primary);
}

/* 统计条 */
.stat-bar {
	display: flex;
	flex-wrap: wrap;
	gap: 0;
	border: 1px solid var(--c-border);
	background: var(--c-surface);
	margin-bottom: 24px;
}

.stat-bar > div {
	flex: 1 1 0;
	min-width: 96px;
	padding: 12px 16px;
	border-right: 1px solid var(--c-border);
	text-align: center;
}

.stat-bar > div:last-child {
	border-right: 0;
}

.stat-bar b {
	display: block;
	font-size: 20px;
	color: var(--c-primary);
	line-height: 1.3;
}

.stat-bar span {
	font-size: 12px;
	color: var(--c-muted);
}

/* 标签胶囊（扁平：实心描边，无圆角） */
.chip {
	display: inline-block;
	padding: 3px 9px;
	font-size: 12px;
	line-height: 1.6;
	color: var(--c-primary);
	background: var(--c-primary-soft);
	border: 1px solid transparent;
	transition: all .15s ease;
}

.chip:hover {
	color: #fff;
	background: var(--c-primary);
	border-color: var(--c-primary);
}

.chip-plain {
	color: var(--c-muted);
	background: transparent;
	border-color: var(--c-border);
}

.chip-plain:hover {
	color: var(--c-primary);
	background: var(--c-primary-soft);
	border-color: var(--c-primary);
}

/* 按钮 */
.btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 8px 18px;
	font-size: 14px;
	color: var(--c-text);
	background: var(--c-bg);
	border: 1px solid var(--c-border-strong);
	transition: all .15s ease;
}

.btn:hover {
	color: #fff;
	background: var(--c-primary);
	border-color: var(--c-primary);
}

/* 空状态 */
.empty {
	padding: 48px 20px;
	text-align: center;
	color: var(--c-muted);
	font-size: 14px;
	border: 1px dashed var(--c-border-strong);
}

.empty i {
	font-size: 30px;
	display: block;
	margin-bottom: 12px;
	color: var(--c-border-strong);
}

/* 回到顶部（扁平方块，替代 235KB 的 to_top.png） */
#back-to-top {
	position: fixed;
	right: 20px;
	bottom: 24px;
	z-index: 900;
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 18px;
	color: var(--c-muted);
	background: var(--c-bg);
	border: 1px solid var(--c-border-strong);
	opacity: 0;
	visibility: hidden;
	transition: all .2s ease;
}

#back-to-top.show {
	opacity: 1;
	visibility: visible;
}

#back-to-top:hover {
	color: #fff;
	background: var(--c-primary);
	border-color: var(--c-primary);
}

/* 无障碍：仅屏幕阅读器可见 */
.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ---------- 跳到正文 ----------
   用 clip-path 而不是 .sr-only 那套 clip：clip 会连同 position:absolute
   一起把元素留在布局流里，固定定位 + clip-path 能让它彻底移出屏幕，
   拿到焦点时再用 top/left 移回来，位置可控。
   不能用 display:none 或 visibility:hidden —— 两者都会让元素在
   按 Tab 顺序里彻底消失，这个链接就永远按不到。 */
.skip-link {
	position: fixed;
	top: 8px;
	left: 8px;
	z-index: 1200;
	padding: 8px 14px;
	font-size: 13px;
	color: var(--c-primary);
	background: var(--c-bg);
	border: 1px solid var(--c-primary);
	/* clip-path 移出屏幕，但元素仍可聚焦 */
	transform: translateY(-200%);
	transition: transform .18s ease;
}

.skip-link:focus {
	transform: translateY(0);
}

/* ---------- 焦点样式 ----------
   全站之前只有浏览器默认焦点环：颜色是系统蓝，在 #e06c75 主色和
   1px 灰描边之间非常跳，而且默认环是双线，宽度不可控。
   这里统一成「主色外框 + 白底内衬」，压在任何背景上都看得见。

   [tabindex] 特意排除 -1：这类元素不可 Tab 到达，只在「跳到正文」
   被激活时由脚本把焦点移进来。焦点环的作用是告诉用户「键盘位置在哪」，
   而一个包住整篇正文的巨型粉框什么也说明不了，还会盖住版面边缘。
   焦点本身照常移动，屏幕阅读器也会正常播报落点。 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 2px;
	/* 白内衬：让焦点环和元素自身的边框之间留 2px 视觉间隙，
	   元素是主色底（按钮 hover）时环不会糊进去。 */
	box-shadow: 0 0 0 4px var(--c-bg);
	border-radius: 0;
}

/* 不支持 :focus-visible 的浏览器退回 :focus。
   现代浏览器全都支持，这条只是不让老浏览器把焦点提示弄丢。 */
@supports not selector(:focus-visible) {
	a:focus,
	button:focus,
	input:focus,
	textarea:focus,
	select:focus,
	[tabindex]:not([tabindex="-1"]):focus {
		outline: 2px solid var(--c-primary);
		outline-offset: 2px;
	}
}

/* 输入框/搜索框自己已经有 :focus-within 的边框反馈，
   再叠一圈外环会变成双层高亮。只留外框。 */
.search-box:focus-within {
	outline: 2px solid var(--c-primary);
	outline-offset: 2px;
}

.search-box input:focus,
.search-box input:focus-visible {
	outline: none;
	box-shadow: none;
}

/* 鼠标点过之后不显示焦点环：:focus-visible 本来就只对键盘生效，
   下面这条是给不支持它的浏览器兜底 —— 用 :focus 兜底就必须
   用 :not(:focus-visible) 把鼠标点击排除掉。 */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible) {
	outline: none;
	box-shadow: none;
}

/* 正文里的锚点链接：目录点过去之后，浏览器不会移动焦点，
   键盘用户的焦点还留在原处，:focus-visible 也就不会亮。
   用 :target 把目标标题标出来作为替代提示。 */
.rich :target,
.post-content :target {
	background: var(--c-primary-soft);
}

/* 页面切换淡入 */
@keyframes fade-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}

body > #content {
	animation: fade-in .25s ease;
}

/* ---------- 响应式 ---------- */
@media screen and (max-width: 768px) {
	.wrap {
		padding: 0 14px;
	}

	#content {
		padding-top: calc(var(--nav-h) - 2px);
	}

	.page-head {
		margin: 28px 0 18px;
	}

	.page-head h1 {
		font-size: 21px;
	}

	.stat-bar > div {
		min-width: 50%;
		border-bottom: 1px solid var(--c-border);
	}

	.stat-bar > div:nth-child(2n) {
		border-right: 0;
	}

	.stat-bar > div:nth-last-child(-n+2) {
		border-bottom: 0;
	}

	#back-to-top {
		right: 12px;
		bottom: 16px;
	}
}

@media screen and (max-width: 480px) {
	body {
		font-size: 14px;
	}
}

/* ---------- 触摸设备上的「粘住的悬停」 ----------
   手指点完抬起之后，浏览器仍然会让 :hover 继续命中那个元素，
   而上面这些按钮的 hover 都是「变主色」—— 于是点过一次的按钮会一直亮着，
   看起来就像它保持着选中状态。没有悬停能力的设备一律退回未悬停时的样子，
   按下反馈仍旧由 :active / 焦点环承担。
   玩家自定义组件的同类处理在 player.css / calendar.css 里。 */
@media (hover: none) {
	.btn:hover {
		color: var(--c-text);
		background: var(--c-bg);
		border-color: var(--c-border-strong);
	}

	.chip:hover {
		color: var(--c-primary);
		background: var(--c-primary-soft);
		border-color: transparent;
	}

	.chip-plain:hover {
		color: var(--c-muted);
		background: transparent;
		border-color: var(--c-border);
	}

	#back-to-top:hover {
		color: var(--c-muted);
		background: var(--c-bg);
		border-color: var(--c-border-strong);
	}
}
