/* 首屏共享最小样式。其余共享源按原层叠顺序编入两条 Presentation 管线。 */
@layer business {
/* ============================================================================
   Login Overlay - 登录遮罩（强制登录页）
   ============================================================================ */

#login-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-takeover);
  background: var(--bg-void);
  display: flex;
  align-items: center;
  justify-content: center;
}

#login-overlay.hidden {
  display: none;
}

/* 卡片宽度按模式变：登录模式在微信启用时是两列（密码 | 微信），
 * setup / register 仍是单列。窄屏由页尾 media query 收回单列。 */
.login-box {
  background: var(--bg-card);
  border: 1px solid var(--border-color-default);
  box-shadow: var(--paper-shadow);
  border-radius: var(--radius-md);
  padding: 40px 36px;
  width: min(320px, 90vw);
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* /health 返回后才知道微信是否启用，卡片会从单列展开成两列 —— 让它过渡而非跳变 */
  transition: width var(--duration-normal) var(--ease-out);
}

.login-box[data-mode="login"][data-wechat="on"] {
  width: min(700px, 92vw);
}

.login-box[data-mode="register"] {
  width: min(400px, 92vw);
}

.login-logo {
  text-align: center;
  font-size: var(--icon-size-2xl);
  color: var(--color-primary);
  margin-bottom: 4px;
}
.login-logo svg {
  width: 48px;
  height: 48px;
  fill: currentcolor;
}

.login-title {
  text-align: center;
  font-family: var(--font-main);
  font-size: var(--font-size-2xl);
  font-weight: 700;
  color: var(--text-main);
  letter-spacing: 1px;
  margin-bottom: 8px;
}

#login-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
}

#login-fields,
#setup-fields .setup-field-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.login-box input[type="text"],
.login-box input[type="password"] {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-input);
  border: 1px solid var(--border-color-default);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-lg);
  color: var(--text-main);
  font-family: var(--font-main);
  transition: border-color 0.2s, box-shadow 0.2s;
  box-sizing: border-box;
}

.login-box input::placeholder {
  color: var(--text-muted);
}

.login-box input:focus-visible {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: var(--shadow-focus);
}

#overlay-error {
  color: var(--color-secondary);
  font-size: var(--font-size-md);
  text-align: center;
  min-height: 1.2em;
}

#overlay-btn-login {
  background: var(--color-primary);
  color: var(--text-on-dark);
  border: 1px solid var(--color-primary);
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 600;
  font-size: var(--font-size-lg);
  font-family: var(--font-main);
  transition: all 0.2s;
  width: 100%;
  margin-top: 4px;
}

#overlay-btn-login:hover {
  background: var(--color-primary-hover);
  box-shadow: var(--shadow-btn-primary);
}

#overlay-btn-login:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

#overlay-btn-setup {
  background: transparent;
  color: var(--text-muted);
  border: 1px dashed var(--border-color-default);
  padding: 9px 16px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 500;
  font-size: var(--font-size-md);
  font-family: var(--font-main);
  transition: all 0.2s;
  width: 100%;
}

#overlay-btn-setup:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

#overlay-btn-setup:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

#overlay-btn-register {
  background: var(--color-primary);
  color: var(--text-on-dark);
  border: 1px solid var(--color-primary);
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 600;
  font-size: var(--font-size-lg);
  font-family: var(--font-main);
  transition: all 0.2s;
  width: 100%;
}

#overlay-btn-register:hover {
  background: var(--color-primary-hover);
  box-shadow: var(--shadow-btn-primary);
}

#overlay-btn-register:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

#overlay-btn-back-to-login {
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border-color-default);
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-weight: 500;
  font-size: var(--font-size-lg);
  font-family: var(--font-main);
  transition: all 0.2s;
  width: 100%;
}

#overlay-btn-back-to-login:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* 本地有 token 时，首次绘制前直接隐藏登录页、显示应用，避免闪烁 */
html.has-token #login-overlay { display: none; }
html.has-token #app { display: flex; }

/* ── 桌面版下载链接 ─────────────────────────────────────── */

.desktop-downloads {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border-color-default);
  text-align: center;
}

.desktop-downloads-title {
  font-size: var(--font-size-sm);
  color: var(--text-muted);
  margin-bottom: 10px;
}

.desktop-downloads-links {
  display: flex;
  gap: 8px;
  justify-content: center;
}

