/* ==========================================================================
   次元小窝 · 个人中心样式（css/my.css）
   结构与首页同构：左常驻侧栏 + 右主内容区，侧栏那套 .sb-* 和首页写法一致，切页不跳。
   设计语言同首页 / 登录页：用线不用阴影 / 主色只表达"可交互·被选中" / 标题压小、字距拉开。
   目录：§0 设计令牌  §1 基础重置  §2 页面骨架  §3 侧栏  §4 资料头卡  §5 内容区（Tab + 面板）  §6 表单  §7 响应式  §8 果冻交互
   ⚠️ 全站零渐变。"氛围"靠点阵图案（见 §1 body::before）。
   ⚠️ :root 令牌和 index.css / login.css 一一对应；好处是不受首页样式干扰，代价是改主题色要改三个文件。
   ========================================================================== */


/* ============================ §0 设计令牌 ============================ */
:root{
	/* ---------- 字号：七档（和 index.css 同一套，改全站只动这几行） ---------- */
	--fs-xs:   12px;
	--fs-sm:   13px;
	--fs-base: 14px;
	--fs-md:   15px;
	--fs-lg:   17px;
	--fs-xl:   20px;
	--fs-2xl:  24px;

	/* ---------- 头像三档 ---------- */
	--av-sm: 32px;
	--av-md: 36px;
	--av-lg: 40px;

	/* 静空蓝阶（和 index.css / login.css 逐字一致，别单独改这里）
	   ⚠️ 色相 206°、饱和度 60~72%，比上一版整体暗一档：
	      上一版主色 #38bdf8 亮度 74%、压白字只有 2.14:1，属于"看着亮、其实看不清"。 */
	--blue-50:   #f2f8fe;
	--blue-100:  #e3f0fb;
	--blue-200:  #c4def5;
	--blue-300:  #96c4e9;
	--blue-400:  #61a4db;   /* 图标 / 开关（配深墨字 6.02:1） */
	--blue-500:  #2f82c4;   /* 强调、选中描边 */
	--blue-600:  #1d6ba6;   /* 主按钮底（白字 5.67:1） */
	--blue-700:  #14507c;   /* 深蓝：焦点环、链接（白字 8.51:1） */

	/* 墨色（实测对比度 15.1 / 9.6 / 6.2 / 3.8:1） */
	--ink-900: #16222e;
	--ink-700: #2f4356;
	--ink-500: #4c5f72;
	--ink-400: #6e8194;

	/* 线 */
	--line:      #d8e4f0;
	--line-soft: #e7eff7;
	--line-blue: #bcd4ea;

	/* 面 */
	--surface: #ffffff;
	--paper:   #f4f8fc;

	/* 语义色：封禁、错误提示用。⚠️ 状态类信息不能跟着主色变蓝，否则"正常"和"封禁"分不清 */
	--alert:      #c9304d;
	--alert-soft: #fdeef2;
	--alert-line: #f6d3dc;
	--ok:         #3f8f6b;
	--ok-soft:    #eaf6f0;

	/* 未读小红点。⚠️ 必须和 index.css 的 --dot 同色，否则左右切页时红点会突然变色 */
	--dot: #ff6b8a;

	/* 圆角：⚠️ 必须和 index.css / login.css 逐字一致，三页切来切去不能有观感差 */
	--r-xs: 6px;
	--r-sm: 10px;
	--r-md: 14px;
	--r-lg: 20px;
	--r-full: 999px;

	/* 间距 */
	--sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;
	--sp-4: 18px; --sp-5: 26px; --sp-6: 40px;

	/* 内容区左右留白。⚠️ .main 的 padding 和 .topbar 的 margin 必须用同一个变量 */
	--gutter: 30px;

	/* 阴影：三级体系，Y 偏移 2 / 8 / 24 */
	--sh-1: 0 2px 8px -2px rgba(29, 107, 166, 0.16), 0 1px 2px rgba(22, 34, 46, 0.05);
	--sh-2: 0 10px 24px -12px rgba(29, 107, 166, 0.40), 0 2px 6px -2px rgba(22, 34, 46, 0.08);
	--sh-3: 0 24px 48px -20px rgba(29, 107, 166, 0.46), 0 8px 20px -10px rgba(22, 34, 46, 0.10);

	/* 动效：--ease 无过冲；要 Q 弹得显式用 --ease-q */
	--ease: cubic-bezier(0.16, 1, 0.3, 1);
	--ease-q: cubic-bezier(0.34, 1.56, 0.64, 1);
	--ease-q-soft: cubic-bezier(0.22, 1.30, 0.36, 1);
	--dur-fast: 160ms;
	--dur-press: 110ms;
	--dur: 320ms;
	--dur-slow: 480ms;

	/* 字体 */
	--font-body: "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei UI",
		"Microsoft YaHei", "Hiragino Sans", "Noto Sans SC", system-ui, sans-serif;
	--font-display: "Jost", var(--font-body);
}


/* ========================= §1 基础重置 ========================= */
*, *::before, *::after{ box-sizing: border-box; }

body{
	margin: 0;
	font-family: var(--font-body);
	font-size: var(--fs-md);
	line-height: 1.8;
	letter-spacing: 0.02em;
	color: var(--ink-700);
	background-color: var(--paper);
	-webkit-font-smoothing: antialiased;
}

/* 氛围层：点阵网格。⚠️ 和 index.css / login.css 必须是同一张图、同一档距 ——
   三页切换时背景纹理不能变，否则像换了站。此处刻意不用径向渐变的"雾状光晕"。 */
body::before{
	content: "";
	position: fixed;
	inset: 0;
	z-index: 0;
	pointer-events: none;      /* 装饰层绝不能挡住点击 */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26'%3E%3Ccircle cx='2' cy='2' r='1.15' fill='%234f93bd' fill-opacity='.16'/%3E%3C/svg%3E");
	background-size: 26px 26px;
}

/* 全站统一一种焦点环 */
:focus-visible{
	outline: 2px solid var(--blue-700);
	outline-offset: 2px;
	border-radius: var(--r-xs);
}


/* ======================== §2 页面骨架 ======================== */
.layout{
	position: relative;
	z-index: 1;                /* 抬到氛围层之上 */
	display: flex;
	min-height: 100vh;
	width: 100%;
}


