/* ==========================================================================
   次元小窝 · 登录 / 注册页样式（css/login.css）
   设计方向：左品牌区 + 右居中卡片，和首页同一套语言（用线不用阴影 / 主色只表达"可交互·被选中"）。
   目录：§0 设计令牌  §1 基础重置  §2 页面骨架  §3 品牌区  §4 表单区  §5 按钮  §6 其它  §7 动效  §8 响应式  §9 果冻交互
   ⚠️ 全站零渐变。"氛围"靠点阵图案；品牌区右下角的同心圆涟漪（§3 .brand::after）
      和首页 .des 的右上角是同一个动机，全站只有这一种装饰语言。
   ⚠️ :root 和 index.css 是一一对应的拷贝。不 @import index.css，是因为那几千行本页用不上、还会带进 body 布局打架。代价：改主题色要改两个文件。
   ========================================================================== */


/* ============================ §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 逐字一致，别单独改这里）
	   ⚠️ 上一版最亮档 #38bdf8 亮度 74%，大面积铺在登录页左半边等于一块光源；
	      这一版整体压暗一档，观感从"霓虹"回到"晴空"。 */
	--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-blue: #bcd4ea;

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

	/* 语义色：错误提示。⚠️ 不能跟着主色变蓝 —— 蓝表示"正常"，错误必须是红的 */
	--alert:      #c9304d;
	--alert-soft: #fdeef2;
	--alert-line: #f6d3dc;

	/* 语义色：成功提示（注册成功）。同理不能写成主色的蓝，
	   要让人一眼分出"成了"和"错了"，所以给一套独立的绿 */
	--ok:      #2f7d5b;
	--ok-soft: #eef8f1;
	--ok-line: #cfe9d9;

	/* 圆角：⚠️ 和 index.css / my.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;

	/* 阴影：三级体系，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; }

html, body{ height: 100%; }

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 / my.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 页面骨架 ========================
   桌面：左品牌 / 右表单，两栏等高等宽比 46 : 54；手机改成上下排（见 §8）。
   ⚠️ 用 min-height 而不是 height：否则表单变高会被裁掉、还不出滚动条。 */
.page{
	position: relative;
	z-index: 1;                /* 抬到氛围层之上 */
	min-height: 100vh;
	display: flex;
	align-items: stretch;      /* 两栏等高 */
}


/* ========================== §3 品牌区 ==========================
   一块实心浅蓝，只放 logo / slogan / 三个卖点。留白比内容多 —— 这是"舞台"。 */
.brand{
	position: relative;
	overflow: hidden;
	flex: 0 0 46%;
	display: flex;
	flex-direction: column;
	/* ⚠️ 原来是 space-between：logo 顶、slogan 中、卖点底，中间被撑出两个大空洞，
	   左半屏看着"什么也没有"。改成整组垂直居中，视觉重心收拢到一处。 */
	justify-content: center;
	gap: 40px;
	padding: 48px;
	/* 实心浅蓝，不透明。⚠️ 原来是 backdrop-filter: blur(24px) 的玻璃 ——
	   品牌区是整页高、还固定不动，模糊层纯属白烧 GPU，换成实底一模一样好看。 */
	background-color: var(--blue-100);
	border-right: 1px solid var(--line-blue);
}

/* 右下角涟漪：3 条同心弧，圆心贴在右下角 → 只露 1/4。
   ⚠️ 原版是 linear-gradient(to top) 的"底光"，去掉渐变后换成几何图案；
   角标动机和 index.css 的 .des（右上角）是同一个，全站只此一种装饰语言。 */
.brand::after{
	content: "";
	position: absolute;
	right: 0;
	bottom: 0;
	width: 300px;
	height: 300px;
	pointer-events: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300' viewBox='0 0 300 300'%3E%3Cg fill='none' stroke='%239ecfe8' stroke-width='1.5' stroke-opacity='.55'%3E%3Ccircle cx='300' cy='300' r='64'/%3E%3Ccircle cx='300' cy='300' r='112'/%3E%3Ccircle cx='300' cy='300' r='160'/%3E%3C/g%3E%3C/svg%3E");
	background-size: contain;
	background-repeat: no-repeat;
}