.desktop-dl-btn {
  text-decoration: none;
  font-size: var(--font-size-sm);
}

/* 注册面板 */
#register-fields { display: flex; flex-direction: column; gap: 10px; }
/* position: relative —— 给 .suggestions-dropdown（absolute）当定位上下文 */
#register-fields .login-field { margin-bottom: 0; position: relative; }
#register-fields .login-field label { display: block; font-size: var(--font-size-md); margin-bottom: 4px; color: var(--text-secondary); }
#register-fields .login-field input { width: 100%; padding: 8px 12px; }
.suggestions-dropdown {
  position: absolute;
  width: 100%;
  max-height: 200px;
  overflow-y: auto;
  background: var(--bg-card);
  border: 1px solid var(--border-color-default);
  border-radius: var(--radius-md);
  list-style: none;
  padding: 0;
  margin: 0;
  z-index: var(--z-dropdown);
  box-shadow: var(--shadow-card-hover);
}
.suggestions-dropdown li {
  padding: 8px 12px;
  cursor: pointer;
  font-size: var(--font-size-md);
}
.suggestions-dropdown li:hover { background: rgba(139, 119, 90, 0.08); }
.suggestions-dropdown li .tenant-fullname { color: var(--text-secondary); font-size: var(--font-size-sm); margin-left: 6px; }
#register-tenant-search { position: relative; }
.switch-auth-mode { text-align: center; margin-top: 12px; font-size: var(--font-size-md); color: var(--text-secondary); }
.switch-auth-mode a { color: var(--color-primary); cursor: pointer; text-decoration: none; }
.switch-auth-mode a:hover { text-decoration: underline; }
#register-error { margin-top: 8px; }
.error-text { color: var(--color-danger); font-size: var(--font-size-md); }

/* ── 登录方式布局：宽屏两列并置，窄屏分段切换 ───────────────────
   微信控件本身的样式在 shell/wechat-login.css（三处共用），这里只管排布。 */

.login-methods {
  display: flex;
  align-items: stretch;
  gap: var(--space-6);
  width: 100%;
}

.login-method-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

.login-method-col--password {
  flex: 1;
}

.login-method-col--wechat {
  flex: 0 0 auto;
  align-items: center;
}

.login-method-title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-md);
  font-weight: 600;
  color: var(--text-secondary);
}

.login-method-title i {
  font-size: var(--icon-size-md);
  color: var(--color-success-text);
}

/* 已并入 `ui-divider--vertical --label --stretch`；只留 flex 定位 */
.login-method-divider {
  flex: 0 0 auto;
}

/* 分段控件只在窄屏出现（宽屏两列都可见，无须切换） */
.login-method-tabs {
  display: none;
  gap: var(--space-1);
  padding: var(--space-1);
  border-radius: var(--radius-md);
  background: var(--bg-panel);
}

.login-method-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px; /* 只在窄屏（触摸）出现，命中区按触摸标准给 */
  padding: var(--space-3) var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-main);
  font-size: var(--font-size-md);
  cursor: pointer;
}

.login-method-tab.is-active {
  background: var(--bg-card);
  color: var(--color-primary);
  font-weight: 600;
  box-shadow: var(--shadow-card);
}

.login-method-tab i {
  font-size: var(--icon-size-sm);
}

/* 各模式下谁出场，一律由这里判定 —— JS 只改 data-mode / data-wechat，
   不再写内联 display（内联优先级高于 media query，两边都写必然打架）。 */
.login-box[data-wechat="off"] .login-method-col--wechat,
.login-box[data-wechat="off"] #register-wechat,
.login-box[data-mode="setup"] .login-method-col--wechat,
.login-box[data-mode="setup"] .login-method-tabs,
.login-box[data-mode="register"] .login-methods {
  display: none;
}

/* 只剩一种登录方式时，列标题与「或」都是噪音 */
.login-box[data-wechat="off"] .login-method-title,
.login-box[data-wechat="off"] .login-method-divider,
.login-box[data-mode="setup"] .login-method-title,
.login-box[data-mode="setup"] .login-method-divider {
  display: none;
}

/* 项目统一移动断点 768px。⚠️ 改这个值要同步 chat.js 里的 matchMedia ——
   窄屏一次只建一个 attempt，两处判断必须一致。 */