/* ========================== §3 侧栏 ==========================
   ⚠️ 逐条复刻 index.css §3，两边侧栏视觉 / 手感一致，左右切页不跳。
   ⚠️ 类名统一用首页那套 .left-sidebar / .sb-*（早期自造的 .sidebar / .sb-logo 已废弃）。
   ⚠️ 手机上整条收进抽屉（见 §7 的 760 档），需要 .sb-toggle + .sb-mask 配合。 */
.left-sidebar{
	width: 236px;

	/* ↓ 四条"保命设置"，缺一不可 */
	flex-shrink: 0;         /* 内容区再宽也不许把侧栏压扁 */
	box-sizing: border-box; /* 让 padding 算进 236px 之内，否则实际会变宽 */
	position: sticky;       /* 右侧滚动时钉在视口顶部 */
	top: 0;
	height: 100vh;          /* ⚠️ 钉住时必须有高度，否则只有内容高，一滚就跟着跑 */
	overflow-y: auto;
	/* ⚠️ 下面这行别删！自定义滚动条是"占宽度"的（见本段下面的 6px 规则），
	   滚动条一开一关，导航项宽度就在 199↔193 之间跳 6px，看着像整条侧栏在抖。
	   stable = 永远预留那 6px，宽度从此与滚动条开关无关。 */
	scrollbar-gutter: stable;

	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
	padding: var(--sp-5) var(--sp-4);

	/* ⚠️ 实底，不要毛玻璃（和 index.css 侧栏一致）。backdrop-filter 会让
	   整条 100vh 侧栏跟着滚动反复重算模糊，是最不值的一处开销。 */
	background-color: var(--surface);
	border-right: 1px solid var(--line);   /* 一根发丝线分界，不用阴影 */
}

/* 侧栏滚动条：做细，用主色浅档 */
.left-sidebar::-webkit-scrollbar{ width: 6px; }
.left-sidebar::-webkit-scrollbar-track{ background: transparent; }
.left-sidebar::-webkit-scrollbar-thumb{ background: var(--blue-200); border-radius: var(--r-full); }
.left-sidebar::-webkit-scrollbar-thumb:hover{ background: var(--blue-300); }

/* ---------- 3.1 品牌区 ---------- */
.sb-brand{
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 0 var(--sp-1);
}

/* 清掉 h1 默认外边距；line-height:0 去掉图片底部空隙 */
.sb-brand-mark{ margin: 0; line-height: 0; }
.sb-brand-mark a{ display: inline-block; line-height: 0; }

.sb-logo-img{ display: block; width: 78%; height: auto; }

.sb-sub{
	margin: 0;
	font-size: var(--fs-xs);
	line-height: 1.6;
	letter-spacing: 0.04em;
	color: var(--ink-500);
}