/* 让内容压在光晕之上 */
.brand > *{ position: relative; z-index: 1; }

/* logo 是透明底 PNG */
.brand-logo{
	display: block;
	width: 132px;
	height: auto;
}

/* logo 从"居中组"里抽出来钉在左上角：
   ⚠️ 它必须脱离文档流（absolute），否则会跟着 slogan 一起跑到屏幕中间，
      品牌标跑到版面中央就不像 logo 了。父级 .brand 已经是 position:relative。 */
.brand > a{
	position: absolute;
	top: 40px;
	left: 48px;
}

.brand-slogan h2{
	margin: 0;
	font-family: var(--font-display);
	font-size: 30px;
	font-weight: 500;
	line-height: 1.35;
	letter-spacing: 0.04em;
	color: var(--ink-900);
}
.brand-slogan p{
	margin: var(--sp-3) 0 0;
	font-size: var(--fs-base);
	line-height: 1.9;
	color: var(--ink-500);
}

/* 小卖点：对勾用 ::before 内联 SVG 画 */
.brand-points{
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--sp-2);
}
.brand-points li{
	display: flex;
	align-items: center;
	gap: 9px;
	font-size: var(--fs-sm);
	letter-spacing: 0.06em;
	color: var(--ink-500);
}
.brand-points li::before{
	content: "";
	flex-shrink: 0;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: var(--blue-300) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232b3a45' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E") center / 10px 10px no-repeat;
}


/* ========================== §4 表单区 ==========================
   居中由 .form-side 负责（flex + center），.card 只管内容和宽度。⚠️ 别把 margin:auto 和 flex 混用，窗口一变窄就歪。 */
.form-side{
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--sp-6) var(--sp-5);
}

.card{
	width: 100%;
	max-width: 380px;     /* 380px 是舒适上限，太宽眼睛要左右扫 */
}

/* ---------- 4.1 卡片头 ---------- */
.card-head{ margin-bottom: var(--sp-5); }

/* 眉标：微型拉丁字 + 拖尾发丝线（同首页 .des-eyebrow）*/
.card-eyebrow{
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 var(--sp-2);
	font-family: var(--font-display);
	font-size: var(--fs-xs);
	font-weight: 500;
	letter-spacing: 0.24em;
	color: var(--ink-500);
}
.card-eyebrow::after{
	content: "";
	width: 46px;
	height: 1px;
	flex-shrink: 0;
	background-color: var(--blue-300);
}

.card-title{
	margin: 0;
	font-size: var(--fs-2xl);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.06em;
	color: var(--ink-900);
}
.card-sub{
	margin: 6px 0 0;
	font-size: var(--fs-base);
	color: var(--ink-500);
}

/* ---------- 4.2 字段 ---------- */
.form{
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
}

.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);
}

/* 输入框外面的壳：图标 + input。⚠️ 边框画在壳上、input 全清干净 —— 点图标附近也能聚焦，聚焦时整个壳一起亮（同首页顶栏搜索框）*/
.field-wrap{
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	height: 42px;
	padding: 0 12px;
	border-radius: var(--r-sm);
	background-color: var(--blue-50);
	border: 1px solid var(--blue-200);
	color: var(--ink-400);
	transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
		box-shadow var(--dur-fast) var(--ease);
}
.field-wrap svg{ width: 16px; height: 16px; flex-shrink: 0; }

/* :focus-within：input 聚焦时整个壳一起高亮 */
.field-wrap:focus-within{
	background-color: var(--surface);
	border-color: var(--blue-600);
	box-shadow: 0 0 0 3px rgba(29, 107, 166, 0.22);
	color: var(--ink-700);
}

