/* Login shares the application's palette and ambient renderer.
   2026-09-21 方案 A「去框」：表单直接浮在光幕上——没有卡片、没有边框、没有磨砂底；
   输入框只剩一条底线，聚焦时底线从左到右亮成薄荷色；表单左侧一条细信号线，跟主界面回答行首那条同源；
   按钮沿用主界面"页面上唯一的实心控件"的做法（中性实心，不靠颜色喊）。 */
body.login-body {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    height: auto;
    overflow: auto;
    margin: 0;
    padding: 0 clamp(24px, 6vw, 96px);
    isolation: isolate;
}
.login-body *, .login-body *::before, .login-body *::after { box-sizing: border-box; }
.login-body .ambient-background::after {
    background: radial-gradient(ellipse at 75% 50%, color-mix(in srgb, var(--bg) 46%, transparent), transparent 65%);
}
.login-brand { display: flex; align-items: center; gap: 12px; padding: 34px 0; color: var(--text-heading); }
.login-brand > img { width: 32px; height: 32px; filter: var(--logo-lift); }
.login-brand > span { display: flex; align-items: center; font-size: 23px; font-weight: 600; letter-spacing: -.6px; }
.login-brand-divider { height: 16px; width: 1px; margin: 0 16px; background: var(--border-strong); }
.login-brand-name { font-size: 13px; font-weight: 400; letter-spacing: 2px; color: var(--text-secondary); }
.login-layout { width: 100%; max-width: 1170px; margin: auto; display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: clamp(40px, 7vw, 120px); align-items: center; padding: 44px 0 64px; }

/* 标语用楷书（2026-09-21 用户点名"帅气的楷书体"）：马善政楷书，SIL OFL，许可证在 fonts/mashanzheng-OFL.txt。
   只子集了标语 + 各表单标签这 37 个字（14 KB），改标语或标签文字要重新切（fonttools --text-file）；退路是本机的华文楷体/楷体。 */
@font-face {
    font-family: 'Ma Shan Zheng Tagline';
    src: url('/fonts/mashanzheng-tagline.woff2') format('woff2');
    /* 声明成 400–700 一整段：标签用 700 时直接用这张脸、浏览器不再合成加粗——这款字本来就是粗笔，
       再叠假粗会糊；只有退路的华文楷体（细）才会被合成加粗 */
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}
/* 标语整块上提（用户 2026-09-21：再往上一些）：第一行的上沿大致和右边第一个输入框平齐，不按表单中心对齐 */
.login-intro { padding-bottom: 20px; margin-top: -72px; }
.login-intro h1 { margin: 0; font-family: 'Ma Shan Zheng Tagline', 'STKaiti', 'KaiTi', 'DFKai-SB', serif; font-size: clamp(40px, 4.8vw, 66px); font-weight: 400; line-height: 1.34; letter-spacing: .04em; color: var(--text-heading); }

/* ---- 表单：无框 ---- */
.login-card { position: relative; width: 100%; padding: 6px 0 0 30px; animation: login-arrive 650ms var(--ease) both; }
/* 左侧信号线：上亮下隐，跟回答行首那条同一语言 */
.login-card::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; border-radius: var(--radius-pill); background: linear-gradient(180deg, var(--accent) 0%, color-mix(in srgb, var(--accent) 40%, transparent) 55%, transparent 100%); }
.login-head { margin-bottom: 28px; }
.login-card[data-mode="login"] .login-head { display: none; }   /* 标语已经在说话了，登录态不再多一个标题 */
.login-title { margin: 0; font-size: 22px; font-weight: 500; letter-spacing: -.3px; color: var(--text-heading); }
.login-subtitle { margin: 10px 0 0; font-size: 13px; line-height: 1.7; color: var(--text-muted); }
.login-form { display: flex; flex-direction: column; gap: 26px; }
.login-body [hidden] { display: none !important; }
.login-note { margin: 0; font-size: 12px; line-height: 1.8; color: var(--text-muted); }
.login-note a { color: var(--link); text-underline-offset: 4px; }

/* 底线式输入框：字写在线上，标签小字在线上方；聚焦时薄荷线从左到右亮起 */
.login-field { position: relative; display: flex; flex-direction: column; gap: 4px; font-size: 12px; letter-spacing: .08em; color: var(--text-secondary); transition: color 160ms ease; }
/* 标签也用楷书、放大、偏黑（用户 2026-09-21："字太小了，也改为帅气楷体偏黑那种"）：
   这款字只有一个字重，"偏黑"靠合成加粗 + 半像素描边；字体子集连标签的字一起切进去了 */