@media (max-width: 768px) {
  .login-box {
    /* 微信 iframe 需要约 300px 净宽，内边距太大会把它挤到裁切 */
    padding: 32px 18px;
  }

  .login-box[data-mode="login"][data-wechat="on"] {
    width: min(380px, 94vw);
  }

  .login-methods {
    flex-direction: column;
    gap: var(--space-5);
  }

  .login-method-divider {
    display: none;
  }

  .login-method-tabs:not([hidden]) {
    display: flex;
  }

  /* 窄屏一次只展示一种方式；宽屏 data-method 不参与布局 */
  .login-methods[data-method="wechat"] .login-method-col--password,
  .login-methods[data-method="password"] .login-method-col--wechat {
    display: none;
  }
}

}
@layer business {
/* ============================================================================
   微信登录控件 —— 登录页 / 注册面板 / 账户绑定弹窗三处共用
   ============================================================================
   官方 iframe（open.weixin.qq.com）是跨域的：内部 DOM 与样式都改不了，能控制的
   只有 WxLogin 参数（stylelite / color_scheme / fast_login）和这里的外层盒子。
   由此推出两条硬约束，改这段样式前先读：

   ① **不写死 iframe 高度**。同一个容器要装两种形态：
      二维码（新版 UI 官方建议扫码区 ≥220×220），以及微信 PC 快捷登录控件
      （Windows 微信 3.9.11+ / Mac 4.0.0+ 客户端已登录时直接给「使用当前微信
      登录」，比二维码矮得多）。曾经写死 240×300 —— 二维码被裁掉两边。

   ② **状态表达全靠我们自己的蒙层**，不靠改一行小字。iframe 内部我们看不见，
      「已扫码待确认 / 已过期 / 失败」必须盖在它上面说清楚。
   ============================================================================ */

.login-wechat-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

.login-wechat-frame {
  position: relative;
  width: 320px;
  max-width: 100%;
  min-height: 320px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-color-subtle);
  border-radius: var(--radius-md);
  background: var(--wechat-qr-canvas);
  overflow: hidden;
}

/* WxLogin 把 iframe 注入这个容器（按 id 定位，故它必须有 id） */
.login-wechat-qr {
  display: grid;
  place-items: center;
}

/* 只去边框、禁止横向溢出；高度交给 iframe 自身，容器用 min-height 兜底 */
.login-wechat-qr iframe {
  display: block;
  border: 0;
  max-width: 100%;
}

/* ── 加载骨架：与二维码同尺寸，避免 iframe 就绪瞬间卡片高度跳变 ── */

.login-wechat-skeleton {
  position: absolute;
  inset: 0;
  display: none;
  background: linear-gradient(100deg, var(--bg-void) 30%, var(--bg-panel) 50%, var(--bg-void) 70%);
  background-size: 220% 100%;
  animation: login-wechat-shimmer 1.2s linear infinite;
}

.login-wechat-frame[data-status="loading"] .login-wechat-skeleton {
  display: block;
}

@keyframes login-wechat-shimmer {
  from { background-position: 120% 0; }
  to   { background-position: -20% 0; }
}

/* ── 状态蒙层 ── */

.login-wechat-mask {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-6);
  text-align: center;
  background: color-mix(in srgb, var(--bg-card) 94%, transparent);
}

.login-wechat-frame[data-status="scanned"] .login-wechat-mask[data-mask="scanned"],
.login-wechat-frame[data-status="verified"] .login-wechat-mask[data-mask="verified"],
.login-wechat-frame[data-status="expired"] .login-wechat-mask[data-mask="expired"],
.login-wechat-frame[data-status="failed"] .login-wechat-mask[data-mask="failed"] {
  display: flex;
}

.login-wechat-mask-icon {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-circle);
  font-size: var(--icon-size-lg);
}