/* ---------- 3.2 上传主按钮 ---------- */
/* 全站唯一的"实心色块"，视觉重心就在这儿 */
.sb-upload{
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	width: 100%;
	height: 38px;
	border: 0;
	border-radius: var(--r-sm);
	cursor: pointer;
	font-family: inherit;   /* ⚠️ 按钮不继承字体，不写会变宋体 */
	font-size: var(--fs-base);
	font-weight: 600;
	letter-spacing: 0.08em;
	color: #fff;
	background-color: var(--blue-600);
	box-shadow: var(--sh-2);
	/* 别写 transition: all（会带上布局属性，莫名抖动）*/
	transition: background-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.sb-upload svg{ width: 16px; height: 16px; }

.sb-upload:hover{ background-color: var(--blue-700); transform: translateY(-1px); }
.sb-upload:active{ transform: translateY(0) scale(0.99); }

/* ---------- 3.3 导航 ---------- */
.sb-nav{
	display: flex;
	flex-direction: column;
	min-height: 0;   /* 允许被压缩，否则内容顶出侧栏 */
}

.sb-group{
	list-style: none;   /* 去掉默认小圆点 */
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

/* 分组小标题：小、浅、字距大，比分割线透气 */
.sb-group-title{
	margin: var(--sp-4) 0 6px;
	padding-left: 10px;
	font-size: var(--fs-xs);
	font-weight: 500;
	letter-spacing: 0.18em;
	color: var(--ink-500);
}

/* 单个导航项 */
.sb-item{
	position: relative;   /* 给选中态竖条做定位基准 */
	display: flex;
	align-items: center;
	gap: 9px;
	height: 34px;
	padding: 0 10px;
	border-radius: var(--r-sm);
	font-size: var(--fs-base);
	color: var(--ink-700);
	text-decoration: none;   /* 去掉 <a> 默认下划线 */
	transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.sb-item svg{
	width: 16px;
	height: 16px;
	flex-shrink: 0;
	opacity: 0.72;   /* 图标比文字浅，突出文字 */
	transition: opacity var(--dur-fast) var(--ease);
}

.sb-item:hover{
	background-color: var(--blue-50);
	color: var(--ink-900);
}
.sb-item:hover svg{ opacity: 1; }

/* 选中态：淡蓝底 + 深字 + 左侧 2px 竖条（::before 画）*/
.sb-item.is-active{
	color: var(--ink-900);
	font-weight: 600;
	background-color: var(--blue-100);
}
.sb-item.is-active svg{ opacity: 1; }
.sb-item.is-active::before{
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);   /* 垂直居中，比硬算 top 值稳 */
	width: 2px;
	height: 16px;
	border-radius: 0 2px 2px 0;
	background-color: var(--blue-700);
}

/* 未读小红点：margin-left:auto 推到行末。红色是"有未读"的通用约定 */
.sb-dot{
	margin-left: auto;
	width: 6px;
	height: 6px;
	flex-shrink: 0;
	border-radius: 50%;
	background: var(--dot);
	box-shadow: 0 0 0 3px rgba(255, 107, 138, 0.14);
}

/* ---------- 3.4 热门标签胶囊 ---------- */
.sb-tags{
	display: flex;
	flex-wrap: wrap;   /* 放不下换行，别撑破 236px */
	gap: 6px;
	padding: 0 var(--sp-1);
}

.sb-tag{
	/* ⚠️ 与 css/index.css 的那份**逐字一致**（侧栏是七个页面共用的，两份样式表各存了一份）。
	   改成全胶囊、padding 提到 4px 11px 的原因见 index.css 里那段注释。 */
	padding: 4px 11px;
	border-radius: var(--r-full);
	font-size: var(--fs-xs);
	color: var(--ink-500);
	background: transparent;
	border: 1px solid var(--line);
	cursor: pointer;
	transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease);
}
.sb-tag:hover{
	color: var(--ink-900);
	background: var(--blue-50);
	border-color: var(--blue-200);
}


/* ========================== §4 主区 ========================== */
.main{
	flex: 1;
	min-width: 0;              /* ⚠️ 不加，长内容会顶破整行 */
	display: flex;
	flex-direction: column;
	gap: var(--sp-5);
	padding: 0 var(--gutter) var(--sp-6);
}

/* 顶栏：通栏 + 实底。⚠️ 通栏要配 calc(100% + 2×--gutter)，只写 100% 右边界会缩进去 */
.topbar{
	position: sticky;
	top: 0;
	z-index: 10;
	width: calc(100% + var(--gutter) * 2);
	margin: 0 calc(var(--gutter) * -1);
	height: 58px;
	padding: 0 var(--gutter);
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	/* ⚠️ 实底。原来是 rgba(255,255,255,0.82) + backdrop-filter: blur(14px)，
	   和 index.css 的顶栏是同一种写法，一起换成实底（滚动不再重算模糊）。 */
	background-color: var(--surface);
	border-bottom: 1px solid var(--line);
}

.tb-title{
	margin: 0;
	font-size: var(--fs-lg);
	font-weight: 600;
	letter-spacing: 0.08em;
	color: var(--ink-900);
}

/* 面包屑：小、浅，跟在标题后。⚠️ .tb-back 是真 <a>，这里显式压成"面包屑的样子" */
.tb-crumb{
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: var(--fs-sm);
	letter-spacing: 0.06em;
	color: var(--ink-400);
}
.tb-back{
	color: var(--blue-700);
	text-decoration: none;      /* ⚠️ 去掉 <a> 默认下划线 */
	white-space: nowrap;        /* 别让 "← 发现首页" 断开 */
	transition: color var(--dur-fast) var(--ease);
}
.tb-back:hover{ color: var(--blue-600); text-decoration: underline; }
.tb-sep{ color: var(--line-blue); }   /* 分隔的 "/"，用最浅线色 */

.tb-actions{
	margin-left: auto;         /* 推到最右边 */
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	font-size: var(--fs-sm);
	color: var(--ink-500);
}


/* ---------- 4.1 资料头卡 ---------- */
.profile{
	position: relative;
	overflow: hidden;
	display: flex;
	align-items: center;
	flex-wrap: wrap;           /* 窄屏时右侧统计换行 */
	gap: var(--sp-4) var(--sp-5);
	padding: var(--sp-5);
	border-radius: var(--r-lg);
	/* ⚠️ 这里复用了 .des 的蓝底令牌纯属误伤，已改回白底 ——
	   资料头卡本来就该是"白卡片"，和首页那块浅蓝头图卡分工不同。 */
	background-color: var(--surface);
	border: 1px solid var(--line-blue);
	box-shadow: var(--sh-1);
}

/* 头像：圆形裁切。⚠️ 里面可能是 <img> 或 <svg> 占位，用 grid 居中 + overflow:hidden 兜溢出 */
.avatar{
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 84px;
	height: 84px;
	border-radius: 50%;
	overflow: hidden;
	color: var(--ink-400);
	background-color: var(--blue-50);
	border: 1px solid var(--line-blue);
	box-shadow: var(--sh-1);   /* 头像是这页最大的"图片"，给一级阴影才有分量 */
}
.avatar svg{ width: 40px; height: 40px; }
.avatar img{
	width: 100%;
	height: 100%;
	object-fit: cover;         /* 非正方形时裁切而非压扁 */
	display: block;
}

/* 昵称 + 用户名 + 徽章那一列 */
.profile-info{
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.profile-name{
	margin: 0;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--sp-2);
	font-size: var(--fs-2xl);
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--ink-900);
}

/* 角色徽章：三种角色三种颜色（身份信息，允许用语义色）*/
.badge{
	display: inline-flex;
	align-items: center;
	height: 20px;
	padding: 0 9px;
	/* ⚠️ 同上：身份贴片和标签是同一类形状，统一全胶囊 */
	border-radius: var(--r-full);
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: 0.08em;
}
/* ⚠️ 不能省！上面的 display:inline-flex 会盖过 [hidden] 的 display:none，不加"已封禁"徽章照样显示（登录页 .form-alert 踩过同坑）*/
.badge[hidden]{ display: none; }
.badge--owner{ color: #b8556b; background-color: #fff5f7; border: 1px solid #f6d3dc; }
.badge--admin{ color: var(--blue-700); background-color: var(--blue-100); border: 1px solid var(--blue-200); }
.badge--user{ color: var(--ink-500); background-color: var(--blue-50); border: 1px solid var(--line); }
/* 封禁状态：用警示红，必须一眼看出 */
.badge--banned{ color: var(--alert); background-color: var(--alert-soft); border: 1px solid var(--alert-line); }

.profile-meta{
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-4);
	font-size: var(--fs-sm);
	color: var(--ink-500);
}
.profile-meta span{ display: inline-flex; align-items: center; gap: 5px; }
.profile-meta svg{ width: 14px; height: 14px; opacity: 0.7; }

/* 头卡右侧数字统计，margin-left:auto 贴到最右 */
.profile-stats{
	display: flex;
	flex-shrink: 0;
	margin-left: auto;
}
.stat{
	display: flex;
	flex-direction: column;
	align-items: flex-end;     /* 数字右对齐 */
	padding: 0 var(--sp-4);
}
.stat + .stat{ border-left: 1px solid var(--line-blue); }   /* 相邻两项之间一条发丝线 */

.stat b{
	font-family: var(--font-display);
	font-size: var(--fs-2xl);
	font-weight: 500;
	line-height: 1.2;
	color: var(--ink-900);
	font-variant-numeric: tabular-nums;   /* 等宽数字，变化时不抖 */
}
.stat span{
	font-size: var(--fs-xs);
	letter-spacing: 0.1em;
	color: var(--ink-500);
}


/* ====================== §5 内容区（Tab） ======================
   Tab 用「藏起来的 radio + label」实现，零 JS：同 name 即单选，面板靠 :checked ~ 控制显隐。
   ⚠️ DOM 顺序硬要求：radio 必须排在所有面板前面（~ 只认后面的兄弟）。 */