.login-field > span { font-family: 'Ma Shan Zheng Tagline', 'STKaiti', 'KaiTi', 'DFKai-SB', serif; font-size: 19px; font-weight: 700; letter-spacing: .1em; color: var(--text-primary); -webkit-text-stroke: .25px currentColor; }
.login-field:focus-within { color: var(--text-primary); }
.login-field input { width: 100%; min-width: 0; min-height: 44px; padding: 6px 0 10px; border: 0; border-bottom: 1px solid var(--border-strong); border-radius: 0; background: transparent; color: var(--text-primary); font: inherit; font-size: 17px; letter-spacing: 0; outline: none; transition: border-color 160ms ease; }
.login-field input:hover { border-bottom-color: var(--text-faint); }
.login-field input::placeholder { color: transparent; }
.login-field input:autofill { box-shadow: 0 0 0 100px var(--bg) inset; -webkit-text-fill-color: var(--text-primary); }
.login-field::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform 260ms var(--ease-soft); }
.login-field:focus-within::after { transform: scaleX(1); }

/* 主按钮：薄荷淡染的药丸（用户 2026-09-21："黑色太突兀"）——底色是主题薄荷的淡染、描边同色，
   跟主界面的淡染控件同一套 token，四个主题各自跟着 --accent 走；悬停染深一档 */
.login-submit { display: inline-flex; align-items: center; justify-content: center; align-self: flex-start; min-height: 54px; margin-top: 24px; padding: 0 40px; border: 1px solid var(--accent-tint-border); border-radius: 46% 54% 42% 58% / 58% 40% 60% 42%; background: var(--accent-tint); color: var(--text-heading); font: inherit; font-size: 14px; font-weight: 600; letter-spacing: .08em; cursor: pointer; transition: background 160ms ease, border-color 160ms ease, box-shadow 200ms ease, opacity 160ms ease; }
.login-submit:hover:not(:disabled) { background: var(--accent-tint-hover); border-color: var(--accent); box-shadow: 0 10px 32px var(--accent-dim); border-radius: 54% 46% 58% 42% / 42% 58% 44% 56%; }
.login-submit:disabled { opacity: .6; cursor: wait; }
/* 处理中：文字右边转一个小圈（箭头 2026-09-21 按用户要求去掉了，空闲态按钮上只有字） */
/* 处理中：按钮上只剩一个转圈（文字撤掉，宽度由 JS 钉住） */
.login-submit.is-busy { cursor: wait; }
.login-submit.is-busy::after { content: ''; width: 16px; height: 16px; border: 1.5px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: login-spin .8s linear infinite; }
.login-actions { display: flex; align-items: center; gap: 18px; margin-top: 8px; }
.login-actions .login-submit { margin-top: 0; }
.login-secondary { min-height: 48px; padding: 0 6px; border: 0; background: transparent; color: var(--text-muted); font: inherit; font-size: 13px; cursor: pointer; transition: color 160ms ease; }
.login-secondary:hover { color: var(--text-primary); }
.login-body button:focus-visible, .login-body a:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
/* 出错提示（2026-09-21）：一行小字贴在按钮上方，前面一颗小红点，淡入上浮；同时表单轻抖一下、底线变红 */
.login-error, .login-form > .login-error { display: flex; align-items: center; gap: 8px; margin: -8px 0 0; color: var(--danger-text); font-size: 13px; letter-spacing: .02em; line-height: 1.6; overflow-wrap: anywhere; animation: login-error-in 260ms var(--ease-soft) both; }
.login-error::before { content: ''; flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%; background: var(--danger-text); box-shadow: 0 0 0 3px var(--danger-dim); }
.login-form.has-error { animation: login-shake 340ms var(--ease-soft); }
.login-form.has-error .login-field input { border-bottom-color: var(--danger-border-soft); }
@keyframes login-error-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes login-shake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-4px); } 45% { transform: translateX(3px); } 70% { transform: translateX(-2px); } }