.field-input{
	flex: 1;
	min-width: 0;              /* 不加长内容会顶破壳 */
	height: 100%;
	border: 0;
	background: transparent;
	outline: none;             /* 用外层 focus-within 代替 */
	font-family: inherit;      /* ⚠️ 表单控件不继承字体，不写会变宋体 */
	font-size: var(--fs-md);
	letter-spacing: inherit;
	color: var(--ink-900);
}
.field-input::placeholder{ color: var(--ink-400); }

/* 「显示密码」按钮，逻辑在 js/login.js（纯 CSS 改不了 input 的 type）*/
.field-eye{
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 30px;
	height: 30px;
	padding: 0;
	border: 0;
	border-radius: var(--r-xs);
	cursor: pointer;
	color: var(--ink-400);
	background: transparent;
	transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.field-eye svg{ width: 17px; height: 17px; }
.field-eye:hover{ color: var(--ink-700); background-color: var(--blue-100); }

/* ---------- 4.3 记住我 / 忘记密码 ---------- */
.form-row{
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	flex-wrap: wrap;
}

/* 复选框：藏起来的 input + 看得见的 span。⚠️ 不用 accent-color 染原生框（各浏览器大小/圆角/对勾都不同），自绘 16×16 方块最稳 */
.check{
	display: inline-flex;
	align-items: center;
	gap: 8px;
	cursor: pointer;
	font-size: var(--fs-sm);
	color: var(--ink-500);
	user-select: none;         /* 连点两下别把文字选中 */
}
.check:hover{ color: var(--ink-900); }

.check-input{
	position: absolute;
	opacity: 0;
	pointer-events: none;      /* 藏起来但保留键盘焦点（同首页 chip）*/
}

.check-box{
	position: relative;
	flex-shrink: 0;
	width: 16px;
	height: 16px;
	border-radius: var(--r-xs);
	background-color: var(--surface);
	border: 1px solid var(--blue-200);
	transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
/* 选中：填主色 + 画个深色对勾 */
.check-input:checked + .check-box{
	background-color: var(--blue-400);
	border-color: var(--blue-400);
}
.check-input:checked + .check-box::after{
	content: "";
	position: absolute;
	inset: 0;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232b3a45' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E") center / 11px 11px no-repeat;
}
.check-input:focus-visible + .check-box{
	box-shadow: 0 0 0 3px rgba(29, 107, 166, 0.35);
}

/* 「忘记密码？」：小号文字链接，不做成按钮 */
.link-quiet{
	font-size: var(--fs-sm);
	color: var(--ink-500);
	text-decoration: none;
	border-bottom: 1px solid transparent;
	transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.link-quiet:hover{ color: var(--blue-700); border-bottom-color: var(--blue-300); }

/* 错误提示条。⚠️ 下面那条 [hidden]{display:none} 不能省 —— 本规则写了 display:flex，会盖过 [hidden] 的 display:none */
.form-alert{
	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(--alert);
	background-color: var(--alert-soft);
	border: 1px solid var(--alert-line);
}
.form-alert svg{ width: 15px; height: 15px; flex-shrink: 0; margin-top: 3px; }
.form-alert[hidden]{ display: none; }

/* 成功提示：同一个容器换个配色，靠 JS 加 .form-alert--ok 这个修饰类。
   ⚠️ 只在 color / background / border 上覆盖，display 和 [hidden] 那条规则仍然有效 */
.form-alert--ok{
	color: var(--ok);
	background-color: var(--ok-soft);
	border-color: var(--ok-line);
}

/* 提示条出现时淡入 + 微微下落。
   ⚠️ 选择器写 :not([hidden]) —— 隐藏时是 display:none，动画不跑空转；
      直接写 .form-alert 的话，元素一隐藏动画就被重置，下次显示有时会「不播」 */
.form-alert:not([hidden]){
	animation: alertIn 0.24s ease-out both;
}
@keyframes alertIn{
	from{ opacity: 0; transform: translateY(-5px); }
	to  { opacity: 1; transform: none; }
}


/* ============================ §5 按钮 ============================ */
.btn{
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	width: 100%;
	height: 44px;
	padding: 0 16px;
	border-radius: var(--r-sm);
	cursor: pointer;
	font-family: inherit;
	font-size: var(--fs-md);
	font-weight: 600;
	letter-spacing: 0.1em;
	transition: background-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}

/* 主按钮：整页唯一的实心色
   ⚠️ 底压到 --blue-600 之后必须换白字：#2a72a6 上压深墨字对比度只剩 2.6:1，
      白字是 5.2:1 —— 这是整页最容易"一眼看到"的那个点，别让它糊。 */
.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); }

/* 加载中：禁用点击 + 变淡 + 露出转圈（JS 加/删 .is-loading）*/
.btn.is-loading{ pointer-events: none; opacity: 0.75; }
.btn-spinner{
	display: none;
	width: 15px;
	height: 15px;
	border-radius: 50%;
	border: 2px solid rgba(22, 34, 46, 0.22);
	border-top-color: var(--ink-900);
	animation: spin 0.7s linear infinite;
}
.btn.is-loading .btn-spinner{ display: block; }
@keyframes spin{ to{ transform: rotate(360deg); } }


/* ======================= §6 其它链接与提示 ======================= */

/* 「—— 或 ——」分隔线：文字夹在 ::before / ::after 画的两条线中间 */
.divider{
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	margin: var(--sp-5) 0;
	font-size: var(--fs-xs);
	letter-spacing: 0.18em;
	color: var(--ink-400);
}
.divider::before,
.divider::after{
	content: "";
	flex: 1;
	height: 1px;
	background-color: var(--line);
}

/* 第三方登录：一排等宽的描边按钮 */
.oauth{
	display: flex;
	gap: var(--sp-2);
}
.oauth-btn{
	flex: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	height: 40px;
	padding: 0 8px;
	border-radius: var(--r-sm);
	cursor: pointer;
	font-family: inherit;
	font-size: var(--fs-sm);
	letter-spacing: 0.06em;
	color: var(--ink-700);
	background-color: var(--surface);
	border: 1px solid var(--blue-200);
	transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease);
}
.oauth-btn svg{ width: 17px; height: 17px; flex-shrink: 0; }
.oauth-btn:hover{
	color: var(--ink-900);
	background-color: var(--blue-50);
	border-color: var(--blue-400);
}