.panel-wrap{
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
}

/* 藏掉 radio：不用 display:none（会丢键盘焦点），透明 + 绝对定位既看不见又能被 Tab 感知 */
.tab-input{
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

/* Tab 条 */
.tabs{
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-1);
	padding-bottom: var(--sp-2);
	border-bottom: 1px solid var(--line);
}

.tab{
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	height: 34px;
	padding: 0 var(--sp-4);
	border-radius: var(--r-sm) var(--r-sm) 0 0;
	cursor: pointer;
	font-size: var(--fs-base);
	color: var(--ink-500);
	transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.tab:hover{ color: var(--ink-900); background-color: var(--blue-50); }
.tab svg{ width: 15px; height: 15px; opacity: 0.75; }

/* 计数小胶囊（"我的作品 3"里那个 3） */
.tab-count{
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 19px;
	height: 18px;
	padding: 0 6px;
	border-radius: var(--r-full);
	font-family: var(--font-display);
	font-size: var(--fs-xs);
	font-weight: 600;
	/* 数字等宽：计数从 3 跳到 12 时位数会变，等宽能让它只横向长、不左右晃 */
	font-variant-numeric: tabular-nums;
	color: var(--ink-500);
	background-color: var(--blue-50);
	border: 1px solid var(--line);
}

/* 选中态：深字加粗 + 底部 2px 主色短线 */
.tab-input:checked + .tab{
	color: var(--ink-900);
	font-weight: 600;
	background-color: var(--blue-50);
}
.tab-input:checked + .tab svg{ opacity: 1; }
.tab-input:checked + .tab::after{
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: calc(var(--sp-2) * -1 - 1px);   /* 压在 .tabs 的底边线上 */
	height: 2px;
	border-radius: 2px 2px 0 0;
	background-color: var(--blue-700);
}
.tab-input:focus-visible + .tab{
	outline: 2px solid var(--blue-700);
	outline-offset: -2px;
}

/* 面板：默认全藏，对应 radio 选中才显示。⚠️ 只能一个个对着 id 写（~ 只能从 radio 找到面板）*/
.panel{ display: none; }
#tab-images:checked   ~ .panel-images,
#tab-fav:checked      ~ .panel-fav,
#tab-comments:checked ~ .panel-comments,
#tab-settings:checked ~ .panel-settings{ display: block; }
/* ⚠️ 这里的 id 必须和上面 label 的 for 一致 */

/* 面板外壳：一个白卡片 */
.panel-inner{
	padding: var(--sp-5);
	border-radius: var(--r-lg);
	background-color: var(--surface);
	border: 1px solid var(--line);
	box-shadow: var(--sh-1);
}

/* 空状态：给一句解释，别留一大片白 */
.empty{
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--sp-3);
	min-height: 200px;
	text-align: center;
	color: var(--ink-400);
}
.empty svg{ width: 34px; height: 34px; opacity: 0.5; }
.empty p{ margin: 0; font-size: var(--fs-base); letter-spacing: 0.1em; }
.empty a{
	margin-top: var(--sp-1);
	font-size: var(--fs-sm);
	color: var(--blue-700);
	text-decoration: none;
	border-bottom: 1px solid var(--blue-200);
	transition: border-color var(--dur-fast) var(--ease);
}
.empty a:hover{ border-bottom-color: var(--blue-500); }


/* =========================== §6 表单 =========================== */
.form{
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
	max-width: 460px;          /* 460px 是舒适上限，太宽眼睛要左右扫 */
}

.field{
	display: flex;
	flex-direction: column;
	gap: 7px;
}

/* 标签：小、浅、字距大，同首页分组小标题 */
.field-label{
	display: flex;
	align-items: baseline;
	gap: 6px;
	font-size: var(--fs-xs);
	font-weight: 500;
	letter-spacing: 0.14em;
	color: var(--ink-500);
}
.field-hint{
	font-size: var(--fs-xs);
	letter-spacing: 0.08em;
	color: var(--ink-400);
}

/* 输入框：边框画在框自己身上（没有图标，不需要外层壳）*/
.input,
.textarea{
	width: 100%;
	padding: 0 12px;
	border-radius: var(--r-sm);
	background-color: var(--blue-50);
	border: 1px solid var(--blue-200);
	outline: none;
	font-family: inherit;      /* ⚠️ 表单控件不继承字体，不写会变宋体 */
	font-size: var(--fs-md);
	letter-spacing: inherit;
	color: var(--ink-900);
	transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
		box-shadow var(--dur-fast) var(--ease);
}
.input{ height: 40px; }
.textarea{ min-height: 92px; padding: 10px 12px; line-height: 1.7; resize: vertical; }

.input:focus,
.textarea:focus{
	background-color: var(--surface);
	border-color: var(--blue-600);
	box-shadow: 0 0 0 3px rgba(29, 107, 166, 0.22);
}
.input::placeholder,
.textarea::placeholder{ color: var(--ink-400); }

/* 只读输入框（用户名不能改）：灰底 + 默认光标 */
.input[readonly]{
	background-color: var(--line-soft);
	border-color: var(--line);
	color: var(--ink-500);
	cursor: not-allowed;
}

/* 开关（暗色模式）：藏起来的 checkbox + 看得见的轨道 */
.switch{
	display: inline-flex;
	align-items: center;
	gap: 10px;
	cursor: pointer;
	font-size: var(--fs-base);
	color: var(--ink-700);
	user-select: none;
}
.switch-input{
	position: absolute;
	opacity: 0;
	pointer-events: none;
}
/* 轨道 */
.switch-track{
	position: relative;
	flex-shrink: 0;
	width: 42px;
	height: 24px;
	border-radius: var(--r-full);
	background-color: var(--blue-200);
	transition: background-color var(--dur-fast) var(--ease);
}
/* 圆点：::after 画，靠 left 平移 */
.switch-track::after{
	content: "";
	position: absolute;
	top: 3px;
	left: 3px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background-color: var(--surface);
	box-shadow: 0 1px 3px rgba(22, 34, 46, 0.22);
	/* Q 弹曲线：滑块会冲过终点一点再退回来，像被弹过去的（不过冲的话是"平移"，很呆） */
	transition: transform var(--dur) var(--ease-q);
}
/* 打开：轨道变主色、圆点滑到右边 */
.switch-input:checked + .switch-track{ background-color: var(--blue-400); }
.switch-input:checked + .switch-track::after{ transform: translateX(18px); }
.switch-input:focus-visible + .switch-track{
	box-shadow: 0 0 0 3px rgba(29, 107, 166, 0.35);
}