/* 出场：整块淡入之后，字段和按钮错开一点点时间抬起来——克制，不炫 */
.login-form > * { animation: login-rise 520ms var(--ease-soft) both; }
.login-form > :nth-child(2) { animation-delay: 70ms; }
.login-form > :nth-child(3) { animation-delay: 140ms; }
.login-form > :nth-child(4) { animation-delay: 210ms; }
.login-form > :nth-child(5) { animation-delay: 280ms; }
@keyframes login-arrive { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes login-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes login-spin { to { transform: rotate(360deg); } }
/* 不规则图形（用户 2026-09-21）：八值圆角画出的有机形，9 秒一轮慢慢呼吸，悬停换一个姿态；
   跟出场动画写在同一条声明里，否则后面 .login-form > * 那条会把它盖掉 */
@keyframes login-blob { 0% { border-radius: 46% 54% 42% 58% / 58% 40% 60% 42%; } 50% { border-radius: 56% 44% 52% 48% / 44% 58% 42% 56%; } 100% { border-radius: 40% 60% 48% 52% / 52% 44% 56% 48%; } }
.login-form > .login-submit, .login-actions .login-submit { animation: login-rise 520ms var(--ease-soft) both, login-blob 9s ease-in-out 700ms infinite alternate; transition: background 160ms ease, border-color 160ms ease, box-shadow 200ms ease, border-radius 600ms var(--ease-soft), opacity 160ms ease; }

@media (max-width: 900px) { .login-layout { gap: 36px; grid-template-columns: minmax(0, 1fr) 340px; } .login-intro { margin-top: -48px; } .login-intro h1 { font-size: 40px; letter-spacing: .04em; } }
@media (max-width: 720px) { body.login-body { padding: 0 24px; } .login-brand { padding: 24px 0; } .login-layout { grid-template-columns: minmax(0, 1fr); max-width: 410px; gap: 34px; padding: 22px 0 40px; } .login-intro { padding: 0; margin-top: 0; } .login-intro h1 { font-size: 38px; line-height: 1.3; } .login-card { padding-left: 22px; } .login-field input { font-size: 16px; } .login-submit { align-self: flex-start; } }
@media (prefers-reduced-motion: reduce) { .login-body *, .login-body *::after { animation: none !important; transition: none !important; } }
@media (forced-colors: active) { .login-field input { border-bottom: 1px solid CanvasText; } .login-submit { border: 1px solid CanvasText; background: ButtonFace; color: ButtonText; } .login-card::before { background: CanvasText; } }

/* 登录成功（2026-09-21）：按钮变成功态（薄荷实底 + 对勾 + 已登录），字段淡出下沉、标语上浮变淡，
   JS 等这段放完再跳；以前不管成败都把按钮复原成"登录"，跳转前那一下就闪出"登录" */
.login-submit.is-done, .login-submit.is-done:disabled { opacity: 1; cursor: default; background: var(--accent); border-color: var(--accent); color: var(--bg); box-shadow: 0 10px 32px var(--accent-glow); }
/* 成功：按钮上只剩一个对勾 */
.login-submit.is-done::before { content: ''; width: 7px; height: 13px; margin-top: -4px; border: solid currentColor; border-width: 0 2.2px 2.2px 0; transform: rotate(45deg); animation: login-check 260ms var(--ease-soft) both; }
@keyframes login-check { from { opacity: 0; transform: rotate(45deg) scale(.6); } to { opacity: 1; transform: rotate(45deg) scale(1); } }
.login-submit.is-done::after { content: none; }
.login-layout.is-leaving .login-field, .login-layout.is-leaving .login-error, .login-layout.is-leaving .login-note { animation: login-sink 320ms var(--ease-soft) forwards; }
.login-layout.is-leaving .login-field:nth-of-type(2) { animation-delay: 50ms; }
/* 按钮不跟着沉：对勾要让人看清，它由跨页面过渡带走 */
.login-layout.is-leaving .login-secondary { animation: login-sink 320ms var(--ease-soft) 120ms forwards; }
.login-layout.is-leaving .login-intro { animation: login-lift 420ms var(--ease-soft) forwards; }
.login-layout.is-leaving .login-card::before { opacity: .4; transition: opacity 300ms ease; }
/* 退场不清空页面（2026-09-21 用户截图：动画放完主页面还没画出来，只剩一枚对勾在空页面上）：
   字段和标语只压暗、不消失，页面是"定住等进门"；主页面画出来那一刻由跨页面过渡接手 */
@keyframes login-sink { to { opacity: .35; transform: translateY(6px); } }
@keyframes login-lift { to { opacity: .45; transform: translateY(-8px); } }