/* 卡片底部的「还没有账号？去注册」*/
.card-foot{
	margin: var(--sp-5) 0 0;
	text-align: center;
	font-size: var(--fs-sm);
	color: var(--ink-500);
}
.card-foot a{
	color: var(--blue-700);
	font-weight: 600;
	text-decoration: none;
	border-bottom: 1px solid var(--blue-200);
	transition: border-color var(--dur-fast) var(--ease);
}
.card-foot a:hover{ border-bottom-color: var(--blue-500); }

/* 卡片左上角的「返回首页」 */
.back-home{
	display: inline-flex;
	align-items: center;
	gap: 5px;
	margin-bottom: var(--sp-4);
	font-size: var(--fs-sm);
	letter-spacing: 0.08em;
	color: var(--ink-500);
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}
.back-home svg{ width: 14px; height: 14px; }
.back-home:hover{ color: var(--blue-700); }


/* =========================== §7 入场动效 ===========================
   品牌区两块 → 卡片里的四块，间隔 60ms，整体不到半秒。
   ⚠️ 包在 prefers-reduced-motion 里：开了"减弱动态效果"的用户直接看终态。 */
@media (prefers-reduced-motion: no-preference){
	/* ⚠️ backwards 不是 both：both 带 forwards，会把 to 帧的 transform 永久钉住，
	   压过 §9 的 `.btn:active{ scale }`，按钮按下去没反应。理由详见 index.css §8。 */
	.brand-slogan,
	.brand-points,
	.card > *{
		animation: lg-rise var(--dur-slow) var(--ease) backwards;
	}
	.brand-slogan{ animation-delay: 60ms; }
	.brand-points{ animation-delay: 140ms; }

	/* .card 的直接子元素有 4 个：返回链接 / 卡片头 / 表单 / 底部 */
	.card > *:nth-child(1){ animation-delay: 40ms; }
	.card > *:nth-child(2){ animation-delay: 100ms; }
	.card > *:nth-child(3){ animation-delay: 160ms; }
	.card > *:nth-child(4){ animation-delay: 220ms; }
}