/* 表单行末的按钮组 */
.form-actions{
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	padding-top: var(--sp-2);
	border-top: 1px solid var(--line-soft);
}

/* 按钮共用形状，主次只靠底色和边框区分 */
.btn{
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	height: 38px;
	padding: 0 20px;
	border-radius: var(--r-sm);
	cursor: pointer;
	font-family: inherit;
	font-size: var(--fs-base);
	font-weight: 600;
	letter-spacing: 0.08em;
	transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}

/* 主按钮：实心主色。⚠️ 底压深之后必须配白字，深墨字会糊在蓝里 */
.btn--primary{
	color: #fff;
	background-color: var(--blue-600);
	border: 1px solid transparent;
	box-shadow: var(--sh-2);
}
.btn--primary:hover{ background-color: var(--blue-700); transform: translateY(-1px); }
.btn--primary:active{ transform: translateY(0) scale(0.99); }

/* 次要按钮（重置）：描边。⚠️ 边框写 1px solid 而非 0 —— 少了会比主按钮矮 2px、窄 2px */
.btn--ghost{
	color: var(--ink-500);
	background-color: var(--surface);
	border: 1px solid var(--blue-200);
	box-shadow: none;
}
.btn--ghost:hover{
	color: var(--ink-900);
	background-color: var(--blue-50);
	border-color: var(--blue-400);
}

/* 小号按钮：一行里并排放两个时用 */
.btn--sm{
	height: 32px;
	padding: 0 14px;
	font-size: var(--fs-sm);
	font-weight: 500;
}

/* 最轻的按钮：只有文字。"恢复默认"是次要且有点破坏性的动作，压到最轻才符合层级 */
.btn--quiet{
	color: var(--ink-400);
	background-color: transparent;
	border: 1px solid transparent;
	box-shadow: none;
}
.btn--quiet:hover{
	color: var(--ink-700);
	background-color: var(--blue-50);
}

/* ---------- 头像选择区：预览小图 + 两个按钮 + 状态文字 ---------- */
.avatar-pick{
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	flex-wrap: wrap;
}

/* 预览框：40×40 圆角小图，空时显示默认头像图标 */
.avatar-pick__preview{
	width: 40px;
	height: 40px;
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	border-radius: 50%;
	border: 1px solid var(--line-blue);
	background-color: var(--blue-50);
	color: var(--blue-400);
}
.avatar-pick__preview svg{ width: 22px; height: 22px; }
/* ⚠️ 预览图要"填满小圆框"：只写 width:100% 时长图会缩、上下留白 */
.avatar-pick__preview img{
	width: 100%;
	height: 100%;
	object-fit: cover;      /* ⚠️ 用 cover 不是 contain，圆框里要填满 */
	display: block;
}

.avatar-pick__btns{
	display: flex;
	align-items: center;
	gap: var(--sp-2);
}

/* 真正的 file input：藏起来但仍可点。⚠️ 不能用 display:none / visibility:hidden —— 会让 label 的 for 转发失效（点"选择图片"没反应）。用"缩成 1px + 透明 + 绝对定位"。⚠️ 也别加 pointer-events:none，那会让它彻底点不到 */
.avatar-file{
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	overflow: hidden;
}

.avatar-pick__note{
	font-size: var(--fs-sm);
	color: var(--ink-400);
	/* ⚠️ 长文件名会把整行顶宽，必须 min-width:0 + 省略号 */
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* label 当按钮用时，鼠标样式手动补 */
label.btn{ cursor: pointer; }


/* ---------- 图片裁剪器（框选版）----------：舞台(装图) + 正方形选框 + 按钮。
   图片固定不动；在图上拖划出正方形选框；滚轮缩放选框。用户看到的就是他要的那块 */
.cropper{
	margin-top: var(--sp-3);
	padding: var(--sp-3);
	border-radius: var(--r-md);
	background-color: var(--blue-50);
	border: 1px solid var(--line-blue);
	/* ⚠️ 为了居中那个 inline-block 滚动容器（不是居中文字）。inline-block 写 margin:0 auto 无效，得靠父级 text-align */
	text-align: center;
}
/* ⚠️ 不能省：上面写了 padding 等，.cropper[hidden] 必须能真的藏起来（.badge / .form-alert / .toast 都踩过）*/
.cropper[hidden]{ display: none; }

/* 滚动容器：图片放大后溢出可视区的部分由它"收起来"。尺寸**固定**，不跟图片走。
   ⚠️ 为什么多包一层：直接在舞台上 overflow:hidden 会把选框也裁掉边缘，包一层把"可视裁剪"和"选框层"分开。它同时是滚轮事件的监听者。
   ⚠️ "深色底"是有用的（改了四轮）：它就是图片溢出可视区时的那片底，溢出部分靠拖动(panX/panY)看。
      用 overflow: hidden 不用 auto —— 平移交给 JS，不要滚动条（用户圈出来的那两条）。 */
.cropper__scroller{
	position: relative;
	overflow: hidden;                 /* ⚠️ 不是 auto —— 平移交给 JS 拖动，不要滚动条 */
	display: inline-block;            /* ⚠️ inline-block 才能被父级 text-align 居中 */
	width: 100%;                      /* 铺满面板宽度 */
	height: 52vh;                     /* 固定视口高度。⚠️ 别再跟着图片变 */
	max-width: 434px;                 /* 宽屏下别铺到整幅，否则裁剪区大得离谱 */
	padding: 0;                       /* ⚠️ 不留内边距，否则又给图片加一圈底 */
	border-radius: var(--r-sm);
	background-color: #0f1a24;        /* 深底。⚠️ 现在是"平移余量" */
	cursor: grab;                     /* 抓手 = 在这里拖能移动图片（框外拖动）*/
	touch-action: none;               /* ⚠️ 拦住触摸滚动，否则手机上拖图片会变成滚页面 */
	user-select: none;
	overscroll-behavior: contain;     /* 面板内滚轮不要连带滚动整页 */
	vertical-align: top;              /* inline-block 的基线空隙，别留着 */
}
/* ⚠️ 拖动时换成 grabbing，给"抓住了"的反馈 */
.cropper__scroller:active{ cursor: grabbing; }

/* 舞台：和容器一样大，就是一个坐标系。图片、遮罩、选框都相对它定位。
   ⚠️ 用绝对定位铺满容器（不是跟着图片走）—— 否则容器被图片撑大会长出滚动条。
   图片靠 flex 居中，比 JS 算 left/top 稳（不用等图片加载完测量）*/
.cropper__stage{
	position: absolute;               /* 铺满容器 */
	left: 0;
	top: 0;
	right: 0;
	bottom: 0;
	display: flex;                    /* 让图片在里面居中 */
	align-items: center;
	justify-content: center;
	line-height: 0;                   /* 消掉行内元素底部那几像素的基线空隙 */
	font-size: 0;                     /* 同上，双保险 */
}

/* 图片：按比例适配可视区，不拉伸。max-width / max-height 给上限，width/height 用 auto。
   ⚠️ 别写 width:100% + max-height，图会被拉扁。
   ⚠️ transform 顺序不能反：translate(panX, panY) 在前、scale(imgScale) 在后，否则平移量会被一起放大（拖起来"越来越猛"）。
   ⚠️ max-height(44vh) 必须小于容器的(52vh)，否则图一进来就顶满、没法挪。 */
.cropper__img{
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 44vh;
	pointer-events: none;             /* 事件统一挂在滚动容器上，图自己不吃 */
	-webkit-user-drag: none;          /* ⚠️ 拦掉原生图片拖拽 */
	transform-origin: center center;
	will-change: transform;           /* 提前告诉浏览器会变，滚轮缩放更跟手 */
}

/* ---------- 正方形选框 ----------
   细白线框 + 四个 L 形角框 + 双色描边（任何图片上都看得清）+ 三分辅助线。
   压暗改成一个独立的遮罩层（见 .cropmask），不用 box-shadow（9999px 扩散掉帧）*/
.cropper__box{
	position: absolute;
	left: 0;
	top: 0;
	width: 140px;                     /* 初始值，JS 一进来就会覆写 */
	height: 140px;
	/* ⚠️ box-sizing: border-box 很重要：不然边框加在尺寸外，JS 按 width 算的采样区和肉眼看到的框差几像素 */
	box-sizing: border-box;
	border: 1px solid rgba(255, 255, 255, 0.95);
	border-radius: 2px;
	/* 描边：外面一层深色，浅色图片上也看得清 */
	box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55);
	cursor: move;
	z-index: 4;                       /* ⚠️ 必须在遮罩(3)之上 */
}