.login-wechat-mask[data-mask="scanned"] .login-wechat-mask-icon {
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

.login-wechat-mask[data-mask="verified"] .login-wechat-mask-icon {
  background: var(--color-success-soft);
  color: var(--color-success-text);
}

.login-wechat-mask[data-mask="expired"] .login-wechat-mask-icon {
  background: var(--color-warning-soft);
  color: var(--color-warning-text);
}

.login-wechat-mask[data-mask="failed"] .login-wechat-mask-icon {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

.login-wechat-mask-title {
  font-size: var(--font-size-lg);
  font-weight: 600;
  color: var(--text-main);
}

.login-wechat-mask-desc {
  font-size: var(--font-size-md);
  color: var(--text-muted);
  max-width: 240px;
}

.login-wechat-mask-desc:empty {
  display: none;
}

/* ── 状态行与提示 ── */

.login-wechat-status {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 1.2em;
  font-size: var(--font-size-md);
  color: var(--text-secondary);
  text-align: center;
}

.login-wechat-dot {
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: var(--radius-circle);
  background: var(--color-success);
}

.login-wechat-status[data-tone="waiting"] .login-wechat-dot {
  animation: login-wechat-breathe 1.6s ease-in-out infinite;
}

.login-wechat-status[data-tone="warning"] .login-wechat-dot {
  background: var(--color-warning);
}

.login-wechat-status[data-tone="danger"] .login-wechat-dot {
  background: var(--color-danger);
}

@keyframes login-wechat-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}

.login-wechat-hint {
  max-width: 300px;
  font-size: var(--font-size-sm);
  color: var(--text-muted);
  text-align: center;
}

/* ============================================================================
   Desktop 授权入口 —— 拉起系统浏览器，不在应用内渲染微信控件
   ----------------------------------------------------------------------------
   与上面的 frame 是并存的两个形态，同一份 index.html 里都在，显隐**不需要新增规则**：
   platform-bootstrap.js 设 html[data-platform=electron|web]，platform.css 按
   [data-platform-only] 施加 display:none —— frame 标 web，launch 标 desktop。

   这里没有跨域 iframe，所以不用蒙层：状态就是自己的 DOM，按 data-status 换文案。
   也因此不能复用上面 frame 的 320×320 二维码画布尺寸（那是官方扫码区的硬约束）。
   ============================================================================ */

.login-wechat-launch {
  width: 320px;
  max-width: 100%;
  min-height: 264px;  /* 与密码列高度相当，避免登录卡片两列高低差过大 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-6);
  text-align: center;
  border: 1px solid var(--border-color-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-card);
}

.login-wechat-launch-icon {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-circle);
  font-size: var(--icon-size-lg);
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

.login-wechat-launch-title {
  font-size: var(--font-size-lg);
  font-weight: 600;
  color: var(--text-main);
}

.login-wechat-launch-desc {
  max-width: 244px;
  font-size: var(--font-size-md);
  color: var(--text-muted);
}

.login-wechat-launch-desc:empty {
  display: none;
}

.login-wechat-launch-actions {
  display: flex;
  gap: var(--space-3);
}

/* ── 各状态下谁出场：JS 只改 data-status ── */

.login-wechat-launch[data-status="idle"] .login-wechat-launch-actions,
.login-wechat-launch[data-status="idle"] .login-wechat-status,
.login-wechat-launch[data-status="waiting"] .login-wechat-launch-primary,
.login-wechat-launch[data-status="authorizing"] .login-wechat-launch-primary,
.login-wechat-launch[data-status="authorizing"] .login-wechat-launch-actions,
.login-wechat-launch[data-status="verified"] .login-wechat-launch-primary,
.login-wechat-launch[data-status="verified"] .login-wechat-launch-actions,
.login-wechat-launch[data-status="done"] .login-wechat-launch-primary,
.login-wechat-launch[data-status="done"] .login-wechat-launch-actions,
.login-wechat-launch[data-status="expired"] .login-wechat-launch-actions,
.login-wechat-launch[data-status="failed"] .login-wechat-launch-actions {
  display: none;
}

.login-wechat-launch[data-status="verified"] .login-wechat-launch-icon,
.login-wechat-launch[data-status="done"] .login-wechat-launch-icon {
  background: var(--color-success-soft);
  color: var(--color-success-text);
}

.login-wechat-launch[data-status="expired"] .login-wechat-launch-icon {
  background: var(--color-warning-soft);
  color: var(--color-warning-text);
}

.login-wechat-launch[data-status="failed"] .login-wechat-launch-icon {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

}
@layer business {
  .presentation-refresh {
    position: fixed;
    right: var(--space-4);
    bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
    z-index: var(--z-toast);
    display: flex;
    max-width: min(420px, calc(100vw - 2 * var(--space-4)));
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border-color-default);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    color: var(--text-main);
    box-shadow: var(--shadow-popover);
  }
}

/*# sourceMappingURL=core.bundle.css.map */