@keyframes lg-rise{
	from{ opacity: 0; transform: translateY(10px); }
	to{ opacity: 1; transform: none; }
}


/* ============================ §8 响应式 ============================
   两档：900 / 620。
   ⚠️ 手机档用 flex-direction: column 不用 display:none —— 品牌区是这页唯一的"情绪"，砍掉就只剩光秃秃的表格 */
@media (max-width: 900px){
	.page{ flex-direction: column; }

	/* 品牌区从"半屏舞台"收成"顶部横幅" */
	.brand{
		flex: none;
		gap: var(--sp-4);
		padding: var(--sp-5);
		border-right: 0;
		border-bottom: 1px solid var(--line-blue);
	}
	.brand-logo{ width: 104px; }
	.brand-slogan h2{ font-size: var(--fs-2xl); }
	.brand-slogan p{ margin-top: var(--sp-2); }
	.brand-points{ display: none; }      /* 宽度优先给表单 */
	.brand::after{ display: none; }      /* 底部光晕在横幅里显得脏 */

	.form-side{ padding: var(--sp-5) var(--sp-4) var(--sp-6); }
	.card{ max-width: 420px; }
}

@media (max-width: 620px){
	.brand{ padding: var(--sp-4); gap: var(--sp-3); }
	.brand-logo{ width: 92px; }
	.brand-slogan h2{ font-size: var(--fs-xl); }
	.brand-slogan p{ font-size: var(--fs-sm); }

	.form-side{ padding: var(--sp-4) var(--sp-3) var(--sp-5); }
	.card-title{ font-size: var(--fs-xl); }

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


/* ================== §9 果冻交互（全站统一按压回弹） ==================
   ⚠️ 两条规则必须成对：基础态用过冲曲线 --ease-q（松手才弹），
      :active 改用 --dur-press + --ease（按下跟手，不过冲）。
   ⚠️ 不给 .brand / .card 加 scale —— 大块缩放像整页在抖。 */

.btn, .oauth-btn, .field-eye, .check{
	transition:
		background-color var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease),
		transform var(--dur) var(--ease-q);
}

.btn:active, .oauth-btn:active, .field-eye:active, .check: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),
		transform var(--dur-press) var(--ease);
}

/* 30×30 的「显示密码」眼睛：小圆键，缩狠一点 */
.field-eye:active{ transform: translateY(0) scale(0.88); }


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

/* ⚠️ 开了「减弱动态效果」时关掉位移/缩放/淡入。用 1ms 不用 0s。 */
@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;
	}
	.btn:active, .oauth-btn:active, .field-eye:active, .check:active{ transform: none !important; }

	/* ⚠️ 例外：加载转圈必须继续转。它不表达"动效"，而是在说"正在等" ——
	   1ms 定住会让用户以为卡死了。它是这一节里唯一保留的运动。 */
	.btn-spinner{ animation-duration: 0.7s !important; animation-iteration-count: infinite !important; }
}

/* 触摸设备：30×30 的眼睛键撑到 44px 热区，视觉尺寸不变 */
@media (pointer: coarse){
	.field-eye{ position: relative; }
	.field-eye::after{
		content: "";
		position: absolute;
		top: 50%;
		left: 50%;
		width: max(100%, 44px);
		height: max(100%, 44px);
		transform: translate(-50%, -50%);
	}
}