.cropper__box:active{ cursor: grabbing; }

/* 压暗遮罩：由四块拼成（上下左右各一块），中间空出来的正好是选框位置。
   ⚠️ 不用 box-shadow: 0 0 0 9999px（扩散大、缩放掉帧），也不用 outline(不受 overflow:hidden 裁剪会盖到面板外)。
   四块位置由 JS 跟着选框写（见 my.js 的 drawMask）*/
.cropmask{
	position: absolute;
	background-color: rgba(10, 18, 26, 0.55);
	pointer-events: none;             /* ⚠️ 遮罩不能吃鼠标事件，否则框外拖不动 */
	z-index: 3;
}
.cropmask[hidden]{ display: none; }

/* 三分辅助线：绝对定位 + 百分比，跟着框尺寸自动变，不用 JS。要足够淡 */
.cropgrid{
	position: absolute;
	background-color: rgba(255, 255, 255, 0.32);
	pointer-events: none;             /* ⚠️ 辅助线不能吃鼠标事件，否则框内拖不动 */
}
.cropgrid--v1{ left: 33.333%; top: 0; width: 1px; height: 100%; }
.cropgrid--v2{ left: 66.666%; top: 0; width: 1px; height: 100%; }
.cropgrid--h1{ top: 33.333%; left: 0; height: 1px; width: 100%; }
.cropgrid--h2{ top: 66.666%; left: 0; height: 1px; width: 100%; }

/* 四角的 L 形角框：用 border-top + border-left"只画两条边"（Instagram / Figma 的常见做法），比实心方块轻。
   ⚠️ 位置：L 要画在**边框线外面**，四个角各往外负偏移，像给框镶护角。 */
.crophandle{
	position: absolute;
	width: 15px;
	height: 15px;
	pointer-events: none;             /* ⚠️ 同上，不能吃鼠标事件 */
	border: 0 solid #ffffff;
	/* 角框也要描边，浅色图上才看得见 */
	filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.8));
}
/* ⚠️ 负偏移写 **-2px** 不是 -1px：absolute 的包含块是父级 padding box（不含 border），.cropper__box 有 1px border，-1px 刚好被抵消，要贴着线外沿还得再让 1px。
   （踩过：一开始写 -1px，像"负偏移没生效"，其实是刚好抵消）*/
.crophandle--tl{ left: -2px; top: -2px;    border-left-width: 3px;  border-top-width: 3px; }
.crophandle--tr{ right: -2px; top: -2px;   border-right-width: 3px; border-top-width: 3px; }
.crophandle--bl{ left: -2px; bottom: -2px; border-left-width: 3px;  border-bottom-width: 3px; }
.crophandle--br{ right: -2px; bottom: -2px; border-right-width: 3px; border-bottom-width: 3px; }

/* ---------- 四角的**拖拽热区**（真正能拉大拉小的那块） ----------
   ⚠️ 为什么需要它：角框 .crophandle 只有 3px 粗且 pointer-events:none，命中面积太小，按偏 1~2px 就落到舞台、被当成"画新框"，框会突然变得很小。
   所以每角铺一块 22×22 的透明热区：比角框大一圈、向框外溢出 4px 盖住边框线、z-index 最高、光标换成斜向缩放箭头。 */
.crophit{
	position: absolute;
	width: 22px;
	height: 22px;
	z-index: 6;                 /* ⚠️ 比 .crophandle / .cropgrid 都高 */
	background: transparent;    /* 只要热区，不要画面 */
	touch-action: none;         /* 手机上别把它当成滚动手势 */
}
.crophit--tl{ left: -4px;  top: -4px;    cursor: nwse-resize; }
.crophit--tr{ right: -4px; top: -4px;    cursor: nesw-resize; }
.crophit--bl{ left: -4px;  bottom: -4px; cursor: nesw-resize; }
.crophit--br{ right: -4px; bottom: -4px; cursor: nwse-resize; }

/* ⚠️ 热区只在桌面端启用。手机上手指粗，22px 热区会压掉选框面积、反而难按 —— 手机保持"只能拖、不能拉角"，改大小就重拖新框 */
@media (max-width: 760px){
	.crophit{ display: none; }
}

/* ⚠️ 这里原本还有 .cropper__tip 和 .cropper__actions 两段样式，已随 HTML 元素一起删掉（改成"滚轮缩放 + 拖框 + 点保存修改自动裁剪"）。样式留着就是死代码 */

/* 操作结果提示条。⚠️ [hidden] 那条不能省：本规则有 display:flex，会盖过 [hidden] 的 display:none */
.toast{
	display: flex;
	align-items: flex-start;
	gap: var(--sp-2);
	padding: 10px 12px;
	border-radius: var(--r-sm);
	font-size: var(--fs-sm);
	line-height: 1.7;
	color: var(--blue-700);
	background-color: var(--blue-100);
	border: 1px solid var(--blue-200);
}
.toast svg{ width: 15px; height: 15px; flex-shrink: 0; margin-top: 3px; }
.toast--warn{
	color: var(--alert);
	background-color: var(--alert-soft);
	border-color: var(--alert-line);
}
.toast[hidden]{ display: none; }


/* ========================== §7 响应式 ==========================
   三档：1080 / 760 / 560。
   ⚠️ 760 档的手机形态改成和首页一样的「抽屉」（原来是隐藏侧栏）：侧栏推到屏外，顶栏出现汉堡按钮，点开拉出 + 遮罩。
   ⚠️ 抽屉要三样配合：.sb-toggle（藏起来的 checkbox）+ .tb-burger（点开）+ .sb-mask（遮罩）。 */
@media (max-width: 1080px){
	:root{ --gutter: 22px; }
	.left-sidebar{ width: 200px; }
	.profile-stats{ margin-left: 0; flex-wrap: wrap; gap: var(--sp-3); }
	.stat{ padding: 0 var(--sp-3) 0 0; }
	.stat + .stat{ padding-left: var(--sp-3); }
}


/* ---------- §7.1 抽屉开关 & 遮罩（桌面端全部不渲染） ---------- */

/* ⚠️ 用 position + opacity 藏，不用 display:none：后者会让键盘也 tab 不到 */
.sb-toggle{
	position: absolute;
	top: 0;
	left: 0;
	width: 0;
	height: 0;
	opacity: 0;
	pointer-events: none;
}

/* 键盘兜底：Tab 到这个隐形 checkbox 时，焦点环画在汉堡按钮上，否则焦点会"凭空消失" */
.sb-toggle:focus-visible ~ .main .tb-burger{
	outline: 2px solid var(--blue-700);
	outline-offset: 2px;
}

/* 桌面端 display:none 不渲染。⚠️ 手机拉开抽屉后把窗口拉宽，也不会残留灰罩子 */
.sb-mask{ display: none; }


/* ---------- §7.2 汉堡按钮 & 关闭按钮（桌面端都藏） ---------- */

.tb-burger,
.sb-close{
	display: none;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	cursor: pointer;
	color: var(--ink-700);
	background-color: var(--blue-50);
	border: 1px solid var(--blue-200);
	border-radius: var(--r-sm);
	transition: background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tb-burger svg,
.sb-close svg{ width: 19px; height: 19px; }

.tb-burger:hover,
.sb-close:hover{
	color: var(--ink-900);
	background-color: var(--blue-100);
	border-color: var(--blue-300);
}


/* ---------- §7.3 抽屉里的登录 / 注册（桌面端顶栏已有一份）---------- */

.sb-auth{ display: none; }

.sb-auth-btn{
	flex: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	font-family: inherit;      /* ⚠️ 按钮不继承字体，不写会变宋体 */
	font-size: var(--fs-base);
	letter-spacing: 0.08em;
	color: var(--ink-700);
	background-color: var(--surface);
	border: 1px solid var(--blue-200);
	border-radius: var(--r-sm);
	transition: background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.sb-auth-btn:hover{
	color: var(--ink-900);
	background-color: var(--blue-50);
	border-color: var(--blue-300);
}

/* 「注册」比「登录」重一点（浅蓝底 + 深字 + 加粗）。⚠️ 不做实心主色 —— 抽屉里已有「上传作品」实心块 */
.sb-auth-btn--reg{
	color: var(--ink-900);
	font-weight: 600;
	background-color: var(--blue-100);
}
.sb-auth-btn--reg:hover{ background-color: var(--blue-200); }


/* ---------- §7.4 手机档：把抽屉拉开 ---------- */

@media (max-width: 760px){
	:root{ --gutter: 14px; }

	.layout{ flex-direction: column; }

	/* 汉堡按钮现身。40×40，明显大于桌面 34px，手指才不易点空 */
	.tb-burger{ display: flex; width: 40px; height: 40px; }

	/* 触控目标地板：桌面 34/38px 是按鼠标定的，手机上换成手指 */
	.sb-upload{ height: 44px; }
	.sb-item{ height: 40px; }

	/* 侧栏 → 固定定位的抽屉，默认整条推到屏幕外 */
	.left-sidebar{
		position: fixed;          /* 脱离文档流 = 关着时不占位 */
		top: 0;
		bottom: 0;
		left: 0;
		z-index: 50;              /* 要压在顶栏(10) 和遮罩(40) 上面 */
		width: min(82vw, 276px);  /* 右边留余量，暗示后面还有内容 */
		height: auto;             /* 覆盖桌面的 height:100vh + sticky */

		transform: translateX(-100%);
		/* 只过渡 transform 和 box-shadow，别写 all */
		transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);

		/* 抽屉自己滚到底时，别把后面的整页也带着一起滚 */
		overscroll-behavior: contain;
	}

	/* 拉开：平移回原位 + 投影子 */
	.sb-toggle:checked ~ .left-sidebar{
		transform: none;
		box-shadow: 0 24px 64px -24px rgba(22, 34, 46, 0.5),
			0 0 0 1px var(--line-blue);
	}

	/* 遮罩现身 */
	.sb-mask{
		display: block;
		position: fixed;
		inset: 0;
		z-index: 40;              /* 低于侧栏(50)、高于顶栏(10) */
		/* ⚠️ 去掉 backdrop-filter: blur(2px)（满屏固定的模糊层，手机上掉帧明显），
		   底色 0.34 → 0.44 补回分量 */
		background-color: rgba(22, 34, 46, 0.44);
		opacity: 0;
		pointer-events: none;     /* 收着时不能挡住点击 */
		transition: opacity var(--dur) var(--ease);
	}
	.sb-toggle:checked ~ .sb-mask{ opacity: 1; pointer-events: auto; }

	/* 关闭按钮：贴品牌区右上角（label，点一下取消勾选）*/
	.sb-close{
		display: flex;
		position: absolute;
		top: var(--sp-3);
		right: var(--sp-3);
		width: 40px;
		height: 40px;
		background-color: transparent;
		border-color: transparent;
	}
	.sb-close:hover{ background-color: var(--blue-100); border-color: transparent; }

	/* 抽屉开着时锁住背景滚动。⚠️ :has() 支持较新，老浏览器整条忽略 —— 后果仅是背景还能滚，开合不受影响，可当渐进增强 */
	body:has(.sb-toggle:checked){ overflow: hidden; }

	.topbar{
		height: auto;
		padding: var(--sp-3) var(--gutter);
		flex-wrap: wrap;
		gap: var(--sp-1) var(--sp-3);
	}

	.main{ padding: 0 var(--gutter) var(--sp-5); gap: var(--sp-4); }

	/* 头卡：改成上下排。⚠️ 横向 flex 改 column 后 align-items 必须一起改成 stretch，否则子项缩成内容宽、右边留白 */
	.profile{
		flex-direction: column;
		align-items: stretch;
		padding: var(--sp-4);
	}
	.avatar{ align-self: center; }     /* 头像单独居中 */
	.profile-info{ align-items: center; text-align: center; }
	.profile-name{ justify-content: center; font-size: var(--fs-xl); }
	.profile-meta{ justify-content: center; }

	/* 统计：改成三格均分。⚠️ 桌面那套靠 .stat 的左右 padding 画竖线，手机数字居中后竖线会落在中间，所以清掉 padding/border 改用 grid 三等分 */
	.profile-stats{
		margin-left: 0;
		width: 100%;
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: var(--sp-3);
	}
	.stat{ align-items: center; padding: 0; }
	.stat + .stat{ border-left: 0; padding-left: 0; }   /* 去掉竖线 */

	.panel-inner{ padding: var(--sp-4); }
	.tab{ padding: 0 var(--sp-3); }

	/* ⚠️ iOS Safari：输入框字号 < 16px 一聚焦就放大整页，手机档顶到 16px */
	.input, .textarea{ font-size: 16px; }

	.form-actions{ flex-wrap: wrap; }
	.btn{ flex: 1; }
}


/* ================== §8 果冻交互（全站统一按压回弹） ==================
   动机：所有"能按的东西"按下去像果冻一样缩一下、松手弹回来。
   ⚠️ 两条规则必须成对，少一条就没有 Q 弹感：
     · 基础态：transform 的 transition 用 --ease-q（带过冲）→ 松手才"弹"回来；
     · :active：把 transition 改写成 --dur-press + --ease（不过冲）→ 按下才跟手。
       若 :active 也用过冲，手指还没松就先冲过头再缩回来，手感是飘的。
   ⚠️ 别给大面积元素（.panel-inner / .mcard / .tb-back）加 scale：
       大块缩放像页面在抖；.tb-back 是 display:inline 的 <a>，transform 对它本来就无效。
   ⚠️ 本节放在文件最后，靠"同优先级后者覆盖"接管前面散落的 :active，别往上搬。 */

.sb-upload, .sb-item, .sb-tag, .tab, .switch, .btn,
.tb-burger, .sb-close, .sb-auth-btn{
	transition:
		background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease),
		box-shadow var(--dur-fast) var(--ease),
		transform var(--dur) var(--ease-q);
}

.sb-upload:active, .sb-item:active, .sb-tag:active, .tab:active, .btn:active,
.tb-burger:active, .sb-close:active, .sb-auth-btn:active{
	transform: translateY(0) scale(0.94);
	transition:
		background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease),
		box-shadow var(--dur-fast) var(--ease),
		transform var(--dur-press) var(--ease);
}

/* 通栏宽行（侧栏项、Tab）：整条缩 0.94 会看出"忽宽忽窄"，幅度收小 */
.sb-item:active, .tab:active{ transform: translateY(0) scale(0.975); }

/* 圆形小图标：面积小，缩狠一点才有回弹的"啪" */
.tb-burger:active, .sb-close:active{ transform: translateY(0) scale(0.90); }

/* 开关：整块别动，只让轨道按一下（缩的是外壳会把 label 文字也带歪） */
.switch:active .switch-track{ transform: scale(0.94); }
.switch-track{ transition: background-color var(--dur-fast) var(--ease), transform var(--dur-press) var(--ease); }


/* ============ §9 无障碍：减弱动态效果 / 触摸目标 ============ */

/* ⚠️ 系统开了「减弱动态效果」时，位移/缩放/淡入全关。用 1ms 不用 0s
   （0s 会让依赖 transitionend 的代码收不到事件）。!important 是覆盖过渡的标准做法。 */
@media (prefers-reduced-motion: reduce){
	*, *::before, *::after{
		animation-duration: 1ms !important;
		animation-delay: 0ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 1ms !important;
		transition-delay: 0ms !important;
	}
	.sb-upload:active, .sb-item:active, .sb-tag:active, .tab:active, .btn:active,
	.tb-burger:active, .sb-close:active, .sb-auth-btn:active,
	.switch:active .switch-track{ transform: none !important; }
}

/* 触摸设备：30~38px 的小图标撑到 44px 热区。伪元素外扩，视觉尺寸不变 */
@media (pointer: coarse){
	.tb-burger, .sb-close{ position: relative; }
	.tb-burger::after, .sb-close::after{
		content: "";
		position: absolute;
		top: 50%;
		left: 50%;
		width: max(100%, 44px);
		height: max(100%, 44px);
		transform: translate(-50%, -50%);
	}
}
