  :root {
    /* ==== 数值真源：ui/IMPLEMENTATION-SPEC.md + ui/design-tokens.css（2026-07-25 Final 1.0）==== */
    /* 颜色（严格照 ui/COLOR-SPEC.md + design-tokens.css，零容差） */
    --bg: #f8f9fb;                /* qd-background（第5批更新为更浅：rgb(248,249,251)） */
    --card: #ffffff;
    --surface-2: #f8fafc;         /* qd-neutral-50：表头/拖放区/代码块/图标钮 hover */
    --neutral-100: #f3f4f6;       /* 禁用输入/中性块底 */
    --neutral-pressed: #f1f5f9;   /* 图标钮 pressed */
    --primary: #2563eb;
    --primary-dark: #1d4ed8;      /* brand hover */
    --primary-pressed: #1e40af;
    --primary-tint: #eff6ff;      /* brand soft：信息/隐私提示、tab 选中 */
    --primary-tint-pressed: #dbeafe;
    --primary-soft-border: #bfdbfe;
    --text: #1f2937;
    --text-strong: #111827;
    --muted: #6b7280;             /* text secondary */
    --text-tertiary: #9ca3af;
    --border: #e5e7eb;
    --divider: #eef2f7;
    --danger: #dc2626;
    --danger-tint: #fef2f2;
    --danger-tint-pressed: #fee2e2;
    --ok: #059669;
    --ok-tint: #ecfdf5;
    --ok-border: #a7f3d0;
    --warn: #d97706;
    --warn-tint: #fffbeb;
    --warn-border: #fde68a;
    --danger-button-border: #fca5a5;
    --file-pdf: #dc2626; --file-pdf-soft: #fee2e2;
    --file-archive: #ea580c; --file-archive-soft: #fff7ed;
    --file-text: #64748b; --file-text-soft: #f1f5f9;
    --file-video: #7c3aed; --file-video-soft: #f5f3ff;
    --progress: #60a5fa; --progress-track: #dbeafe;
    /* 间距（只用 4/8/12/16/24/32/48） */
    --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-6: 24px; --sp-8: 32px; --sp-12: 48px;
    /* 圆角：输入/按钮 12、banner 16、卡片 20、模态 24 */
    --r-sm: 12px; --r-md: 16px; --r-lg: 20px; --r-xl: 24px; --r-pill: 999px;
    /* 阴影（仅两级）+ focus ring */
    --sh-1: 0 8px 24px rgb(15 23 42 / 8%);
    --sh-2: 0 16px 40px rgb(15 23 42 / 12%);
    --focus-ring: 0 0 0 3px rgb(37 99 235 / 22%);
    --overlay: rgb(15 23 42 / 42%);
    /* 字号层级 */
    --fs-display: 32px; --fs-h1: 28px; --fs-h2: 20px; --fs-body: 16px; --fs-cap: 13px;
    /* 安全区（刘海 / Home 指示条）：**统一走这四个变量**，不要在别处直接写 env()。
       原因：`env(safe-area-inset-*)` 在桌面浏览器恒为 0，刘海类 bug 只能等真机暴露（实测吃过两次：
       底部 tab 栏盖住内容、使用说明标题叠到状态栏）。套一层变量后，开发预览台可以用
       `?safe=47,34` 直接把安全区模拟出来，在桌面上就能验。 */
    --safe-top: env(safe-area-inset-top);
    --safe-bottom: env(safe-area-inset-bottom);
    --safe-left: env(safe-area-inset-left);
    --safe-right: env(safe-area-inset-right);
    /* App 骨架固定尺寸 */
    --appbar-h: 56px; --tabbar-h: 64px;
    --bottom-nav-bg: rgb(255 255 255 / 96%);
    /* 代码块语义（真源：--qd-code-*） */
    --code-bg: #0f172a;
    --code-text: #e2e8f0;
    --code-border: #1e293b;
    --code-control: rgb(255 255 255 / 10%);
    --code-control-hover: rgb(255 255 255 / 16%);
  }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 16px calc(var(--tabbar-h) + var(--safe-bottom) + 16px);
  }
  /* ===== App 标题栏（56 高，左 QRDart 品牌 + 右设置圆钮；bg=页面背景、无阴影/边框）===== */
  .topbar {
    position: sticky; top: 0;
    align-self: stretch; width: 100%; box-sizing: border-box;
    display: flex; justify-content: space-between; align-items: center;
    min-height: calc(var(--appbar-h) + var(--safe-top));
    padding: var(--safe-top) 16px 0;
    background: var(--bg);
    z-index: 20;
  }
  /* 标题栏只保留品牌 + 使用说明（仅二维码页） + 设置钮，其它历史入口收进设置页 */
  .topbar > *:not(#appBarTitle):not(#settingsBtn):not(#helpBtn):not(.desktop-nav) { display: none !important; }
  #helpBtn { display: none; }
  body.qr-tab #helpBtn { display: inline-flex; }
  .topbar { min-height: calc(56px + var(--safe-top)); }
  #appBarTitle { display: inline-flex !important; align-items: center; gap: 8px; font-size: 20px; line-height: 28px; font-weight: 600; letter-spacing: -.01em; color: var(--text-strong); }
  #appBarTitle .brand-mark { width: 28px; height: 28px; flex: 0 0 auto; color: var(--primary); }
  /* 品牌是「回首页」的链接：去掉链接默认的下划线与蓝色，补 hover / 键盘焦点视觉（可点得看得出来） */
  #appBarTitle { text-decoration: none; cursor: pointer; border-radius: var(--r-sm); transition: opacity 120ms ease; }
  #appBarTitle:hover { opacity: .72; }
  #appBarTitle:active { opacity: .55; }
  #appBarTitle:focus-visible { outline: 0; box-shadow: var(--focus-ring); }
  #settingsBtn { display: inline-flex !important; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; border: 1px solid var(--border); background: var(--card); border-radius: 50%; box-shadow: 0 4px 12px rgb(15 23 42 / 6%); color: var(--text); cursor: pointer; }
  #settingsBtn svg { width: 24px; height: 24px; }
  #settingsBtn:active { background: var(--surface-2); }
  .topbar select {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: #fff;
    font-size: 13px;
    cursor: pointer;
  }
  .topbar .user-btn {
    padding: 6px 14px;
    font-size: 13px;
    border: 1px solid var(--border);
    background: #fff;
    border-radius: 8px;
    cursor: pointer;
  }
  .topbar .user-btn.primary { background: var(--primary); color: #fff; border-color: var(--primary); }
  .topbar .username { font-size: 13px; color: var(--muted); }
  /* 页面级大标题：随 tab 变化；标题区约 44 高，左对齐、与卡片同宽同左缘 */
  h1 { font-size: 24px; line-height: 32px; font-weight: 600; letter-spacing: -.01em; margin: 8px auto 0; max-width: 560px; width: 100%; text-align: left; box-sizing: border-box; color: var(--text-strong); }
  .subtitle { color: var(--muted); font-size: 13px; line-height: 18px; margin: 2px auto 16px; max-width: 560px; width: 100%; text-align: left; box-sizing: border-box; }
  .card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);       /* 20 */
    box-shadow: var(--sh-1);          /* 0 8px 24px rgb(15 23 42/8%) */
    padding: 16px;
    width: 100%;
    max-width: 560px;
    margin-bottom: 12px;              /* 相邻卡片 12 */
  }
  textarea {
    width: 100%;
    min-height: 110px;
    border: 1px solid #d1d5db;
    border-radius: var(--r-sm);
    padding: 11px 12px;
    font-size: 16px;
    line-height: 24px;
    resize: vertical;
    font-family: inherit;
  }
  textarea:focus { outline: 0; border-color: var(--primary); box-shadow: var(--focus-ring); }
  .drop {
    margin-top: 14px;
    border: 2px dashed var(--border);
    border-radius: 10px;
    padding: 22px;
    text-align: center;
    color: var(--muted);
    cursor: pointer;
    transition: border-color .15s, background .15s;
    display: block;
  }
  .drop.over { border-color: var(--primary); background: #eff6ff; }
  .drop input { display: none; }
  .drop .lock { font-size: 12px; margin-top: 4px; }
  .drop-sub { font-size: 12px; margin-top: 4px; }
  .field-note { font-size: 12px; margin: -4px 0 4px; } /* 勾选项下的说明：手机端也要显示（隐私提示） */
  .opts-row { display: flex; flex-wrap: wrap; gap: 0 18px; }
  .help-link { display: block; text-align: center; font-size: 13px; color: var(--primary); cursor: pointer; margin: 2px 0 18px; text-decoration: none; }
  .help-link:hover { text-decoration: underline; }
  .pick-toggle { display: inline-block; margin-top: 12px; font-size: 13px; color: var(--muted); cursor: pointer; }
  .pick-toggle:hover { color: var(--primary); }
  .help-item h3 { font-size: 14px; margin: 12px 0 4px; }
  .help-item p { margin: 0; font-size: 13px; color: var(--muted); line-height: 1.7; white-space: pre-line; }
  .file-list { margin-top: 10px; font-size: 14px; }
  .file-item {
    display: flex; align-items: center; justify-content: space-between;
    padding: 6px 10px; background: #f9fafb; border-radius: 8px; margin-top: 6px;
  }
  .file-item .rm { color: var(--danger); cursor: pointer; border: none; background: none; font-size: 16px; }
  .btn {
    margin-top: 16px;
    width: 100%;
    min-height: 48px;
    padding: 0 16px;
    font-size: 16px;
    font-weight: 600;
    color: #fff;
    background: var(--primary);
    border: none;
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: background-color 160ms;
  }
  .btn:hover { background: var(--primary-dark); }
  .btn:active { background: var(--primary-pressed); }
  .btn:disabled { background: #e8eef7; color: #94a3b8; cursor: not-allowed; }
  .error { color: var(--danger); font-size: 14px; margin-top: 10px; display: none; }
  .result { display: none; text-align: center; }
  .result h2 { font-size: 17px; margin: 0 0 12px; }
  .qr-item { padding: 14px 0; border-bottom: 1px solid var(--border); }
  .qr-item:last-child { border-bottom: none; }
  .qr-item img { max-width: 100%; border-radius: 8px; }
  .qr-name { font-size: 15px; font-weight: 600; word-break: break-all; margin-bottom: 8px; }
  .qr-link {
    font-size: 13px; word-break: break-all; color: var(--primary);
    text-decoration: none; display: inline-block; margin-top: 8px;
  }
  .qr-meta { font-size: 12px; color: var(--muted); margin-top: 6px; }
  .small-btns { margin-top: 10px; display: flex; gap: 8px; justify-content: center; }
  .small-btns button {
    padding: 7px 14px; font-size: 13px; border: 1px solid var(--border);
    background: #fff; border-radius: 8px; cursor: pointer;
  }
  .small-btns button:hover { background: #f3f4f6; }
  .progress { display: none; margin-top: 12px; height: 8px; background: var(--border); border-radius: 4px; overflow: hidden; }
  .progress > div { height: 100%; width: 0; background: var(--primary); transition: width .2s; }
  .tabs { display: flex; gap: 6px; margin-bottom: 16px; background: #f3f4f6; padding: 4px; border-radius: 10px; }
  .tab {
    flex: 1; padding: 9px; font-size: 14px; font-weight: 600;
    border: none; background: none; border-radius: 8px; cursor: pointer; color: var(--muted);
  }
  .tab.active { background: #fff; color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.08); }
  .join-row { display: flex; gap: 8px; margin-top: 12px; }
  .join-row input {
    flex: 1; padding: 11px 12px; font-size: 15px;
    border: 1px solid var(--border); border-radius: 10px;
    text-transform: uppercase; font-family: inherit;
  }
  .join-row input:focus { outline: 2px solid var(--primary); border-color: transparent; }
  .join-row button {
    padding: 11px 20px; font-size: 15px; font-weight: 600;
    border: 1px solid var(--primary); color: var(--primary);
    background: #fff; border-radius: 10px; cursor: pointer;
  }
  .p2p-status { text-align: center; font-size: 14px; color: var(--muted); margin: 4px 0 12px; }
  .p2p-code { font-size: 22px; font-weight: 700; letter-spacing: 4px; margin-top: 8px; }
  /* 匿名聊天 */
  .chat-log { height: 340px; overflow-y: auto; border: 1px solid var(--border); border-radius: 12px; padding: 12px; background: #f9fafb; display: flex; flex-direction: column; gap: 8px; }
  .chat-msg { max-width: 78%; padding: 8px 12px; border-radius: 14px; font-size: 14px; line-height: 1.4; word-break: break-word; white-space: pre-wrap; }
  .chat-msg.mine { align-self: flex-end; background: var(--primary); color: #fff; border-bottom-right-radius: 4px; }
  .chat-msg.peer { align-self: flex-start; background: #fff; border: 1px solid var(--border); color: var(--text); border-bottom-left-radius: 4px; }
  .chat-msg .who { display: block; font-size: 11px; opacity: .7; margin-bottom: 2px; }
  .chat-msg .body { display: block; }
  .chat-msg .time { display: block; font-size: 10px; opacity: .6; margin-top: 3px; text-align: right; }
  .chat-msg.peer .time { text-align: left; }
  /* 自己消息的发送状态角标：发送中· / 已发✓ / 失败(重发按钮) */
  .chat-msg.mine .msg-status { display: inline-block; margin-left: 6px; font-size: 11px; opacity: .85; }
  .chat-msg.mine .msg-status.failed { opacity: 1; }
  .msg-resend { border: none; background: rgba(255,255,255,.25); color: #fff; border-radius: 6px; padding: 1px 8px; font-size: 11px; cursor: pointer; }
  .msg-resend::before { content: '⚠ '; }
  .chat-msg a.chat-link { color: inherit; text-decoration: underline; word-break: break-all; }
  .chat-msg .chat-img { display: block; max-width: 100%; width: 220px; max-height: 260px; object-fit: cover; border-radius: 10px; cursor: pointer; background: #e5e7eb; min-height: 60px; }
  #imgLightbox { display: none; position: fixed; inset: 0; z-index: 3000; background: rgba(0,0,0,.92); align-items: center; justify-content: center; padding: 16px; }
  #imgLightbox.show { display: flex; }
  #imgLightbox img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 6px; }
  /* 音视频通话（微信风格）：深色背景 + 圆角方头像 + 名字 + 带文字标签的圆形控制钮 */
  #callOverlay { display: none; position: fixed; inset: 0; z-index: 3500; background: linear-gradient(180deg, #2b3440 0%, #1c2530 100%); }
  #callOverlay.show { display: block; }
  #callRemote { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #1b2430; opacity: 0; }
  #callOverlay.video.connected #callRemote { opacity: 1; } /* 视频接通才显画面 */
  #callCenter { position: absolute; top: 14%; left: 0; right: 0; display: flex; flex-direction: column; align-items: center; gap: 12px; color: #fff; }
  #callAvatar { width: 88px; height: 88px; border-radius: 18px; background: rgba(255,255,255,.16); display: flex; align-items: center; justify-content: center; font-size: 44px; }
  #callOverlay:not(.connected) #callAvatar { animation: callpulse 1.6s ease-out infinite; }
  @keyframes callpulse { 0% { box-shadow: 0 0 0 0 rgba(255,255,255,.4); } 100% { box-shadow: 0 0 0 22px rgba(255,255,255,0); } }
  #callName { font-size: 20px; font-weight: 600; }
  #callStatus { font-size: 15px; opacity: .8; }
  #callTimer { font-size: 15px; opacity: .85; font-variant-numeric: tabular-nums; }
  #callOverlay.connected.video #callCenter { top: calc(20px + var(--safe-top)); }
  #callOverlay.connected.video #callAvatar, #callOverlay.connected.video #callName { display: none; }
  #callLocalWrap { position: absolute; right: 12px; top: calc(12px + var(--safe-top)); width: 28vw; max-width: 130px; aspect-ratio: 3/4; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,.5); background: #000; }
  #callLocal { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }
  /* 控制条：每个 = 圆钮 + 下方文字 */
  #callControls, .call-inc-btns { position: absolute; left: 0; right: 0; bottom: calc(46px + var(--safe-bottom)); display: flex; justify-content: center; gap: 40px; }
  .call-ctl { display: flex; flex-direction: column; align-items: center; gap: 8px; }
  .call-ctl button { width: 64px; height: 64px; border-radius: 50%; border: none; font-size: 26px; cursor: pointer; background: rgba(255,255,255,.22); color: #fff; display: flex; align-items: center; justify-content: center; }
  .call-ctl span { font-size: 13px; color: rgba(255,255,255,.85); }
  .call-ctl.call-hang button, #callDeclineBtn { background: #f5433f; transform: rotate(135deg); } /* 挂断/拒绝：红 + 话筒转 135° */
  #callAcceptBtn { background: #07c160; } /* 微信绿 */
  #callIncoming { display: none; position: fixed; inset: 0; z-index: 3600; background: linear-gradient(180deg, #2b3440 0%, #1c2530 100%); color: #fff; }
  #callIncoming.show { display: block; }
  #callIncAvatar { position: absolute; top: 16%; left: 0; right: 0; margin: 0 auto; width: 88px; height: 88px; border-radius: 18px; background: rgba(255,255,255,.16); display: flex; align-items: center; justify-content: center; font-size: 44px; }
  #callIncName { position: absolute; top: calc(16% + 100px); left: 0; right: 0; text-align: center; font-size: 20px; font-weight: 600; }
  #callIncomingText { position: absolute; top: calc(16% + 136px); left: 0; right: 0; text-align: center; font-size: 15px; opacity: .8; }
  .chat-input .chat-imgbtn { padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: #fff; font-size: 18px; line-height: 1; cursor: pointer; }
  .chat-input .chat-imgbtn:disabled { opacity: .5; cursor: default; }
  .chat-sys { align-self: center; font-size: 12px; color: var(--muted); background: rgba(0,0,0,.05); padding: 2px 10px; border-radius: 10px; }
  #chatLock, #xferLock { padding: 18px 16px; border: 1px dashed var(--border); border-radius: 12px; background: #f9fafb; color: var(--muted); font-size: 14px; text-align: center; line-height: 1.55; }
  /* 全屏聊天（连接后接管整屏，App 式，像 telegram）+ 顶栏 */
  .chat-topbar { display: none; }
  /* 独立聊天界面：#chatWrap 被 JS 移到 body 直接子级，整页普通 flex 布局（不用 position:fixed，
     从根上避开 iOS Safari 键盘弹出时 fixed 失固定 / 文档被滚走的坑）。键盘弹出（interactive-widget=
     resizes-content）时 body 的 100dvh 自然收缩，聊天记录区随之变矮，输入框始终贴在键盘上方。 */
  /* Chatbox（web.chatboxai.app）同款：不跟 iOS 较劲——html/body 保持普通流（非 fixed）、
     height:100%（配合 chat.html 的 viewport height=device-height = 设备高度）、body overflow:hidden，
     不做任何 visualViewport 尺寸重算。布局固定成设备高度、输入框在最底部，键盘弹出时让 iOS
     原生把聚焦输入框滚动到键盘上方——不重算、不锁死，就不会出现留白/错位。*/
  html.in-chat, body.in-chat { height: 100%; margin: 0; padding: 0; overflow: hidden; }
  body.in-chat { display: flex; flex-direction: column; min-height: 0; background: #fff; }
  body.in-chat > *:not(#chatWrap):not(#imgLightbox):not(#callOverlay):not(#callIncoming) { display: none !important; }
  /* #chatWrap 用 fixed 钉在「可见窗口」上：高度=visualViewport.height、top=offsetTop（JS 设），
     键盘弹出时容器缩到可见区，顶栏留顶、消息区可滚、输入框贴底，iOS 无需把整页顶上去。*/
  body.in-chat #chatWrap { position: fixed; top: 0; left: 0; width: 100%; height: 100%; min-height: 0; background: #fff; display: flex !important; flex-direction: column; overflow: hidden; z-index: 2000; }
  body.in-chat .chat-topbar { display: flex; align-items: center; gap: 12px; padding: calc(10px + var(--safe-top)) 14px 10px; background: var(--primary); color: #fff; flex: 0 0 auto; }
  body.in-chat .chat-topbar .chat-exit { background: rgba(255,255,255,.22); border: none; color: #fff; width: 34px; height: 34px; border-radius: 9px; font-size: 16px; line-height: 1; cursor: pointer; flex: 0 0 auto; }
  body.in-chat .chat-topbar .chat-title { min-width: 0; }
  body.in-chat .chat-topbar .ct-name { font-weight: 600; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body.in-chat .chat-topbar .ct-conn { font-size: 11.5px; opacity: .9; margin-top: 1px; }
  body.in-chat .chat-log { flex: 1 1 auto; height: auto; max-height: none; min-height: 0; border: none; border-radius: 0; background: #eceff3; }
  body.in-chat .chat-input { flex: 0 0 auto; margin: 0; padding: 8px 10px calc(8px + var(--safe-bottom)); border-top: 1px solid var(--border); background: #fff; }
  /* 群聊：邀请条 / 审批 / 成员面板（都在 #chatWrap 内、flex:0 不挤压消息区）*/
  #gcBar { flex: 0 0 auto; background: #f1f5f9; border-bottom: 1px solid var(--border); padding: 8px 12px; font-size: 13px; max-height: 38vh; overflow-y: auto; }
  #gcInvite { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
  #gcInvite .gc-link { font-size: 11px; color: var(--primary); word-break: break-all; flex: 1 1 60%; }
  .gc-copy, .gc-ok, .gc-no, .gc-kick { border: none; border-radius: 7px; padding: 4px 10px; font-size: 12px; cursor: pointer; color: #fff; white-space: nowrap; }
  .gc-copy { background: var(--primary); }
  .gc-req { display: flex; align-items: center; gap: 6px; padding: 5px 0; }
  .gc-req-name { flex: 1 1 auto; min-width: 0; }
  .gc-ok { background: #16a34a; }
  .gc-no { background: #64748b; }
  #gcMembersPanel { flex: 0 0 auto; background: #fff; border-bottom: 1px solid var(--border); padding: 6px 12px; max-height: 38vh; overflow-y: auto; }
  .gc-mem { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 5px 0; font-size: 14px; }
  .gc-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: #22c55e; }
  .gc-dot.off { background: #cbd5e1; }
  .gc-mem span:nth-child(2) { flex: 1 1 auto; }
  .gc-kick { background: var(--danger); }
  body.in-chat .chat-topbar #gcMembersBtn { margin-left: auto; }
  /* 服务器传输高级区见文件后部「12/13 CLI Advanced」 */
  .chat-input { display: flex; gap: 8px; margin-top: 10px; align-items: flex-end; }
  .chat-input textarea { flex: 1; min-width: 0; height: 44px; min-height: 44px; box-sizing: border-box; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; font-size: 14px; font-family: inherit; line-height: 1.4; resize: none; max-height: 120px; overflow-y: auto; }
  .chat-input button { padding: 10px 18px; border: none; border-radius: 10px; background: var(--primary); color: #fff; font-size: 14px; font-weight: 600; cursor: pointer; white-space: nowrap; }
  .chat-input button:disabled { opacity: .5; cursor: default; }
  .pick-code { margin-top: 8px; font-size: 14px; color: var(--muted); }
  .pick-del { margin-left: 10px; font-size: 12px; padding: 2px 8px; border: 1px solid var(--border); border-radius: 6px; background: #fff; color: var(--danger); cursor: pointer; }
  .pick-del:hover { border-color: var(--danger); }
  .pick-del:disabled { opacity: .5; cursor: default; }
  .pick-code b { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 18px; letter-spacing: 3px; color: var(--text); }
  .pick-text { white-space: pre-wrap; word-break: break-all; background: #f9fafb; border: 1px solid var(--border); padding: 10px 12px; border-radius: 8px; margin-top: 10px; text-align: left; font-size: 14px; }
  /* 组合(文字+文件)结果 / 提取码取回：区块标签 + 文件下载行 */
  .combined-preview { margin-top: 12px; text-align: left; }
  .pick-sec { font-size: 12px; font-weight: 700; color: var(--muted); margin: 14px 0 4px; }
  .pick-file { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; margin-top: 8px; text-align: left; }
  .pick-file .pf-name { font-size: 14px; word-break: break-all; color: var(--text); }
  .pick-file .pf-dl { flex: 0 0 auto; background: var(--primary); color: #fff; text-decoration: none; padding: 7px 14px; border-radius: 8px; font-size: 13px; font-weight: 600; }
  .g-copy { display: inline-block; margin-top: 8px; font-size: 13px; color: var(--primary); background: none; border: none; cursor: pointer; padding: 4px 0; }
  /* 生成提取码后面的「?」帮助 */
  .pick-help { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; margin-left: 4px; border-radius: 50%; border: 1px solid var(--muted); color: var(--muted); font-size: 11px; font-weight: 700; cursor: pointer; vertical-align: middle; }
  .pick-help:hover { border-color: var(--primary); color: var(--primary); }
  .save-hist {
    display: flex; align-items: center; gap: 7px;
    margin-top: 12px; font-size: 14px; color: var(--muted); cursor: pointer;
  }
  .save-hist input { width: 16px; height: 16px; accent-color: var(--primary); cursor: pointer; }
  .modal h3 { font-size: 13px; color: var(--muted); margin: 16px 0 4px; font-weight: 600; }
  .hist-row {
    display: flex; justify-content: space-between; align-items: center; gap: 10px;
    padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 13px;
  }
  .hist-info { flex: 1; min-width: 0; }
  .hist-name { font-weight: 600; word-break: break-all; }
  .hist-meta { color: var(--muted); font-size: 12px; margin-top: 2px; }
  .hist-actions { display: flex; gap: 6px; flex-shrink: 0; }
  .hist-actions button {
    padding: 5px 10px; font-size: 12px; border: 1px solid var(--border);
    background: #fff; border-radius: 7px; cursor: pointer; white-space: nowrap;
  }
  .hist-actions button:hover { background: #f3f4f6; }
  .hist-actions button.danger { color: var(--danger); border-color: #fecaca; }
  .hist-empty { color: var(--muted); font-size: 13px; padding: 8px 0; }
  .plan-card {
    display: flex; justify-content: space-between; align-items: center;
    border: 1px solid var(--border); border-radius: 10px;
    padding: 12px 14px; margin-top: 10px;
  }
  .plan-card .p-name { font-weight: 600; font-size: 14px; }
  .plan-card .p-desc { font-size: 12px; color: var(--muted); margin-top: 2px; }
  .plan-card .p-price { font-size: 16px; font-weight: 700; color: var(--primary); white-space: nowrap; margin-left: 12px; }
  /* 页脚(法务/版权/版本)：手机隐藏——这些收进设置页；仅桌面 ≥1024 底部显示 */
  footer { display: none; color: var(--muted); font-size: 12px; margin-top: 8px; text-align: center; }
  .foot-links { margin-top: 6px; }
  .foot-links a { color: var(--muted); text-decoration: underline; }
  .foot-links a:hover { color: var(--primary); }
  .foot-links .dot { margin: 0 6px; }
  /* 登录 / 注册弹窗 */
  .overlay {
    position: fixed; inset: 0;
    background: rgba(0,0,0,.4);
    display: none;
    align-items: center; justify-content: center;
    /* 必须高于设置面板（#settingsScreen z-index:3000）：设置里点「升级 / 历史记录 / 登录」时
       设置面板留在下面垫着（关掉弹层就回到设置），弹层得盖在它上面才看得见。
       仍低于通话全屏 3500 与确认弹窗 4000。 */
    z-index: 3200;
    /* 让开状态栏/刘海与 Home 指示条：index.html 用了 viewport-fit=cover，弹层会延伸到安全区里 */
    padding: calc(16px + var(--safe-top)) 16px calc(16px + var(--safe-bottom));
  }
  .overlay.show { display: flex; }
  .modal {
    background: #fff;
    border-radius: 14px;
    padding: 24px;
    width: 100%;
    max-width: 360px;
    position: relative;
  }
  .modal h2 { margin: 0 0 16px; font-size: 18px; }
  .modal input {
    width: 100%;
    padding: 11px 12px;
    font-size: 15px;
    border: 1px solid var(--border);
    border-radius: 10px;
    margin-bottom: 10px;
    font-family: inherit;
  }
  .modal input:focus { outline: 2px solid var(--primary); border-color: transparent; }
  .modal .close {
    position: absolute; top: 12px; right: 12px;
    border: none; background: none; font-size: 18px;
    color: var(--muted); cursor: pointer;
  }
  /* ===== 16 使用说明：手机全屏、桌面双栏的结构化帮助弹窗 ===== */
  body.help-open { overflow: hidden; }
  .help-overlay {
    z-index: 3200;   /* 同 .overlay：设置里点「帮助与反馈」时要盖在设置面板（3000）之上 */
    padding: 0;
    align-items: stretch;
    background: var(--bg);
  }
  .help-modal {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100dvh;
    max-width: none;
    max-height: none;
    min-height: 0;
    padding: 0;
    overflow: hidden;
    border-radius: 0;
    background: var(--bg);
  }
  .help-modal-header {
    flex: 0 0 auto;
    /* 手机上使用说明是**整屏**弹层，而 index.html 用了 viewport-fit=cover（PWA 全屏需要）→
       内容会顶到状态栏/刘海下面：标题会和时间叠在一起、右上关闭钮撞电池图标（用户实测截图）。
       顶部补安全区，高度也跟着加，不然按钮被压扁。 */
    min-height: calc(72px + var(--safe-top));
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: calc(var(--sp-3) + var(--safe-top)) var(--sp-4) var(--sp-3);
    background: var(--card);
    border-bottom: 1px solid var(--border);
  }
  .help-heading {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
  }
  .help-heading-icon,
  .help-card-icon,
  .help-hero-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--primary-tint);
    color: var(--primary);
  }
  .help-heading-icon {
    width: 40px;
    height: 40px;
    border: 1px solid var(--primary-soft-border);
    border-radius: var(--r-md);
  }
  .help-icon {
    display: inline-block;
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
    background-color: currentColor;
    -webkit-mask: var(--help-icon) center / contain no-repeat;
    mask: var(--help-icon) center / contain no-repeat;
  }
  .help-icon[data-help-icon="help"] { --help-icon: url("/icons/help.svg"); }
  .help-icon[data-help-icon="x"] { --help-icon: url("/icons/x.svg"); }
  .help-icon[data-help-icon="shield-filled"] { --help-icon: url("/icons/shield-filled.svg"); }
  .help-icon[data-help-icon="check"] { --help-icon: url("/icons/check.svg"); }
  .help-icon[data-help-icon="laptop"] { --help-icon: url("/icons/laptop.svg"); }
  .help-modal h2 {
    margin: 0;
    color: var(--text-strong);
    font-size: var(--fs-h2);
    line-height: 28px;
    font-weight: 600;
  }
  .help-heading p {
    margin: 0;
    color: var(--muted);
    font-size: 12px;
    line-height: 16px;
  }
  .help-close {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: var(--card);
    color: var(--text);
    cursor: pointer;
  }
  .help-close:hover { background: var(--surface-2); }
  .help-close:active { background: var(--neutral-pressed); }
  .help-close:focus-visible,
  .help-done:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }
  .help-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: var(--sp-3) var(--sp-4) var(--sp-6);
    scrollbar-gutter: stable;
  }
  .help-hero {
    min-height: 132px;
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    padding: var(--sp-4);
    border: 1px solid var(--primary-soft-border);
    border-radius: var(--r-lg);
    background: var(--primary-tint);
  }
  .help-hero-icon {
    width: 44px;
    height: 44px;
    border-radius: var(--r-md);
    background: var(--card);
    box-shadow: var(--sh-1);
  }
  .help-hero-copy { min-width: 0; }
  .help-hero h3 {
    margin: 0;
    color: var(--text-strong);
    font-size: 18px;
    line-height: 24px;
    font-weight: 600;
  }
  .help-hero p {
    margin: var(--sp-1) 0 0;
    color: var(--text);
    font-size: 13px;
    line-height: 18px;
  }
  .help-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-top: var(--sp-3);
  }
  .help-tag {
    min-height: 24px;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-1) var(--sp-2);
    border: 1px solid var(--primary-soft-border);
    border-radius: var(--r-pill);
    background: var(--card);
    color: var(--primary);
    font-size: 12px;
    line-height: 16px;
    font-weight: 500;
  }
  .help-tag-icon { width: 14px; height: 14px; }
  .help-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-3);
    margin-top: var(--sp-3);
  }
  .help-card {
    min-width: 0;
    padding: var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    background: var(--card);
    box-shadow: var(--sh-1);
  }
  .help-card-head {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
  }
  .help-card-icon {
    width: 40px;
    height: 40px;
    border-radius: var(--r-sm);
  }
  .help-card-icon .help-icon { width: 20px; height: 20px; }
  .help-card-copy { min-width: 0; }
  .help-card h3 {
    margin: 0;
    color: var(--text-strong);
    font-size: 16px;
    line-height: 22px;
    font-weight: 600;
  }
  .help-card-copy p {
    margin: var(--sp-1) 0 0;
    color: var(--muted);
    font-size: 13px;
    line-height: 18px;
  }
  .help-bullets,
  .help-steps {
    display: grid;
    gap: var(--sp-2);
    margin: var(--sp-3) 0 0;
    padding: 0;
    color: var(--text);
    font-size: 13px;
    line-height: 18px;
  }
  .help-bullets { list-style: none; }
  .help-bullets li {
    position: relative;
    padding-left: var(--sp-4);
  }
  .help-bullets li::before {
    content: "";
    position: absolute;
    top: 7px;
    left: 2px;
    width: 5px;
    height: 5px;
    border-radius: var(--r-pill);
    background: var(--primary);
  }
  .help-steps { list-style: none; }
  .help-steps li {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2);
  }
  .help-step-number {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-pill);
    background: var(--primary-tint);
    color: var(--primary);
    font-size: 12px;
    line-height: 16px;
    font-weight: 600;
  }
  .help-step-text { padding-top: 3px; }
  .help-advanced-note {
    min-height: 40px;
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2);
    margin-top: var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r-sm);
    background: var(--surface-2);
    color: var(--muted);
    font-size: 12px;
    line-height: 16px;
  }
  .help-advanced-note .help-icon {
    width: 18px;
    height: 18px;
    color: var(--text);
  }
  .help-modal-footer {
    flex: 0 0 auto;
    /* 同上：整屏弹层的底边要避开 Home 指示条 */
    min-height: calc(68px + var(--safe-bottom));
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    margin: 0;
    padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + var(--safe-bottom));
    padding-bottom: calc(var(--sp-3) + var(--safe-bottom));
    border-top: 1px solid var(--border);
    background: var(--card);
  }
  .help-footer-note {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    color: var(--muted);
    font-size: 12px;
    line-height: 16px;
    text-align: left;
  }
  .help-footer-note .help-icon {
    width: 18px;
    height: 18px;
    color: var(--primary);
  }
  .help-done {
    flex: 0 0 auto;
    min-width: 96px;
    height: 44px;
    padding: 0 var(--sp-4);
    border: 1px solid var(--primary);
    border-radius: var(--r-sm);
    background: var(--primary);
    color: var(--card);
    font-size: 14px;
    line-height: 20px;
    font-weight: 600;
    cursor: pointer;
  }
  .help-done:hover { border-color: var(--primary-dark); background: var(--primary-dark); }
  .help-done:active { border-color: var(--primary-pressed); background: var(--primary-pressed); }
  @media (min-width: 1024px) {
  /* 桌面容器宽度：随视口增长，上限 1600（大屏不再只占中间一小条；要调宽窄只改这一行） */
  :root { --desk-w: min(1600px, 100%); }
  /* 「使用说明」在桌面顶栏常驻：原来只在二维码 tab 显示(body.qr-tab)，切到快传/聊天/中转就消失了。
     桌面顶栏空间充足，应任何 tab 都能点开说明。（手机顶栏窄，仍保持只在二维码 tab 显示） */
  #helpBtn { display: inline-flex !important; }
    .help-overlay {
      align-items: center;
      padding: var(--sp-6);
      background: var(--overlay);
    }
    .help-modal {
      width: 960px;
      height: min(864px, calc(100dvh - var(--sp-12)));
      border: 1px solid var(--border);
      border-radius: var(--r-xl);
      box-shadow: var(--sh-2);
    }
    .help-modal-header {
      min-height: 80px;
      padding: var(--sp-4) var(--sp-6);
    }
    .help-heading-icon { width: 44px; height: 44px; }
    .help-scroll { padding: var(--sp-6); }
    .help-hero { min-height: 112px; align-items: center; }
    .help-hero-icon { width: 48px; height: 48px; }
    .help-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--sp-4);
      margin-top: var(--sp-4);
    }
    .help-card-settings { grid-column: 1 / -1; }
    .help-modal-footer { padding: var(--sp-3) var(--sp-6); }
  }
  .modal .switch-line { font-size: 13px; color: var(--muted); margin-top: 12px; text-align: center; }
  .modal .switch-line a { color: var(--primary); cursor: pointer; text-decoration: none; }
  /* 手机上压缩顶部区域高度，生成后二维码尽量一屏可见 */
  @media (max-width: 480px) {
    /* 匿名聊天手机适配：记录区随视口高、输入框回到 1 行（旧面板，后续按 08 重做） */
    .chat-log { height: 42vh; min-height: 150px; max-height: 320px; }
    .chat-input textarea { min-height: 42px; }
    .drop-sub { display: none; }
  }

/* 底部已改为统一的 4-tab 栏，首页「按分类浏览工具」区一律隐藏（工具箱走顶栏/设置页） */
.app-tools-cats { display: none !important; }

/* 共享文字：标签行(标签占满 + 右侧复制按钮) + 小复制按钮 */
.shared-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.shared-head > span { flex: 1; min-width: 0; }
.copy-btn { flex: 0 0 auto; padding: 4px 12px; font-size: 12px; border: 1px solid var(--border); background: #fff; color: var(--text); border-radius: 8px; cursor: pointer; line-height: 1.4; }
.copy-btn:hover { background: #f3f4f6; border-color: var(--primary); color: var(--primary); }

/* ===== PWA 设置页（iOS 风分组列表）+ 版本更新横幅 ===== */
/* 标题栏(品牌+⚙️)与底部 tab 栏现在是全模式统一(见文件上方)。装成 App 时另隐藏页脚，
   因为底部已有 tab 栏、且法务链接已收进设置页。 */
/* 桌面(≥1024)才显示底部页脚；App 独立形态永远无页脚（全部收进设置页） */
@media (min-width: 1024px) {
  /* 桌面容器宽度：随视口增长，上限 1600（大屏不再只占中间一小条；要调宽窄只改这一行） */
  :root { --desk-w: min(1600px, 100%); }
  /* 「使用说明」在桌面顶栏常驻：原来只在二维码 tab 显示(body.qr-tab)，切到快传/聊天/中转就消失了。
     桌面顶栏空间充足，应任何 tab 都能点开说明。（手机顶栏窄，仍保持只在二维码 tab 显示） */
  #helpBtn { display: inline-flex !important; } footer { display: block; } }
@media (display-mode: standalone) { footer { display: none !important; } }
html.pwa-standalone footer { display: none !important; }

/* 版本更新横幅：检测到新版时显示（标题栏下方常规流），点击强制更新 */
#updateBanner { align-self: stretch; width: 100%; box-sizing: border-box; z-index: 9; background: var(--primary); color: #fff;
  font-size: 14px; font-weight: 600; text-align: center; padding: 10px 14px; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,.15); }
#updateBanner:active { background: var(--primary-dark); }

/* 设置页容器：默认隐藏；.open 时全屏铺开 */
#settingsScreen { display: none; position: fixed; inset: 0; z-index: 3000; background: var(--bg);
  flex-direction: column; overflow-y: auto; }
#settingsScreen.open { display: flex; }
.set-hd { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; justify-content: space-between;
  padding: calc(10px + var(--safe-top)) 14px 10px; background: rgba(244,246,249,.92);
  backdrop-filter: blur(6px); border-bottom: 1px solid var(--border); }
.set-title { font-size: 17px; font-weight: 700; }
.set-close { background: none; border: none; color: var(--primary); font-size: 16px; cursor: pointer; padding: 4px; width: 56px; text-align: left; }
.set-body { max-width: 640px; width: 100%; margin: 0 auto; padding: 14px 14px calc(28px + var(--safe-bottom)); box-sizing: border-box; }
.set-glabel { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin: 20px 6px 6px; }
.set-group { background: var(--card); border-radius: 12px; overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,.05); }
.set-group:empty { display: none; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
  padding: 13px 16px; font-size: 15px; color: var(--text); text-decoration: none; text-align: left;
  background: none; border: none; border-top: 1px solid var(--border); cursor: pointer; box-sizing: border-box; }
.set-group > .set-row:first-child { border-top: none; }
.set-row.static { cursor: default; }
.set-row:not(.static):active { background: #eef1f6; }
.set-row .set-val { color: var(--muted); font-size: 14px; margin-left: auto; }
.set-row .set-val.badge { color: #fff; background: var(--primary); border-radius: 999px; padding: 2px 10px; font-size: 12px; font-weight: 600; }
.set-row .set-arrow { color: var(--muted); font-size: 18px; margin-left: 6px; }
.set-row.danger { color: var(--danger); }
.set-row .set-sub { color: var(--muted); font-size: 12px; }
.set-foot { text-align: center; color: var(--muted); font-size: 12px; margin-top: 24px; }

/* ===== 设置 15：嵌套页头 + 分组设置项（对齐 15.spec.yaml）===== */
/* 高度必须是「56 + 安全区」：原来写死 height:56 而 padding-top 被算进这 56 里，
   开了 viewport-fit=cover 后内容就顶到状态栏下面去了（真机可见）。
   同时去掉从 .set-hd 继承来的 backdrop-filter：本行背景是不透明的 --card，模糊毫无效果，
   而 sticky 元素上的 backdrop-filter 在移动端每帧重绘，是进设置卡顿的主因之一。 */
.set-hd.nested-header {
  flex: 0 0 auto;
  height: auto;
  min-height: calc(56px + var(--safe-top));
  padding: var(--safe-top) 16px 0;
  background: var(--card);
  backdrop-filter: none;
  border-bottom: 1px solid var(--border);
  box-sizing: border-box;
}
.nested-header .back-btn { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; padding: 0;
  background: transparent; border: 0; border-radius: var(--r-pill); color: var(--text); cursor: pointer; }
.nested-header .back-btn svg { width: 24px; height: 24px; }
.nested-header .header-title { flex: 1 1 auto; text-align: center; font-size: 16px; font-weight: 600; color: var(--text-strong); }
.nested-header .done-btn { width: 64px; height: 44px; background: transparent; border: 0; border-radius: var(--r-sm);
  color: var(--primary); font-size: 14px; font-weight: 500; cursor: pointer; }

.set-body.settings-main { padding: 12px 16px calc(24px + var(--safe-bottom)); }
.settings-section + .settings-section { margin-top: 24px; }
.settings-section .section-label { margin: 0 0 8px 4px; font-size: 13px; color: var(--muted); text-transform: none; letter-spacing: 0; }
.settings-main .card { padding: 0; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1); overflow: hidden; }
.settings-main .card:empty { display: none; }
/* 设置行：图标 + 标题(+副文案) + 值/开关 + chevron */
.settings-main .setting-row { display: flex; align-items: center; gap: 12px; width: 100%; box-sizing: border-box; min-height: 52px; padding: 10px 16px;
  background: var(--card); border: 0; border-top: 1px solid var(--divider); font-size: 15px; color: var(--text); font-family: inherit; text-align: left; text-decoration: none; cursor: pointer; }
.settings-main .card > .setting-row:first-child { border-top: 0; }
.settings-main .setting-row.static { cursor: default; }
.settings-main .setting-row:not(.static):active { background: var(--surface-2); }
.settings-main .setting-row .row-icon { flex: 0 0 auto; display: flex; width: 20px; height: 20px; color: var(--muted); }
.settings-main .setting-row .row-icon svg { width: 20px; height: 20px; }
.settings-main .setting-row .row-icon.brand { color: var(--primary); }
.settings-main .setting-row .row-icon.danger { color: var(--danger); }
.settings-main .setting-row .setting-title { flex: 0 1 auto; color: inherit; }
.settings-main .setting-row .setting-title.danger { color: var(--danger); }
.settings-main .setting-row .row-copy { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.settings-main .setting-row .setting-helper { font-size: 12px; color: var(--muted); }
.settings-main .setting-row .setting-value { margin-left: auto; max-width: 150px; font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.settings-main .setting-row .chevron { flex: 0 0 auto; display: flex; width: 20px; height: 20px; color: var(--text-tertiary); }
.settings-main .setting-row .chevron svg { width: 20px; height: 20px; }
.settings-main .setting-row .ios-switch { margin-left: auto; }
.settings-main .setting-row .status-badge { margin-left: auto; }
/* 账号行（头像 + 邮箱 + 状态） */
.settings-main .account-row { min-height: 64px; }
.settings-main .account-row .avatar { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); }
.settings-main .account-row .avatar svg { width: 24px; height: 24px; }
.settings-main .account-row .setting-helper.ok { color: var(--ok); }
/* 退出登录 */
.settings-main .logout-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; box-sizing: border-box; height: 48px; margin-top: 24px;
  background: var(--card); border: 1px solid var(--danger-button-border); border-radius: var(--r-sm); color: var(--danger); font-size: 15px; font-weight: 600; cursor: pointer; }
.settings-main .logout-btn svg { width: 18px; height: 18px; }
.settings-main .privacy-banner { margin-top: 12px; height: auto; min-height: 48px; padding: 10px 12px; }
.settings-footer { margin-top: 24px; }
.settings-panel { width: 100%; min-height: 100%; display: flex; flex-direction: column; background: var(--bg); }
.settings-layout { flex: 1 1 auto; min-height: 0; }
.settings-sidebar { display: none; }
.settings-main .setting-row .row-icon img,
.settings-main .setting-row .chevron img { display: block; width: 100%; height: 100%; }
.settings-main .logout-btn img { display: block; width: 18px; height: 18px; }
.settings-main .privacy-banner img { display: block; width: 20px; height: 20px; }
.settings-main .setting-row:focus-visible,
.nested-header button:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
}

/* ===================================================================
   PC 桌面端（03 二维码 / 07 快传 / 13 中转）——共用壳：顶部导航 + 居中主区 + 双栏
   移动端不受影响：以下全部在 ≥1024px 生效
   =================================================================== */
.desktop-nav { display: none; }
@media (min-width: 1024px) {
  /* 桌面容器宽度：随视口增长，上限 1600（大屏不再只占中间一小条；要调宽窄只改这一行） */
  :root { --desk-w: min(1600px, 100%); }
  /* 「使用说明」在桌面顶栏常驻：原来只在二维码 tab 显示(body.qr-tab)，切到快传/聊天/中转就消失了。
     桌面顶栏空间充足，应任何 tab 都能点开说明。（手机顶栏窄，仍保持只在二维码 tab 显示） */
  #helpBtn { display: inline-flex !important; }
  /* —— 15 设置：960×720 居中面板 + 240px 分组导航 + 单组内容 ——
     手机继续使用连续分组列表；桌面才启用 roving-tabindex 导航。 */
  #settingsScreen {
    padding: var(--sp-12);
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--overlay);
  }
  #settingsScreen .settings-panel {
    width: 960px;
    height: min(720px, calc(100vh - 96px));
    min-height: min(640px, calc(100vh - 48px));
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    background: var(--card);
    box-shadow: var(--sh-2);
    overflow: hidden;
  }
  #settingsScreen .set-hd.nested-header {
    position: static;
    flex: 0 0 72px;
    height: 72px;
    display: grid;
    grid-template-columns: 80px minmax(0, 1fr) 80px;
    padding: 0 var(--sp-6);
    background: var(--card);
  }
  #settingsScreen .nested-header .back-btn { justify-self: start; }
  #settingsScreen .nested-header .back-btn img { width: 24px; height: 24px; }
  #settingsScreen .nested-header .header-title {
    font-size: 20px;
    line-height: 28px;
    font-weight: 600;
  }
  #settingsScreen .nested-header .done-btn {
    justify-self: end;
    width: 80px;
    height: 40px;
    padding: 0 var(--sp-4);
    border: 1px solid var(--primary-soft-border);
    border-radius: var(--r-sm);
    background: var(--primary-tint);
    font-weight: 600;
  }
  #settingsScreen .nested-header .done-btn:hover { background: var(--primary-tint-pressed); }
  #settingsScreen .settings-layout {
    display: grid;
    grid-template-columns: 240px minmax(0, 1fr);
    overflow: hidden;
  }
  #settingsScreen .settings-sidebar {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-6);
    padding: var(--sp-6) var(--sp-4);
    border-right: 1px solid var(--border);
    background: var(--surface-2);
  }
  #settingsScreen .settings-sidebar-head {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 0 var(--sp-2);
  }
  #settingsScreen .settings-sidebar-head > span:last-child {
    min-width: 0;
    display: grid;
    gap: var(--sp-1);
  }
  #settingsScreen .settings-sidebar-head strong {
    color: var(--text-strong);
    font-size: 16px;
    line-height: 20px;
    font-weight: 600;
  }
  #settingsScreen .settings-sidebar-head small {
    color: var(--muted);
    font-size: 12px;
    line-height: 16px;
  }
  #settingsScreen .settings-sidebar-icon {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-sm);
    background: var(--primary-tint);
  }
  #settingsScreen .settings-sidebar-icon img { width: 20px; height: 20px; }
  #settingsScreen .settings-nav { display: grid; gap: var(--sp-2); }
  #settingsScreen .settings-nav-item {
    width: 100%;
    min-height: 48px;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 0 var(--sp-3);
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 14px;
    line-height: 20px;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
  }
  #settingsScreen .settings-nav-item:hover { background: var(--card); border-color: var(--border); }
  #settingsScreen .settings-nav-item.is-active {
    border-color: var(--primary-soft-border);
    background: var(--primary-tint);
    color: var(--primary);
    font-weight: 600;
  }
  #settingsScreen .settings-nav-item:focus-visible {
    outline: 0;
    box-shadow: var(--focus-ring);
  }
  #settingsScreen .settings-nav-glyph {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    background: currentColor;
    -webkit-mask: var(--settings-icon) center / contain no-repeat;
    mask: var(--settings-icon) center / contain no-repeat;
  }
  #settingsScreen .set-body.settings-main {
    max-width: none;
    min-width: 0;
    height: 100%;
    margin: 0;
    padding: var(--sp-6);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--bg);
  }
  #settingsScreen .settings-section { margin: 0; }
  #settingsScreen .settings-section:not(.is-active) { display: none; }
  #settingsScreen .settings-section .section-label {
    margin: 0 0 var(--sp-3);
    padding-left: var(--sp-1);
    color: var(--text-strong);
    font-size: 20px;
    line-height: 28px;
    font-weight: 600;
  }
  #settingsScreen .settings-main .card {
    width: 100%;
    max-width: none;
    border-radius: var(--r-md);
    box-shadow: var(--sh-1);
  }
  #settingsScreen .settings-main .setting-row {
    min-height: 64px;
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) minmax(96px, 160px) 20px;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
  }
  #settingsScreen .settings-main .setting-row:hover:not(.static) { background: var(--surface-2); }
  #settingsScreen .settings-main .setting-row:focus-visible {
    position: relative;
    z-index: 1;
    box-shadow: inset var(--focus-ring);
  }
  #settingsScreen .settings-main .setting-row .row-icon {
    width: 40px;
    height: 40px;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-sm);
    background: var(--primary-tint);
    color: var(--primary);
  }
  #settingsScreen .settings-main .setting-row .row-icon img { width: 20px; height: 20px; opacity: .72; }
  #settingsScreen .settings-main .setting-row .row-icon.danger { background: var(--danger-tint); }
  #settingsScreen .settings-main .setting-row .setting-title {
    grid-column: 2;
    min-width: 0;
    align-self: center;
    font-size: 15px;
    line-height: 20px;
    font-weight: 500;
  }
  #settingsScreen .settings-main .setting-row .row-copy {
    grid-column: 2 / 4;
    align-self: center;
  }
  #settingsScreen .settings-main .setting-row .setting-value,
  #settingsScreen .settings-main .setting-row .status-badge {
    grid-column: 3;
    justify-self: end;
    margin-left: 0;
    text-align: right;
  }
  #settingsScreen .settings-main .setting-row .chevron {
    grid-column: 4;
    justify-self: end;
  }
  #settingsScreen .settings-main .setting-row .ios-switch {
    grid-column: 3 / 5;
    justify-self: end;
    margin-left: 0;
  }
  #settingsScreen .settings-main .account-row .avatar {
    grid-column: 1;
    width: 40px;
    height: 40px;
  }
  #settingsScreen .settings-main .account-row .row-copy { grid-column: 2 / 4; }
  #settingsScreen .settings-main .clear-row:hover { background: var(--danger-tint); }
  #settingsScreen .settings-main .privacy-banner {
    width: 100%;
    margin-top: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
  }
  #settingsScreen .settings-main .privacy-banner .pb-ico { width: 20px; height: 20px; }
  #settingsScreen .settings-main .logout-btn {
    width: min(240px, 100%);
    margin: var(--sp-6) auto 0;
  }
  #settingsScreen .settings-main .logout-btn:hover { background: var(--danger-tint); }
  #settingsScreen .settings-footer { margin-top: var(--sp-4); }

  /* —— 顶部栏：白底 + 分隔线 + 品牌 + 顶部导航 + 设置 —— */
  .topbar.app-header { height: 64px; padding: 0 32px; background: var(--card); border-bottom: 1px solid var(--border); gap: 24px; }
  .topbar.app-header .brand-name { font-size: 20px; }
  .desktop-nav { display: flex; align-items: stretch; height: 64px; gap: 8px; margin-left: 8px; }
  .desktop-nav > * { display: inline-flex; align-items: center; padding: 0 14px; border: 0; border-bottom: 3px solid transparent;
    background: transparent; color: var(--text); font-size: 15px; font-weight: 500; font-family: inherit; text-decoration: none; cursor: pointer; }
  .desktop-nav > *:hover { color: var(--primary); }
  .desktop-nav > .active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }
  .topbar.app-header .help-entry, .topbar.app-header #langSel, .topbar.app-header .user-btn { margin-left: 0; }
  .topbar.app-header #settingsBtn { margin-left: auto; }
  /* 桌面隐藏底部 tab 栏（导航已上移） */
  .bottom-nav { display: none !important; }
  body.mm-tab { padding-bottom: 24px; }

  /* —— 主区：所有页面共用同一桌面容器（内容宽 1200 + 左右 32 内距 = 1264），
       保证二维码/快传/聊天/中转的 hero 与卡片左右边缘完全对齐 —— */
  .mobile-main, #panelXfer.relay-main { max-width: var(--desk-w); width: 100%; margin: 0 auto; padding: 24px 64px 32px !important; row-gap: 24px !important; box-sizing: border-box; }

  /* 外层卡在桌面放开宽度限制（移动端仍是 560 窄列） */
  #mainCard { max-width: var(--desk-w) !important; width: 100%; }

  /* —— 03 桌面按 Codex 数值：两卡各 minHeight 640、内距 32、二维码 272/248；结果卡空态也占位 —— */
  /* 编辑卡不强制 640：否则按钮下方撑出一大片空白，提取码卡被挤到下面。
     左栏改为「编辑卡 + 提取码卡」自然堆叠填满，右栏(结果)保持 640 定高做视觉基准。 */
  #panelQr .editor-card { padding: 32px; box-sizing: border-box; }
  /* 结果卡：空态给足高度做占位（避免右半边空白），有内容后跟随内容不留大片空白 */
  #panelQr #result.card { padding: 32px; box-sizing: border-box; }
  #panelQr #result.card.is-empty { min-height: 560px; }
  #panelQr .pick-card { padding: 24px 32px; }
  #panelQr .editor-card .card-title, #panelQr #result .card-title { font-size: 20px; line-height: 28px; }
  /* 未生成时右栏也保留占位（空态提示），避免右半边整片空白 */
  #panelQr #result.card { display: flex !important; flex-direction: column; }
  /* 空态（#qrArea 无内容）：显示占位提示，标题行留空则隐藏 */
  #panelQr #result.card.is-empty::before { content: attr(data-empty); display: flex; flex: 1 1 auto; align-items: center; justify-content: center;
    text-align: center; padding: 24px; color: var(--text-tertiary); font-size: 14px; line-height: 1.6; white-space: pre-line; }
  #panelQr #result.card.is-empty .res-head { display: none; }
  #panelQr .qr-frame { width: 272px; height: 272px; padding: 12px; }
  #panelQr .qr-frame img, #panelQr .qr-frame .qr-canvas { width: 248px; height: 248px; }
  /* 提取码卡：桌面空间充足 → 默认展开（由 JS 去掉 hidden，状态与 aria 一致），头部收起箭头无意义则隐藏 */
  #panelQr .pick-card.always-open .pick-head .pick-chev, #panelQr .pick-card.always-open .pick-head svg { display: none; }
  #panelQr .pick-card.always-open .pick-head { cursor: default; }

  /* —— 03 二维码：左输入(448) 右结果(624) 双栏 ——
     showTab 会给 #panelQr 内联 display:flex，故这里必须 !important 才能改成 grid */
  #panelQr.mobile-main[style*="display: flex"] { display: grid !important; grid-template-columns: 448px minmax(0, 1fr); gap: 24px; align-content: start; }
  #panelQr > .qr-hero { grid-column: 1 / -1; }          /* hero 通栏 */
  #panelQr > .editor-card, #panelQr > .pick-card { grid-column: 1; }
  #panelQr > #result { grid-column: 2; grid-row: 2 / span 3; align-self: start; }

  /* —— 07 快传：入口两卡并排；房间态 共享文本(480) + 文件(696) —— */
  #p2pHome { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
  /* 手机端 #p2pHome 用 margin 撑间距（早期 display:contents 被内联 display 覆盖的遗留），
     桌面已由 grid gap 统一节奏 → 清掉这些 margin，否则快传的「标题→卡片」比其它页多 12px */
  #p2pHome > .card, #p2pHome > .path-divider { margin-top: 0; margin-bottom: 0; }
  #p2pHome > .qr-hero, #p2pHome > .first-use { grid-column: 1 / -1; }
  /* 快传桌面保持两卡直排；聊天桌面另有正式竖向「或」分隔轨。 */
  #p2pHome > .path-divider { display: none; }
  #p2pHome > * + * { margin-top: 0; }
  #p2pConnected { display: grid; grid-template-columns: minmax(0, 1fr) 480px; gap: 24px; align-items: start; }
  /* 06 合并区（契约 desktop1440：1120×104、两行、房间码在第一行、收藏带字 132×40）。
     选择器必须带 #p2pConnected：本文件后面还有 .connection-hero 的手机规则，
     同权重后者胜 —— 不提高优先级的话桌面这几条压根不生效（本项目已在这坑上摔过三次）。 */
  #p2pConnected > .connection-hero { grid-column: 1 / -1; padding: 12px 16px; }
  #p2pConnected > .connection-hero .room-code-group { display: flex; }
  #p2pConnected > .connection-hero .favorite-device { width: 132px; height: 40px; }
  #p2pConnected > .connection-hero .favorite-device .fav-label { display: inline; font-size: 13px; font-weight: 600; white-space: nowrap; }
  /* 桌面两行：用 grid 把「状态行」与「隐私说明行」放到同一行（不用负边距那种脆弱写法）。
     高度 = 顶行 44 + 第二行 32 + 行距 4 + 上下内距 24 = 104，正好命中契约值。 */
  #p2pConnected > .connection-hero {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "top top" "state privacy";
    align-items: center;
    row-gap: var(--sp-1);
    column-gap: var(--sp-2);
  }
  #p2pConnected > .connection-hero .connection-top { grid-area: top; }
  #p2pConnected > .connection-hero .connection-state-row { grid-area: state; flex-wrap: nowrap; }
  #p2pConnected > .connection-hero .connection-privacy-row { grid-area: privacy; min-height: 0; }
  #p2pWaiting > .page-hero { grid-column: 1 / -1; }
  #p2pConnected > * + * { margin-top: 0; }
  #p2pWaiting { display: grid; grid-template-columns: 480px minmax(0, 1fr); gap: 24px; align-items: start; }
  #p2pWaiting > .page-hero { grid-column: 1 / -1; }
  #p2pWaiting > * + * { margin-top: 0; }
  #p2pWaiting > .room-card { grid-row: span 3; }

  /* —— 37 聊天首页正式桌面规则 ——
     1440: 内容宽 1376；创建约 745 / 分隔轨 48 / 加入约 535，列间各 24。
     ≥1600: 容器封顶 1600、内容宽 1536；创建约 838 / 分隔轨 48 / 加入约 602。
     创建稍重但不另拆「群聊」第三卡：一对一/群聊共享创建门禁与上下文，群聊作为高可见次级动作更清楚。 */
  /* 后文有移动端 #panelChat.chat-main 的 16px 内距；桌面必须显式压过它，
     否则会在 32px 页面安全边距外再叠一层 16px，破坏 1376/1536 精确内容宽。 */
  #panelChat.chat-main { max-width: none; padding: 0 !important; }
  #chatHome.chat-main, #panelChat.chat-main > #chatHome {
    display: grid !important;
    grid-template-columns: minmax(0, 1.28fr) 48px minmax(360px, .92fr);
    column-gap: 24px;
    /* !important：手机版 #chatHome.chat-main{row-gap:8px} 写在本文件更后面（1780 行附近），
       同权重后者胜 → 独立 /chat 页的竖向节奏会掉回 8，和 index 的 24 不一致 */
    row-gap: 24px !important;
    align-items: stretch;
    max-width: var(--desk-w);
    width: 100%;
    margin: 0 auto;
    padding: 24px 64px 32px !important; /* 四页统一左右留白 64（以聊天页原 32 为基准翻倍） */
    box-sizing: border-box;
  }
  #chatHome > .page-hero { grid-column: 1 / -1; }
  #chatHome > #chatCreateBox { grid-column: 1; grid-row: 2; }
  #chatHome > .chat-lock-card { grid-column: 1; grid-row: 2; }
  #chatHome > .path-divider {
    grid-column: 2;
    grid-row: 2;
    display: flex;
    flex-direction: column;
    align-self: stretch;
    width: 48px;
    height: auto;
    min-height: 252px;
    gap: 8px;
  }
  #chatHome > .path-divider .divider-left,
  #chatHome > .path-divider .divider-right {
    width: 1px;
    height: auto;
    min-height: 48px;
    flex: 1 1 auto;
  }
  #chatHome > .path-divider .divider-text {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 36px;
    width: 36px;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: var(--card);
    color: var(--muted);
    font-weight: 600;
    box-shadow: var(--sh-1);
  }
  #chatHome > .join-room-card { grid-column: 3; grid-row: 2; }
  #chatHome > .chat-capabilities { grid-column: 1 / -1; grid-row: 3; }
  #chatHome > .error { grid-column: 1 / -1; grid-row: 4; }
  #chatHome > .create-room-card,
  #chatHome > .join-room-card,
  #chatHome > .chat-lock-card {
    min-height: 252px;
    padding: 24px;
  }
  #chatHome > .create-room-card .chat-create-actions {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(176px, .85fr);
    gap: 12px;
    margin-top: 16px;
  }
  #chatHome > .create-room-card .chat-create-actions .generate-btn,
  #chatHome > .create-room-card .chat-create-actions .group-create-btn {
    width: 100%;
    height: 48px;
    margin-top: 0;
  }
  #chatHome > .join-room-card .chat-join-row { margin-top: 16px; }
  #chatHome > .join-room-card .result-actions { height: 48px; margin-top: 16px; }
  #chatHome > .join-room-card .result-actions button { height: 48px; }
  #chatHome > .chat-lock-card {
    align-items: flex-start;
    justify-content: center;
    flex-direction: column;
    border-color: var(--primary-soft-border);
    background: var(--primary-tint);
  }
  #chatHome > .chat-lock-card .lock-ico { width: 48px; height: 48px; background: var(--card); color: var(--primary); }
  #chatHome > .chat-lock-card .lock-copy { max-width: 620px; color: var(--muted); font-size: 14px; line-height: 1.6; }
  #chatHome.chat-main > * { margin-bottom: 0; }
  #chatPage { max-width: var(--desk-w) !important; }
  /* chat.html 的外壳 .card（我加了 bare 只去掉了皮，宽度仍是移动端 560）——桌面必须放开，
     否则里面的双栏被压在 560 里，看起来就是「没做左右布局」 */
  #panelChat > .card { max-width: none !important; width: 100%; }

  /* —— 13 中转：左上传(696) 右结果/账号(480) —— */
  #panelXfer.relay-main[style*="display: flex"] { display: grid !important; grid-template-columns: minmax(0, 1fr) 480px; gap: 24px; align-content: start; }
  #panelXfer > .page-hero { grid-column: 1 / -1; }
  #panelXfer > .upload-card { grid-column: 1; grid-row: 2 / span 3; }
  #panelXfer > .account-access-card, #panelXfer > .server-banner, #panelXfer > .relay-result-card { grid-column: 2; }
  #panelXfer > .relay-advanced { grid-column: 1 / -1; }

  /* 卡片解除全局 max-width:560（那是移动端窄列的宽度），否则桌面双栏里卡片填不满栏位、
     右边缘和 hero 对不齐；同时让卡片在各自栏位内撑满 */
  .mobile-main .card, .relay-main .card, #chatHome .card { max-width: none; width: auto; }
}

/* ===================================================================
   v1.110 二维码首页 + 外壳 —— 严格对齐 ui/IMPLEMENTATION-SPEC.md（数值真源）
   =================================================================== */
/* ---- 底部导航（COLOR-SPEC §5：条 rgba(255,255,255,.96)，选中项 52×48 圆14 底 #EFF6FF） ---- */
.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; justify-content: center;
  height: calc(var(--tabbar-h) + var(--safe-bottom));
  padding: 0 8px var(--safe-bottom);
  background: var(--bottom-nav-bg); backdrop-filter: blur(12px);
  border-top: 1px solid var(--border); box-shadow: var(--sh-1); }
.tabbar-inner { display: flex; width: 100%; max-width: 560px; }
.nav-cell { flex: 1; display: flex; align-items: center; justify-content: center; }
.tab-item { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  width: 52px; height: 48px; border: none; background: transparent; cursor: pointer; padding: 0;
  border-radius: 14px; color: var(--muted); font-size: 12px; line-height: 16px; font-weight: 500;
  -webkit-tap-highlight-color: transparent; }
.tab-item svg { width: 24px; height: 24px; display: block; }
.tab-item.active { background: var(--primary-tint); color: var(--primary); }

/* 卡片内旧的顶部分段 tab 已被底部导航取代：隐藏（按钮仍在 DOM 供 showTab 逻辑复用） */
.card > .tabs { display: none; }
/* 二维码 tab：外层大卡透明化，让介绍区/编辑卡/结果卡各自独立成卡（其余 tab 仍用大白卡） */
.card.bare { background: transparent; border: none; box-shadow: none; padding: 0; margin-bottom: 0; }
/* 主区 .mobile-main（01/04.spec：flex 列，gap 12，padding 8/16/80；更空旷）。仅当前屏挂类 */
.mobile-main { flex-direction: column; row-gap: 12px; padding: 8px 16px calc(var(--tabbar-h) + var(--safe-bottom) + 32px); box-sizing: border-box; }
.mobile-main .card, .mobile-main .editor-card { margin-bottom: 0; }        /* gap 由 row-gap 提供 */
/* 04 首页卡片间距用 margin，不依赖 display:contents —— 否则 p2pBackHome 给 #p2pHome 设内联 display:block 会覆盖 contents，导致卡片间距塌陷粘在一起 */
#p2pHome > * + * { margin-top: 12px; }
body.mm-tab { padding-left: 0; padding-right: 0; padding-bottom: 0; }
body.mm-tab > h1, body.mm-tab > .subtitle, body.mm-tab > #helpLink { display: none; }

/* ---- Header「使用说明」入口（4.1：88×44，问号 20，仅二维码页显示） ---- */
#helpBtn { display: none; align-items: center; gap: 4px; height: 44px; min-width: 88px; padding: 0 8px;
  border: none; background: none; color: var(--text); font-size: 13px; line-height: 18px; font-weight: 500; cursor: pointer; border-radius: var(--r-sm); }
#helpBtn svg { width: 20px; height: 20px; color: var(--muted); }
body.qr-tab #helpBtn { display: inline-flex; }

/* ---- 紧凑双栏介绍区（01.spec：56 高，左标题·竖分隔·右隐私；实心盾牌徽标 30） ---- */
.qr-hero { display: flex; align-items: center; min-height: 56px; box-sizing: border-box;
  background: var(--primary-tint); border: 1px solid var(--primary-soft-border); border-radius: var(--r-md); padding: 0 12px; }
/* 标题列按内容自适应（原来写死 120px 是按中文「文字二维码」量的，英文 "Text QR Code" 放不下
   会折两行 → 内容 80 高溢出 56 的 hero）。上限 46% 防长文案把状态列挤没。 */
.qr-hero .hero-copy { flex: 0 0 auto; width: auto; max-width: 46%; min-width: 0; padding-right: 4px; }
.qr-hero .hero-title { font-size: 20px; line-height: 24px; font-weight: 600; color: var(--text-strong); }
.qr-hero .hero-subtitle { font-size: 12px; line-height: 16px; color: var(--muted); }
.qr-hero .hero-divider { flex: 0 0 auto; width: 1px; height: 40px; background: var(--divider); margin: 0 8px; }
.qr-hero .hero-status { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; padding-left: 8px; color: var(--primary); }
.qr-hero .status-icon { flex: 0 0 auto; width: 20px; height: 20px; display: flex; }
.qr-hero .status-icon svg { width: 20px; height: 20px; }
.qr-hero .status-icon .ic-cloud { display: none; }
.qr-hero .status-copy { min-width: 0; }
.qr-hero .status-main { font-size: 13px; line-height: 18px; font-weight: 500; color: var(--primary); }
.qr-hero .status-detail { font-size: 12px; line-height: 16px; color: var(--muted); }
.qr-hero.upload { background: var(--warn-tint); border-color: var(--warn-border); }
.qr-hero.upload .hero-status { color: var(--warn); }
.qr-hero.upload .status-icon .ic-shield { display: none; }
.qr-hero.upload .status-icon .ic-cloud { display: block; }
.qr-hero.upload .status-main { color: var(--warn); }

/* ---- 提取码取回卡（final 21：折叠头 48 + 输入/成功/错误态） ---- */
.pick-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); overflow: hidden; }
.pick-head { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 48px; padding: 0 12px;
  border: none; background: none; cursor: pointer; text-align: left; font: inherit; color: var(--text); }
.pick-head .ph-key { flex: 0 0 auto; display: flex; color: var(--muted); }
.pick-head .ph-label { flex: 1 1 auto; font-size: 15px; font-weight: 500; }
.pick-head .ph-chev { flex: 0 0 auto; display: flex; color: var(--muted); transition: transform 160ms; }
.pick-head[aria-expanded="true"] .ph-chev { transform: rotate(180deg); }
.pick-body { padding: 0 12px 12px; }
.pick-body[hidden] { display: none; }
.pick-ilabel { font-size: 14px; line-height: 20px; font-weight: 500; margin: 4px 0 8px; }
.pick-inrow { display: flex; gap: 8px; }
.pick-inrow input { flex: 1 1 auto; min-width: 0; height: 48px; padding: 0 12px; font-size: 16px;
  border: 1px solid #d1d5db; border-radius: var(--r-sm); text-transform: uppercase; font-family: inherit; }
.pick-inrow input:focus { outline: 0; border-color: var(--primary); box-shadow: var(--focus-ring); }
.pick-inrow button { flex: 0 0 auto; min-width: 88px; height: 48px; padding: 0 16px; font-size: 16px; font-weight: 600;
  color: #fff; background: var(--primary); border: none; border-radius: var(--r-sm); cursor: pointer; }
.pick-inrow button:active { background: var(--primary-pressed); }
.pick-hint { font-size: 12px; line-height: 16px; color: var(--muted); margin-top: 8px; }
/* 取回成功卡 */
.pick-ok-head { display: flex; align-items: center; gap: 8px; color: var(--ok); font-size: 15px; font-weight: 600; margin-top: 4px; }
.pick-ok-box { border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px; margin-top: 8px; }
.pick-ok-label { font-size: 13px; color: var(--muted); margin-bottom: 8px; }
.pick-ok-box .pick-text { min-height: 72px; white-space: pre-wrap; word-break: break-word; background: none; border: none; padding: 0; font-size: 14px; line-height: 20px; color: var(--text); }
.pick-ok-actions { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.pick-ok-foot { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ok); }
.pick-ok-copy { min-height: 40px; padding: 0 14px; font-size: 14px; font-weight: 600; color: var(--primary); background: var(--card); border: 1px solid var(--primary); border-radius: var(--r-sm); cursor: pointer; }
/* 取回错误态 */
.pick-err-head { display: flex; align-items: center; gap: 8px; color: var(--danger); font-size: 14px; font-weight: 600; margin-top: 4px; }
.pick-err-sub { font-size: 13px; line-height: 18px; color: var(--muted); margin: 4px 0 12px; }
.pick-err-actions { display: flex; flex-direction: column; gap: 8px; }

/* ---- 编辑卡（01.spec 第5批：白卡 内边距 16、标题 H3、textarea 72、设置行 48、按钮 44） ---- */
.editor-card { box-sizing: border-box; padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.card-title { font-size: 17px; line-height: 24px; font-weight: 600; color: var(--text-strong); }
.editor-card .card-title { margin-bottom: 8px; }
.qe-field { position: relative; }
#panelQr #qrText { width: 100%; min-height: 72px; height: 72px; box-sizing: border-box; }
.char-counter { text-align: right; font-size: 12px; line-height: 16px; color: var(--muted); margin-top: 4px; height: 18px; }
.editor-card .settings-list { margin-top: 8px; border-top: 1px solid var(--divider); }
.editor-card .divider-1, .editor-card .divider-2 { height: 1px; background: var(--divider); }
.generate-btn { display: block; width: 100%; height: 44px; margin-top: 8px; padding: 0 16px; border: none;
  border-radius: var(--r-sm); background: var(--primary); color: #fff; font-size: 16px; font-weight: 600; cursor: pointer; transition: background-color 160ms; }
.generate-btn:hover { background: var(--primary-dark); }
.generate-btn:active { background: var(--primary-pressed); }

/* 设置行（4.6：整行 48 高；历史=36 图标底块，提取码=裸云图标） */
.setting-row { display: flex; align-items: center; gap: 12px; min-height: 48px; }
.setting-row .icon-tile { flex: 0 0 auto; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center;
  background: var(--neutral-100); border-radius: var(--r-sm); color: var(--text); }
.setting-row .setting-icon { flex: 0 0 auto; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; color: var(--warn); }
.setting-row .icon-tile svg, .setting-row .setting-icon svg { width: 24px; height: 24px; }
.setting-row .setting-text { flex: 1 1 auto; min-width: 0; }
.setting-row .setting-label { font-size: 16px; line-height: 20px; font-weight: 500; color: var(--text); }
.setting-row .setting-helper { font-size: 12px; line-height: 16px; color: var(--muted); margin-top: 2px; }

/* iOS 开关：checkbox 自身即轨道（44×26），::after 为圆点（COLOR-SPEC §4） */
.ios-switch { appearance: none; -webkit-appearance: none; position: relative; flex: 0 0 auto; margin: 0;
  width: 44px; height: 26px; border-radius: var(--r-pill); background: var(--input-border, #d1d5db); cursor: pointer; transition: background-color 160ms ease; }
.ios-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 22px; height: 22px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgb(15 23 42 / 24%); transition: transform 160ms ease; }
.ios-switch:checked { background: var(--primary); }
.ios-switch:checked::after { transform: translateX(18px); }
.ios-switch:focus-visible { box-shadow: var(--focus-ring); }

/* ---- 结果卡「已生成」（01.spec：QR 框 192 白、码 168/144、提取码 28、按钮 44） ---- */
.result { text-align: left; padding: 16px; }
.res-head { display: flex; align-items: center; justify-content: space-between; min-height: 28px; margin-bottom: 12px; }
.result-card .card-title { margin: 0; }
.status-badge { display: inline-flex; align-items: center; height: 24px; padding: 0 8px; font-size: 12px; line-height: 16px; font-weight: 500;
  border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); }
.status-badge:empty { display: none; }
.status-badge.green { background: var(--ok-tint); color: var(--ok); }
#qrArea { display: flex; flex-direction: column; align-items: center; }
.qr-frame { position: relative; width: 144px; height: 144px; box-sizing: border-box; margin-top: 8px; padding: 0; background: #fff; border-radius: var(--r-sm); display: flex; align-items: center; justify-content: center; }
.qr-frame img.qr-canvas { width: 144px; height: 144px; display: block; }
.qr-frame .qr-brand { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); width: 23px; height: 23px; padding: 3px; background: #fff; border-radius: 6px; color: var(--primary); }
/* 提取码行（52 高：标签 64 + 代码 28/700 + 复制 44） */
.res-pick { align-self: stretch; margin-top: 12px; }
.res-pick .rp-top { display: flex; align-items: center; gap: 8px; min-height: 44px; }
.res-pick .rp-label { flex: 0 0 64px; font-size: 13px; line-height: 18px; color: var(--muted); }
.res-pick .rp-code { flex: 1 1 auto; text-align: center; font-size: 28px; line-height: 36px; font-weight: 700; letter-spacing: .08em; color: var(--primary); }
.res-pick .rp-copy { flex: 0 0 44px; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: none; background: none; color: var(--primary); cursor: pointer; }
.res-pick .rp-sub { font-size: 12px; line-height: 16px; color: var(--muted); margin-top: 4px; }
.result-actions { align-self: stretch; display: flex; gap: 8px; margin-top: 8px; }
.result-actions button { flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; font-size: 16px; font-weight: 600; border: 1px solid var(--primary);
  background: var(--card); color: var(--primary); border-radius: var(--r-sm); cursor: pointer; transition: background-color 160ms; }
.result-actions button svg { width: 18px; height: 18px; flex: 0 0 auto; }
.result-actions button:hover { background: var(--primary-tint); }
.result-actions button:active { background: var(--primary-tint-pressed); }
.res-del { align-self: center; min-height: 44px; margin-top: 8px; background: none; border: none; color: var(--danger); font-size: 14px; font-weight: 500; cursor: pointer; }
.res-del:disabled { opacity: .5; cursor: default; }
.privacy-footer { align-self: center; display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 13px; line-height: 18px; color: var(--ok); }
.privacy-footer svg { width: 18px; height: 18px; flex: 0 0 auto; }
.privacy-footer.muted { color: var(--muted); }

/* ===================================================================
   快传 04 · 创建/加入入口（对齐 04.spec.yaml）
   =================================================================== */
/* 快传页 .mobile-main：04 首页 row-gap 12；05 房间态挂 .mm-room → row-gap 8 */
#panelP2p.mobile-main { padding-top: 4px; row-gap: 12px; }
#panelP2p.mobile-main.mm-room { row-gap: 8px; }

/* 顶部合并区 transfer-hero（358×140，放宽版）：hero-summary(88 上标题+副标题、下隐私一行) + hero-steps(52 三步) */
.qr-hero.transfer-hero { box-sizing: border-box; min-height: 140px; padding: 0; flex-direction: column; align-items: stretch; gap: 0;
  background: var(--primary-tint); border: 1px solid var(--primary-soft-border); border-radius: var(--r-md); overflow: hidden; }
.transfer-hero .hero-summary { box-sizing: border-box; min-height: 88px; display: flex; flex-direction: column; justify-content: center; row-gap: 4px; padding: 12px; }
.transfer-hero .hero-copy { width: auto; max-width: none; display: flex; flex-direction: column; row-gap: 4px; }
.transfer-hero .hero-title { font-size: 20px; line-height: 24px; font-weight: 600; letter-spacing: -.01em; color: var(--text-strong); }
.transfer-hero .hero-subtitle { font-size: 13px; line-height: 16px; color: var(--muted); }
.transfer-hero .hero-status { display: flex; align-items: center; column-gap: 8px; height: 16px; }
.transfer-hero .status-icon { flex: 0 0 auto; display: flex; width: 16px; height: 16px; color: var(--primary); }
.transfer-hero .status-icon svg { width: 16px; height: 16px; }
.transfer-hero .status-main { flex: 0 0 auto; font-size: 12px; line-height: 16px; font-weight: 600; color: var(--primary); }
.transfer-hero .status-divider { flex: 0 0 auto; width: 1px; height: 16px; background: var(--primary-soft-border); }
.transfer-hero .status-detail { font-size: 12px; line-height: 16px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.transfer-hero .hero-steps { box-sizing: border-box; min-height: 52px; display: flex; align-items: center; justify-content: space-between; padding: 0 12px;
  background: var(--card); border-top: 1px solid var(--primary-soft-border); }
.hero-steps .step { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-width: 96px; min-height: 52px; }
.hero-steps .step-number { width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); font-size: 12px; font-weight: 500; }
.hero-steps .step-text { font-size: 12px; line-height: 16px; color: var(--text); }
.hero-steps .step-line { flex: 0 0 auto; width: 16px; height: 1px; background: var(--primary-soft-border); }

/* 创建/加入卡片（放宽版）：card-header(48) = card-icon(40) + card-copy(标题+副标题, gap4) */
.create-room-card, .join-room-card { box-sizing: border-box; padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.join-room-card { min-height: 220px; }
.create-room-card .card-header, .join-room-card .card-header { display: flex; align-items: center; gap: 8px; height: 48px; }
.create-room-card .card-icon, .join-room-card .card-icon { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-sm); background: var(--primary-tint); color: var(--primary); }
.create-room-card .card-icon svg, .join-room-card .card-icon svg { width: 22px; height: 22px; }
.create-room-card .card-copy, .join-room-card .card-copy { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; row-gap: 4px; }
.create-room-card .card-title, .join-room-card .card-title { font-size: 16px; line-height: 24px; font-weight: 600; color: var(--text-strong); }
.create-room-card .card-subtitle, .join-room-card .card-subtitle { font-size: 13px; line-height: 16px; color: var(--muted); }

.feature-list { box-sizing: border-box; height: 72px; border: 1px solid var(--border); background: var(--surface-2); border-radius: var(--r-sm); padding: 0 12px; margin-top: 12px; }
.feature-list .feature { box-sizing: border-box; display: flex; align-items: center; gap: 8px; height: 36px; font-size: 13px; color: var(--text); }
.feature-list .feature + .feature { border-top: 1px solid var(--border); }
.feature-list .feature-ico { flex: 0 0 auto; display: flex; color: var(--primary); }
.feature-list .feature-ico svg { width: 18px; height: 18px; }
.create-room-card .generate-btn { width: 100%; height: 48px; margin-top: 12px; }
.card-helper { font-size: 12px; line-height: 16px; color: var(--muted); margin-top: 4px; }

.path-divider { display: flex; align-items: center; justify-content: center; gap: 8px; height: 24px; font-size: 12px; color: var(--muted); }
.path-divider .divider-left, .path-divider .divider-right { flex: 1 1 auto; height: 1px; background: var(--border); }

/* 房间码：一个真输入框铺在两个展示格之上（焦点不移动 → iOS 不会重挑输入法）。
   真输入框透明、承接键盘/粘贴/退格；两个 .code-cell 只负责显示字符。 */
.room-code-input { position: relative; display: flex; gap: 8px; width: 112px; height: 44px; margin: 12px auto 0; } /* 2 格 = 2×52 + 8 */
.room-code-input .code-input {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2;
  border: 0; background: transparent; color: transparent; caret-color: transparent;
  text-align: center; font-size: 22px; letter-spacing: 30px; text-indent: 30px;
  -webkit-text-fill-color: transparent; outline: none; padding: 0;
}
.room-code-input .code-cell { width: 52px; height: 44px; text-align: center; font-size: 22px; font-weight: 600; text-transform: uppercase;
  border: 1px solid var(--input-border, #d1d5db); border-radius: var(--r-sm); background: var(--card); color: var(--text); font-family: inherit; box-sizing: border-box; }
/* 焦点态画在展示格上：真输入框获得焦点时，当前该输入的那一格高亮 */
.room-code-input .code-cell.is-active { border-color: var(--primary); box-shadow: var(--focus-ring); }
.join-room-card .result-actions { display: flex; gap: 8px; height: 44px; margin-top: 12px; }
.join-room-card .join-btn, .join-room-card .scan-room-btn { flex: 1 1 0; box-sizing: border-box; display: flex; align-items: center; justify-content: center; gap: 8px; height: 44px; padding: 0;
  border: 1px solid var(--primary); background: var(--card); color: var(--primary); border-radius: var(--r-sm); font-size: 15px; font-weight: 600; cursor: pointer; }
.join-room-card .join-btn:hover, .join-room-card .scan-room-btn:hover { background: var(--primary-tint); }
.join-room-card .scan-room-btn svg { width: 18px; height: 18px; }

/* 只让文字本身可点：原来是撑满整行的 flex，点很远的空白也会命中（用户实测） */
.first-use { display: flex; align-items: center; justify-content: center; gap: 6px; height: 44px; width: fit-content; max-width: 100%; margin-left: auto; margin-right: auto; padding: 0 8px; background: transparent; color: var(--primary); font-size: 13px; font-weight: 500; text-decoration: none; cursor: pointer; }
.first-use svg { width: 20px; height: 20px; }

/* ===================================================================
   快传 05 · 等待对方（房间等待态，对齐 05.spec.yaml）
   =================================================================== */
/* #p2pRoom 是 .mobile-main 的直接块级子项；间距同 04（基础 padding-top 4 / row-gap 8），卡片间用 margin 8 */
#p2pRoom > * + * { margin-top: 8px; }
#p2pWaiting > * + *, #p2pConnected > * + * { margin-top: 8px; }
/* hidden 属性必须真隐藏（否则被 .qr-link 等 display 规则盖过，占位露出 raw link） */
[hidden] { display: none !important; }
/* 当前显示的状态容器（等待/已连接）贴着顶部，hero 不吃 * + * 的上边距（前面有隐藏的 status/link 兄弟） */
#p2pRoom > #p2pWaiting, #p2pRoom > #p2pConnected { margin-top: 0; }
/* 当前显示的首块不吃 * + * 的 8px 上边距（06 合并后首块类名换成了 .connection-hero） */
#p2pConnected > .connection-hero, #p2pConnected > .page-hero, #p2pWaiting > .page-hero { margin-top: 0; }
/* 契约给的显式排序：合并区 0 → 文件核心卡 1 → 共享文本 2 */
#p2pConnected > .connection-hero { order: 0; }
#p2pConnected > .file-transfer-card { order: 1; }
#p2pConnected > .shared-text-card { order: 2; }
/* 统一 hero 页头（.page-hero）：标题+副标题+隐私一行，浅底卡；05/06 各带修饰类 */
.page-hero { box-sizing: border-box; background: var(--primary-tint); border: 1px solid var(--primary-soft-border); border-radius: var(--r-md); }
.page-hero .hero-copy { display: flex; flex-direction: column; row-gap: 4px; min-width: 0; }
.page-hero .hero-title { font-size: 20px; line-height: 24px; font-weight: 600; letter-spacing: -.01em; color: var(--text-strong); }
.page-hero .hero-subtitle { font-size: 13px; line-height: 16px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.page-hero .hero-status { display: flex; align-items: center; column-gap: 8px; height: 16px; }
.page-hero .status-icon { flex: 0 0 auto; display: flex; width: 16px; height: 16px; color: var(--primary); }
.page-hero .status-icon svg { width: 16px; height: 16px; }
.page-hero .status-main { flex: 0 0 auto; font-size: 12px; line-height: 16px; font-weight: 600; color: var(--primary); }
.page-hero .status-divider { flex: 0 0 auto; width: 1px; height: 16px; background: var(--primary-soft-border); }
.page-hero .status-detail { font-size: 12px; line-height: 16px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 05 等待 hero：上「标题+副标题」+右「取消」，下隐私一行（88） */
.waiting-hero { min-height: 88px; padding: 12px; display: flex; flex-wrap: wrap; align-items: flex-start; column-gap: 8px; row-gap: 4px; }
.waiting-hero .hero-copy { flex: 1 1 auto; min-width: 0; }
.waiting-hero .cancel-room-btn {
  flex: 0 0 auto;
  width: 80px;
  height: 44px;
  padding: 0 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: var(--card);
  border: 1px solid var(--danger-button-border);
  border-radius: var(--r-sm);
  color: var(--danger);
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 160ms, border-color 160ms;
}
.waiting-hero .cancel-room-btn .cancel-icon {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  background: currentColor;
  -webkit-mask: url("/icons/x.svg") center / 16px 16px no-repeat;
  mask: url("/icons/x.svg") center / 16px 16px no-repeat;
}
.waiting-hero .cancel-room-btn:hover { background: var(--danger-tint); }
.waiting-hero .cancel-room-btn:active { background: var(--danger-tint-pressed); }
.waiting-hero .cancel-room-btn:focus-visible { outline: 0; box-shadow: var(--focus-ring); }
/* 隐私行换到第二行并占满：不这样的话它会和标题+按钮挤在同一行被截（06 加退出按钮后出现过） */
.waiting-hero .hero-status { flex: 1 0 100%; }

.room-card { box-sizing: border-box; padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); text-align: center; }
.room-card .room-label { font-size: 13px; line-height: 18px; color: var(--muted); text-align: left; }
.room-card .room-code-row { display: flex; align-items: center; justify-content: center; gap: 8px; height: 48px; }
.room-card .room-code { font-size: 40px; line-height: 48px; font-weight: 700; letter-spacing: 3.2px; color: var(--primary); }
.room-card .room-code-copy { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--primary); cursor: pointer; }
.room-card .room-code-copy svg { width: 20px; height: 20px; }
.room-card .room-helper { font-size: 12px; line-height: 16px; color: var(--muted); }
.room-card .room-qr { width: 184px; height: 184px; margin: 12px auto 0; background: #fff; border-radius: var(--r-sm); position: relative; display: flex; align-items: center; justify-content: center; }
.room-card .room-qr img { width: 184px; height: 184px; display: block; }
.room-card .qr-brand { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); width: 36px; height: 36px; background: #fff; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--primary); }
.room-card .qr-brand svg { width: 24px; height: 24px; }
.room-card .room-caption { font-size: 13px; line-height: 18px; color: var(--muted); margin-top: 8px; }
.room-card .room-actions { display: flex; gap: 8px; height: 48px; margin-top: 12px; }
.room-card .share-invite-btn, .room-card .copy-code-btn { flex: 1 1 0; box-sizing: border-box; display: flex; align-items: center; justify-content: center; gap: 8px; height: 48px; border-radius: var(--r-sm); font-size: 15px; font-weight: 600; cursor: pointer; }
.room-card .share-invite-btn { background: var(--primary); border: 0; color: #fff; }
.room-card .copy-code-btn { background: var(--card); border: 1px solid var(--primary); color: var(--primary); }
.room-card .share-invite-btn svg, .room-card .copy-code-btn svg { width: 18px; height: 18px; }
.room-card .copy-link-btn { display: flex; align-items: center; justify-content: center; gap: 8px; height: 44px; margin-top: 8px; box-sizing: border-box; background: var(--card); border: 1px solid var(--primary); color: var(--primary); border-radius: var(--r-sm); font-size: 15px; font-weight: 600; text-decoration: none; cursor: pointer; }
.room-card .copy-link-btn svg { width: 18px; height: 18px; }

.join-steps-card { box-sizing: border-box; padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.join-steps-card .steps-title { font-size: 16px; line-height: 22px; font-weight: 600; color: var(--text-strong); }
.join-steps-card .step-open, .join-steps-card .step-transfer, .join-steps-card .step-enter { display: flex; align-items: center; gap: 8px; height: 32px; font-size: 13px; color: var(--text); }
.join-steps-card .step-idx { flex: 0 0 auto; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); font-size: 12px; font-weight: 600; }
.join-steps-card .step-code { font-weight: 700; color: var(--primary); }

/* 高度用 min-height：写死 44 + overflow:hidden 时，桌面下两项文字换行需要 76px，会被裁掉一半 */
.feature-card { box-sizing: border-box; min-height: 44px; display: flex; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1); overflow: hidden; }
.feature-card .multi-file-feature, .feature-card .shared-text-feature { flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 4px 8px; font-size: 13px; color: var(--text); }
.feature-card .shared-text-feature { border-left: 1px solid var(--border); }
.feature-card .f-ico { display: flex; color: var(--primary); }
.feature-card .f-ico svg { width: 20px; height: 20px; }

.privacy-banner { box-sizing: border-box; height: 48px; display: flex; align-items: center; gap: 8px; padding: 0 12px;
  background: var(--primary-tint); border: 1px solid var(--primary-soft-border); border-radius: var(--r-md); color: var(--primary); font-size: 13px; font-weight: 500; }
.privacy-banner .pb-ico { flex: 0 0 auto; display: flex; }
.privacy-banner svg { width: 20px; height: 20px; }

/* ===================================================================
   快传 06 · 已连接态（连接卡 / 共享文本卡 / 多文件卡，对齐 06.spec.yaml）
   =================================================================== */
/* 状态胶囊（供 06 及后续复用） */
.status-pill { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 10px; border-radius: var(--r-pill); font-size: 12px; font-weight: 600; white-space: nowrap; }
.status-pill svg { width: 16px; height: 16px; }
.status-pill .pill-ico { display: flex; }
.status-pill.ok { background: var(--ok-tint); color: var(--ok); }
.status-pill.brand { background: var(--primary-tint); color: var(--primary); }
.status-pill.danger { background: var(--danger-tint); color: var(--danger); }
.status-pill.warn { background: var(--warn-tint); color: var(--warn); }
.status-pill.wait { background: var(--neutral-100); color: var(--text-tertiary); }

/* 连接卡 */
.connection-card { box-sizing: border-box; min-height: 64px; padding: 12px; background: var(--card); border: 1px solid var(--ok-border); border-radius: var(--r-md); box-shadow: var(--sh-1); }
.connection-card .conn-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 连接方式徽标（直连绿 / 中转蓝 / 等待黄）+ 说明行——让用户一眼知道走不走服务器 */
.connection-hero .route-badge { display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 8px; border-radius: var(--r-pill); font-size: 12px; font-weight: 600; white-space: nowrap; }
.connection-hero .route-badge svg { width: 14px; height: 14px; }
.connection-hero .route-badge.ok { background: var(--ok-tint); color: var(--ok); }
.connection-hero .route-badge.brand { background: var(--primary-tint); color: var(--primary); }
.connection-hero .route-badge.warn { background: var(--warn-tint); color: var(--warn); }
.connection-hero .route-badge.danger { background: var(--danger-tint); color: var(--danger); }
.connection-card .conn-detail { font-size: 12px; line-height: 16px; color: var(--muted); margin-top: 4px; }
.connection-card .encryption-pill { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 10px; border-radius: var(--r-pill); font-size: 12px; background: var(--ok-tint); color: var(--ok); white-space: nowrap; }
.connection-card .encryption-pill svg { width: 16px; height: 16px; }
.connection-card .conn-bottom { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.connection-card .conn-room { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* 手机端连上之后不再显示房间码：连上了就没用了，而这块位置本来就挤（用户反馈「显示太多内容」）。
   桌面空间充足则保留（房间码由 syncConnRoomCode() 两端都写对，此前加入方显示的是 HTML 占位假码）。 */
@media (max-width: 1023px) { .connection-card .conn-room { display: none; } }
.connection-card .conn-label { font-size: 13px; color: var(--muted); }
.connection-card .room-code { font-size: 24px; line-height: 32px; font-weight: 700; letter-spacing: 2px; color: var(--primary); }
.connection-card .copy-code-btn { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--primary); cursor: pointer; }
.connection-card .copy-code-btn svg { width: 20px; height: 20px; }
.connection-card .peer-device { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--ok); white-space: nowrap; }
.connection-card .peer-device svg { width: 18px; height: 18px; }

/* 共享文本卡 / 多文件卡 通用头 */
.shared-text-card, .file-transfer-card { box-sizing: border-box; padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.shared-text-card .card-head, .file-transfer-card .card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.shared-text-card .card-title, .file-transfer-card .card-title { display: inline-flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 600; color: var(--text-strong); }
.shared-text-card .card-title .ct-ico, .file-transfer-card .card-title .ct-ico { display: flex; color: var(--primary); }
.shared-text-card .card-title .ct-ico svg, .file-transfer-card .card-title .ct-ico svg { width: 20px; height: 20px; }

/* 共享文本编辑器 */
.shared-editor { display: block; width: 100%; box-sizing: border-box; min-height: 112px; padding: 12px; border: 1px solid var(--primary); border-radius: var(--r-sm); background: var(--card); color: var(--text); font-family: inherit; font-size: 14px; line-height: 1.5; resize: vertical; }
.shared-editor:focus { outline: 0; box-shadow: var(--focus-ring); }
.shared-text-card .card-helper { margin-top: 8px; }
.shared-text-card .result-actions { display: flex; gap: 8px; margin-top: 12px; }
.shared-text-card .copy-all-btn, .shared-text-card .clear-text-btn { flex: 1 1 0; box-sizing: border-box; display: flex; align-items: center; justify-content: center; gap: 8px; height: 44px; border-radius: var(--r-sm); font-size: 15px; font-weight: 600; cursor: pointer; background: var(--card); }
.shared-text-card .copy-all-btn { border: 1px solid var(--primary); color: var(--primary); }
.shared-text-card .clear-text-btn { border: 1px solid var(--danger-button-border); color: var(--danger); }
.shared-text-card .copy-all-btn svg, .shared-text-card .clear-text-btn svg { width: 18px; height: 18px; }

/* 多文件卡 */
/* 添加更多文件：底部整条实心 CTA（核心操作） */
.file-transfer-card .add-files-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; box-sizing: border-box; height: 44px; margin-top: 8px; border: 0; border-radius: var(--r-sm); background: var(--primary); color: #fff; font-size: 15px; font-weight: 600; cursor: pointer; }
.file-transfer-card .add-files-btn svg { width: 18px; height: 18px; }
.file-transfer-card .xfer-total { margin-bottom: 8px; }
.file-transfer-card .transfer-summary { height: 20px; font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 6px; }
.progress-track { height: 6px; background: var(--progress-track); border-radius: var(--r-pill); overflow: hidden; }
.progress-track .progress-value { height: 6px; background: var(--progress); border-radius: var(--r-pill); transition: width .2s; }

/* 文件行（addP2pItem 生成，真实传输驱动 meta/进度） */
.file-rows { display: flex; flex-direction: column; }
.file-row { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; min-height: 60px; padding: 12px 0; border-top: 1px solid var(--divider); }
.file-row:first-child { border-top: 0; }
.file-row .file-icon { flex: 0 0 auto; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-sm); }
.file-row .file-icon svg { width: 24px; height: 24px; }
/* 收敛颜色：文件图标一律浅蓝底 + 品牌蓝图标，靠形状区分类型（不再红橙紫灰） */
.file-icon--pdf, .file-icon--archive, .file-icon--video, .file-icon--text, .file-icon--file { background: var(--primary-tint); color: var(--primary); }
.file-row .file-body { flex: 1 1 0; min-width: 0; }
.file-row .file-name { font-size: 14px; font-weight: 500; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-row .file-meta { font-size: 12px; color: var(--muted); margin-top: 2px; word-break: break-word; }
/* 文件行进度条：仅进行中态显示（纯 data-state 驱动，避免 JS 时序残留灰条） */
.file-row .progress { display: none; height: 6px; margin-top: 6px; background: var(--progress-track); border-radius: var(--r-pill); overflow: hidden; }
.file-row[data-state="sending"] .progress, .file-row[data-state="receiving"] .progress,
.file-row[data-state="flushing"] .progress, .file-row[data-state="resuming"] .progress { display: block; }
.file-row .progress > div { height: 100%; width: 0; background: var(--progress); border-radius: var(--r-pill); transition: width .2s; }
.file-row > a, .file-row > button { flex: 1 0 100%; margin-left: 48px; margin-top: 2px; align-self: flex-start; }
/* 保存文件 / 下载动作 */
.file-row .file-action, .file-row > a.file-action { color: var(--primary); font-size: 13px; font-weight: 600; text-decoration: none; cursor: pointer; }

/* ===================================================================
   中转 12 · 文件中转（对齐 12.spec.yaml）
   =================================================================== */
#panelXfer.relay-main { flex-direction: column; row-gap: 8px; padding: 4px 16px calc(var(--tabbar-h) + var(--safe-bottom) + 32px); box-sizing: border-box; }
#panelXfer.relay-main > * { margin-bottom: 0; }
.relay-hero { height: 88px; padding: 12px; display: flex; flex-direction: column; justify-content: center; row-gap: 4px; }

.account-access-card { box-sizing: border-box; height: 64px; padding: 0 12px; display: flex; align-items: center; gap: 12px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1); }
.account-access-card .avatar { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); }
.account-access-card .avatar svg { width: 24px; height: 24px; }
.account-access-card .account-copy { flex: 1 1 auto; min-width: 0; }
.account-access-card .account-status { font-size: 13px; font-weight: 500; color: var(--text-strong); }
.account-access-card .account-name { font-size: 12px; color: var(--muted); }
.account-access-card .status-badge, .relay-result-card .status-badge { flex: 0 0 auto; gap: 4px; background: var(--ok-tint); color: var(--ok); }
.account-access-card .status-badge svg, .relay-result-card .status-badge svg { width: 16px; height: 16px; }

/* 中转未开放：徽标转灰 + 「去升级」按钮 + 上传卡整体禁用（但页面照常可见，让用户先看清功能） */
.account-access-card .status-badge.locked { background: var(--neutral-100); color: var(--muted); }
.account-access-card .relay-unlock-btn { flex: 0 0 auto; height: 32px; padding: 0 12px; margin-left: 4px;
  background: var(--primary); border: 0; border-radius: var(--r-sm); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer; }
.upload-card.locked { position: relative; }
.upload-card.locked > *:not(.locked-hint) { opacity: .45; pointer-events: none; }
.upload-card.locked::after { content: attr(data-locked-hint); position: absolute; left: 16px; right: 16px; bottom: 16px;
  padding: 10px 12px; box-sizing: border-box; background: var(--warn-tint); border: 1px solid var(--warn-border); border-radius: var(--r-sm);
  color: var(--warn); font-size: 12px; line-height: 1.45; text-align: center; }

.server-banner { box-sizing: border-box; min-height: 64px; padding: 12px; display: flex; align-items: center; gap: 12px; background: var(--primary-tint); border: 1px solid var(--primary-soft-border); border-radius: var(--r-md); }
.server-banner .sb-ico { flex: 0 0 auto; display: flex; color: var(--primary); }
.server-banner .sb-ico svg { width: 28px; height: 28px; }
.server-banner .banner-title { font-size: 13px; font-weight: 500; color: var(--primary); }
.server-banner .banner-helper { font-size: 12px; color: var(--muted); margin-top: 2px; }

.upload-card { box-sizing: border-box; padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.upload-card .card-title { font-size: 16px; font-weight: 600; color: var(--text-strong); }
.upload-card .drop-zone { box-sizing: border-box; width: 100%; height: 112px; margin-top: 12px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; background: var(--surface-2); border: 1px dashed var(--primary-soft-border); border-radius: var(--r-md); color: var(--primary); font-size: 13px; font-weight: 500; cursor: pointer; }
.upload-card .drop-zone .dz-ico { display: flex; }
.upload-card .drop-zone .dz-ico svg { width: 32px; height: 32px; }
.upload-card .drop-helper { font-size: 12px; color: var(--muted); margin-top: 6px; text-align: center; }
#relayFileList { margin-top: 8px; }
#relayFileList:empty { display: none; }
#relayFileList .file-row { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 8px 0; border-top: 1px solid var(--divider); }
#relayFileList .file-row:first-child { border-top: 0; }
#relayFileList .file-icon { flex: 0 0 auto; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-sm); background: var(--primary-tint); color: var(--primary); }
#relayFileList .file-icon svg { width: 24px; height: 24px; }
#relayFileList .file-body { flex: 1 1 0; min-width: 0; }
#relayFileList .file-name { font-size: 14px; font-weight: 500; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#relayFileList .file-meta { font-size: 12px; color: var(--muted); }
.upload-card .remove-file-btn { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--muted); cursor: pointer; }
.upload-card .remove-file-btn svg { width: 18px; height: 18px; }
.upload-card .add-more-btn { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; height: 44px; margin-top: 4px; background: transparent; border: 0; color: var(--primary); font-size: 13px; font-weight: 600; cursor: pointer; }
.upload-card .add-more-btn svg { width: 18px; height: 18px; }
.upload-card .field-label { font-size: 13px; font-weight: 500; color: var(--text); margin-top: 12px; }
.upload-card .retention-control { display: flex; width: 100%; box-sizing: border-box; height: 44px; margin-top: 8px; padding: 4px; background: var(--neutral-100); border: 1px solid var(--border); border-radius: var(--r-sm); gap: 4px; }
.upload-card .retention-control button { flex: 1 1 0; height: 100%; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--text); font-size: 13px; font-weight: 500; cursor: pointer; }
.upload-card .retention-control button.active { background: var(--primary); color: #fff; }
.upload-card .access-code-row { display: flex; align-items: center; gap: 8px; height: 48px; margin-top: 12px; padding: 0 12px; box-sizing: border-box; background: var(--card); border: 1px solid var(--input-border, #d1d5db); border-radius: var(--r-sm); }
.upload-card .access-code-row .ac-ico { flex: 0 0 auto; display: flex; color: var(--muted); }
.upload-card .access-code-row .ac-ico svg { width: 20px; height: 20px; }
.upload-card .access-code-row input { flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent; font-family: inherit; font-size: 14px; color: var(--text); }
.upload-card .generate-btn { width: 100%; height: 48px; margin-top: 12px; }

.relay-result-card { box-sizing: border-box; min-height: 176px; padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.relay-result-card .card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.relay-result-card .card-title { display: inline-flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 600; color: var(--text-strong); }
.relay-result-card .card-title .ct-ico.ok { display: flex; color: var(--ok); }
.relay-result-card .card-title .ct-ico svg { width: 20px; height: 20px; }
.relay-result-card .relay-url-row { display: flex; align-items: center; gap: 8px; }
.relay-result-card .relay-url { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; height: 44px; padding: 0 12px; box-sizing: border-box; background: var(--primary-tint); border: 1px solid var(--primary-soft-border); border-radius: var(--r-sm); color: var(--primary); font-size: 13px; font-weight: 500; text-decoration: none; }
.relay-result-card .relay-url .ru-ico { flex: 0 0 auto; display: flex; }
.relay-result-card .relay-url .ru-ico svg { width: 18px; height: 18px; }
.relay-result-card .relay-url span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.relay-result-card .copy-url-btn { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--primary); cursor: pointer; }
.relay-result-card .copy-url-btn svg { width: 18px; height: 18px; }
.relay-result-card .relay-expiry { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); margin-top: 8px; }
.relay-result-card .relay-expiry svg { width: 16px; height: 16px; }
.relay-result-card .result-actions { display: flex; gap: 8px; height: 44px; margin-top: 12px; }
.relay-result-card .copy-link-btn, .relay-result-card .delete-now-btn { flex: 1 1 0; box-sizing: border-box; display: flex; align-items: center; justify-content: center; gap: 8px; height: 44px; border-radius: var(--r-sm); background: var(--card); font-size: 15px; font-weight: 600; cursor: pointer; }
.relay-result-card .copy-link-btn { border: 1px solid var(--primary); color: var(--primary); }
.relay-result-card .delete-now-btn { border: 1px solid var(--danger-button-border); color: var(--danger); }
.relay-result-card .copy-link-btn svg, .relay-result-card .delete-now-btn svg { width: 18px; height: 18px; }

/* ===================================================================
   聊天 08 · 匿名聊天（home 用统一 hero + 建/加入卡；房间态会话卡/气泡）
   =================================================================== */
#panelChat.chat-main { flex-direction: column; row-gap: 8px; padding: 4px 16px 80px; box-sizing: border-box; }
#panelChat.chat-main > #chatHome { display: contents; }
/* 聊天等待态（套 05 设计）：hero 里已有标题/副文案/取消，旧的橙色状态行与底部原生「取消」在此状态下多余 → 隐藏。
   注意只在等待态隐藏：连接中/重连等状态 #chatQrBox 是 none，#chatStatus 照常显示（诊断信息不能丢）。 */
#chatRoom:has(> #chatQrBox:not([style*="display: none"])) > .p2p-status,
#chatRoom:has(> #chatQrBox:not([style*="display: none"])) > div > #chatCancel { display: none; }
#chatQrBox > * + * { margin-top: 8px; }
#chatQrBox .room-card { text-align: center; }
/* ===== 通用确认弹窗（破坏性操作前拦一道：取消房间 / 退出聊天 / 退群）===== */
.confirm-modal { max-width: 340px; text-align: left; }
.confirm-overlay { z-index: 4000; }
.confirm-modal h2 { margin: 0 0 8px; font-size: 17px; font-weight: 600; color: var(--text-strong); }
.confirm-modal .confirm-body { font-size: 14px; line-height: 1.5; color: var(--muted); }
.confirm-modal .confirm-actions { display: flex; gap: 8px; margin-top: 20px; }
.confirm-modal .confirm-actions button { flex: 1 1 0; box-sizing: border-box; height: 44px; border-radius: var(--r-sm);
  font-size: 15px; font-weight: 600; font-family: inherit; cursor: pointer; }
.confirm-modal .confirm-cancel { background: var(--card); border: 1px solid var(--border); color: var(--text); }
.confirm-modal .confirm-cancel:hover { background: var(--surface-2); }
.confirm-modal .confirm-ok { background: var(--primary); border: 0; color: #fff; }
.confirm-modal .confirm-ok.danger { background: var(--danger); }
.confirm-modal .confirm-ok:focus-visible { outline: 0; box-shadow: var(--focus-ring); }

/* 等待态在 #chatRoom 里（不是 #chatHome），要自己补左右留白 + 底部给底栏让位，否则卡片贴边 */
#chatRoom { box-sizing: border-box; padding: 4px 16px 80px; }
body.in-chat #chatRoom { padding: 0; } /* 进入聊天全屏后由 #chatWrap 接管，不要这层内边距 */

/* chat.html 的底部导航用 <a> 跳页（非同页切 tab），去掉链接下划线，与 index 的 <button> 观感一致 */
.bottom-nav a.tab-item { text-decoration: none; }
/* chat.html（独立聊天页）首页：#chatHome 自己当弹性列（index 里则由 #panelChat 承担）
   左右要留 16 内边距、底部留出底部导航高度，否则卡片贴边、且被底栏压住 */
#chatHome.chat-main { display: flex; flex-direction: column; row-gap: 8px; box-sizing: border-box; padding: 4px 16px 80px; }
#chatHome.chat-main > * { margin-bottom: 0; }
/* 群聊创建按钮：次级描边（弱于 1对1 的实心 CTA） */
.create-room-card .chat-create-actions { display: flex; flex-direction: column; }
.create-room-card .group-create-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; box-sizing: border-box; height: 44px; margin-top: 8px;
  background: var(--card); border: 1px solid var(--primary); border-radius: var(--r-sm); color: var(--primary); font-size: 15px; font-weight: 600; cursor: pointer; }
.create-room-card .group-create-btn svg,
.create-room-card .group-create-btn img { width: 18px; height: 18px; }
/* 未登录/未开通提示卡 */
.chat-lock-card { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1); }
.chat-lock-card .lock-ico { flex: 0 0 auto; display: flex; width: 36px; height: 36px; align-items: center; justify-content: center; border-radius: var(--r-sm); background: var(--neutral-100); color: var(--muted); }
.chat-lock-card .lock-ico svg,
.chat-lock-card .lock-ico img { width: 20px; height: 20px; }
.chat-lock-card .lock-copy { flex: 1 1 auto; font-size: 13px; line-height: 1.45; color: var(--muted); }
.chat-hero { height: 88px; padding: 12px; display: flex; flex-direction: column; justify-content: center; row-gap: 4px; }
.chat-hero .status-icon img { width: 16px; height: 16px; }
.create-room-card .chat-lan-row { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 13px; color: var(--text); }
.create-room-card .chat-lan-row .ios-switch { flex: 0 0 auto; }
.chat-join-row { margin-top: 12px; }
.chat-join-row input { width: 100%; box-sizing: border-box; height: 48px; padding: 0 12px; text-align: center; font-size: 20px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  border: 1px solid var(--input-border, #d1d5db); border-radius: var(--r-sm); background: var(--card); color: var(--text); font-family: inherit; }
.chat-join-row input::placeholder { font-size: 14px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--text-tertiary); }
.create-room-card .chat-lan-row { line-height: 1.35; }
.chat-join-row input:focus { outline: 0; border-color: var(--primary); box-shadow: var(--focus-ring); }
.join-room-card .result-actions { display: flex; gap: 8px; height: 44px; margin-top: 12px; }
.create-room-card .card-icon img,
.join-room-card .card-icon img { width: 22px; height: 22px; }
.join-room-card .scan-room-btn img { width: 18px; height: 18px; }

/* 内容较少的桌面首页补一条能力说明；手机 844 高内保持现有紧凑入口，不增加滚动负担。 */
.chat-capabilities { display: none; }
@media (min-width: 1024px) {
  .chat-capabilities {
    display: grid;
    grid-template-columns: minmax(260px, .8fr) minmax(0, 2.2fr);
    gap: 24px;
    align-items: center;
    min-height: 116px;
    padding: 16px 24px;
    border: 1px solid var(--primary-soft-border);
    border-radius: var(--r-lg);
    background: var(--primary-tint);
    box-sizing: border-box;
  }
  .chat-capabilities-head { display: flex; align-items: center; gap: 12px; }
  .capabilities-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 44px;
    height: 44px;
    border-radius: var(--r-md);
    background: var(--card);
    box-shadow: var(--sh-1);
  }
  .capabilities-mark img { width: 22px; height: 22px; }
  .chat-capabilities-head > span:last-child,
  .chat-capability-grid article > span { display: grid; gap: 2px; }
  .chat-capabilities strong { color: var(--text-strong); font-size: 14px; line-height: 20px; }
  .chat-capabilities small { color: var(--muted); font-size: 12px; line-height: 18px; }
  .chat-capability-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
  .chat-capability-grid article {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
    min-height: 64px;
    padding: 10px 12px;
    border: 1px solid var(--primary-soft-border);
    border-radius: var(--r-md);
    background: var(--card);
    box-sizing: border-box;
  }
  .chat-capability-grid article > img { flex: 0 0 20px; width: 20px; height: 20px; }
}

/* 房间态：会话卡（对端 + 通话入口） */
.chat-session-card { box-sizing: border-box; height: 72px; padding: 12px; display: flex; align-items: center; gap: 8px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1); }
.chat-session-card .avatar { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); }
.chat-session-card .avatar svg { width: 24px; height: 24px; }
.chat-session-card .session-copy { flex: 1 1 0; min-width: 0; }
.chat-session-card .peer-name { font-size: 15px; font-weight: 500; color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-session-card .status-pill { height: 20px; margin-top: 2px; font-size: 12px; font-weight: 500; }
.chat-session-card .phone-btn, .chat-session-card .video-btn { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-pill); color: var(--primary); cursor: pointer; }
.chat-session-card .more-btn { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; border-radius: var(--r-pill); color: var(--text); cursor: pointer; }
.chat-session-card button svg { width: 20px; height: 20px; }

/* ===== 聊天房间 08 / 群聊 09·10：全屏态(body.in-chat)重皮成卡片式 ===== */
/* 会话卡：白底 + 返回 + 头像 + 名/状态胶囊 + 语音/视频/成员（替代旧深蓝顶栏） */
body.in-chat .chat-topbar.chat-session-card { display: flex; align-items: center; gap: 8px; height: auto; min-height: 64px;
  padding: calc(10px + var(--safe-top)) 12px 10px; background: var(--card); color: var(--text);
  border: 0; border-bottom: 1px solid var(--border); border-radius: 0; box-shadow: none; flex: 0 0 auto; }
body.in-chat .chat-session-card .back-btn { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: var(--r-pill); color: var(--text); cursor: pointer; }
body.in-chat .chat-session-card .back-btn svg { width: 24px; height: 24px; }
body.in-chat .chat-session-card .avatar { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); }
body.in-chat .chat-session-card .avatar svg { width: 24px; height: 24px; }
body.in-chat .chat-session-card .session-copy { flex: 1 1 0; min-width: 0; }
body.in-chat .chat-session-card .ct-name { font-size: 15px; font-weight: 600; color: var(--text-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.in-chat .chat-session-card .ct-conn { margin-top: 2px; height: 20px; font-size: 12px; font-weight: 500; }
body.in-chat .chat-session-card .ct-conn:empty { display: none; }
body.in-chat .chat-session-card .phone-btn, body.in-chat .chat-session-card .video-btn { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-pill); color: var(--primary); cursor: pointer; }
body.in-chat .chat-session-card .more-btn { flex: 0 0 auto; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: var(--r-pill); color: var(--text); cursor: pointer; }
body.in-chat .chat-session-card button svg { width: 20px; height: 20px; }

/* 消息气泡（08）：收=白底描边、发=品牌蓝；最大宽 272 */
body.in-chat .chat-log.message-list { background: var(--bg); padding: 12px 16px; gap: 12px; }
body.in-chat .chat-msg { max-width: 272px; padding: 12px; border-radius: var(--r-md); font-size: 14px; line-height: 1.45; }
body.in-chat .chat-msg.peer { background: var(--card); border: 1px solid var(--border); color: var(--text); border-bottom-left-radius: 6px; }
body.in-chat .chat-msg.mine { background: var(--primary); color: #fff; border-bottom-right-radius: 6px; }

/* 输入条（08 composer）：图片 + 药丸输入 + 圆形发送 */
body.in-chat .chat-input.chat-composer { display: flex; align-items: center; gap: 8px; min-height: 64px;
  padding: 10px 16px calc(10px + var(--safe-bottom)); background: var(--card); border-top: 1px solid var(--border); }
body.in-chat .chat-composer .add-btn { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  padding: 0; background: transparent; border: 0; border-radius: var(--r-pill); color: var(--primary); cursor: pointer; }
body.in-chat .chat-composer .add-btn svg { width: 24px; height: 24px; }
body.in-chat .chat-composer .add-btn:disabled { opacity: .45; cursor: default; }
body.in-chat .chat-composer .message-input { flex: 1 1 auto; min-width: 0; box-sizing: border-box; min-height: 44px; max-height: 120px; padding: 11px 14px;
  background: var(--card); border: 1px solid var(--input-border, #d1d5db); border-radius: var(--r-pill); font-size: 14px; line-height: 20px; font-family: inherit; color: var(--text); resize: none; }
body.in-chat .chat-composer .message-input:focus { outline: 0; border-color: var(--primary); box-shadow: var(--focus-ring); }
body.in-chat .chat-composer .send-btn { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  padding: 0; background: var(--primary); border: 0; border-radius: var(--r-pill); color: #fff; cursor: pointer; }
body.in-chat .chat-composer .send-btn svg { width: 22px; height: 22px; }
body.in-chat .chat-composer .send-btn:disabled { opacity: .45; cursor: default; }

/* 群聊：邀请条 + 加入审批（09）——审批做成醒目卡片行 */
body.in-chat #gcBar { flex: 0 0 auto; padding: 8px 16px; background: var(--bg); border-bottom: 1px solid var(--divider); }
body.in-chat #gcInvite { font-size: 12px; color: var(--muted); word-break: break-all; }
.gc-req { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 10px 12px; margin-top: 8px;
  background: var(--warn-tint); border: 1px solid var(--warn-border); border-radius: var(--r-md); }
.gc-req .gc-req-name { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 500; color: var(--warn); }
.gc-req .gc-ok, .gc-req .gc-no { flex: 0 0 auto; height: 36px; padding: 0 14px; border-radius: var(--r-sm); font-size: 13px; font-weight: 600; cursor: pointer; }
.gc-req .gc-ok { background: var(--primary); border: 0; color: #fff; }
.gc-req .gc-no { background: var(--card); border: 1px solid var(--danger-button-border); color: var(--danger); }

/* 群成员（10）：成员行 + 在线/离线 + 重命名/移出 */
body.in-chat #gcMembersPanel { flex: 0 0 auto; max-height: 45vh; overflow-y: auto; padding: 8px 16px; background: var(--bg); border-bottom: 1px solid var(--divider); }
.member-list { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1); overflow: hidden; }
.gc-mem { display: flex; align-items: center; gap: 10px; min-height: 56px; padding: 8px 14px; border-top: 1px solid var(--divider); font-size: 14px; color: var(--text); }
.gc-mem:first-child { border-top: 0; }
.gc-mem .gc-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--ok); }
.gc-mem .gc-dot.off { background: var(--text-tertiary); }
.gc-mem .gc-copy, .gc-mem .gc-kick { flex: 0 0 auto; height: 32px; padding: 0 10px; border-radius: var(--r-sm); font-size: 12px; font-weight: 600; cursor: pointer; background: var(--card); }
.gc-mem .gc-copy { border: 1px solid var(--border); color: var(--text); }
.gc-mem .gc-kick { border: 1px solid var(--danger-button-border); color: var(--danger); }

/* ===== 通话 11：深色全屏 + 上下布景 + 控制坞（真源图标，替代原 emoji 圆钮）===== */
#callOverlay.call-screen { background: #101826; }
#callOverlay .remote-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #0b1220; }
#callOverlay .top-scrim, #callOverlay .bottom-scrim { position: absolute; left: 0; right: 0; pointer-events: none; }
#callOverlay .top-scrim { top: 0; height: 236px; background: linear-gradient(180deg, rgb(8 12 20 / 72%), transparent); }
#callOverlay .bottom-scrim { bottom: 0; height: 304px; background: linear-gradient(0deg, rgb(8 12 20 / 82%), transparent); }
/* 视频接通态：顶部信息避开右上角本地小窗（小窗最宽 130 + 边距），否则加密胶囊被压住 */
#callOverlay .call-header { z-index: 2; }
#callOverlay.connected.video #callCenter { align-items: flex-start; padding: 0 152px 0 16px; }
#callOverlay.connected.video .call-conn, #callOverlay.connected.video .call-timer { text-align: left; }
#callOverlay .call-avatar { width: 96px; height: 96px; display: flex; align-items: center; justify-content: center;
  background: rgb(255 255 255 / 14%); border-radius: var(--r-pill); color: #fff; }
#callOverlay .call-avatar svg { width: 44px; height: 44px; }
#callOverlay .peer-name { font-size: 18px; font-weight: 600; color: #fff; }
#callOverlay .call-conn { background: rgb(255 255 255 / 14%); color: #a7f3d0; height: 24px; }
#callOverlay .call-conn:empty { display: none; }
#callOverlay .call-timer { font-size: 13px; color: rgb(255 255 255 / 75%); }
/* 本地小窗 + 「我」标签 */
#callLocalWrap.local-preview { border: 1px solid rgb(255 255 255 / 18%); z-index: 2; }
#callLocalWrap .local-label { position: absolute; left: 6px; bottom: 6px; height: 20px; padding: 0 8px; display: inline-flex; align-items: center;
  background: rgb(8 12 20 / 70%); color: #fff; border-radius: var(--r-pill); font-size: 12px; font-weight: 500; }
/* 控制坞：圆角深色容器 + 图标圆钮（麦/摄像头=品牌蓝，关闭态转深灰；挂断=红） */
#callControls.call-controls { z-index: 2; gap: 24px; padding: 12px 16px calc(12px + var(--safe-bottom));
  background: rgb(16 24 38 / 72%); backdrop-filter: blur(8px); border-radius: var(--r-xl) var(--r-xl) 0 0; }
#callControls .call-ctl button, #callIncoming .call-ctl button { width: 56px; height: 56px; border-radius: var(--r-pill); border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center; background: var(--primary); color: #fff; font-size: 0; transform: none; }
#callControls .call-ctl button svg, #callIncoming .call-ctl button svg { width: 26px; height: 26px; }
#callControls .call-ctl button.off { background: rgb(255 255 255 / 18%); }
#callControls .call-hang button, #callIncoming .decline { background: var(--danger); }
#callIncoming .accept { background: var(--ok); }
#callControls .call-ctl span, #callIncoming .call-ctl span { font-size: 12px; color: rgb(255 255 255 / 85%); }
#callIncoming .call-avatar { width: 56px; height: 56px; display: flex; align-items: center; justify-content: center;
  background: rgb(255 255 255 / 14%); border-radius: var(--r-pill); color: #fff; }
#callIncoming .call-avatar svg { width: 26px; height: 26px; }

/* ===== 12/13 CLI Advanced：折叠头、代码块、token 与文件列表 ===== */
.relay-advanced {
  width: 100%;
  max-width: 560px;
  box-sizing: border-box;
  margin-top: 4px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--sh-1);
}
.relay-advanced > summary {
  min-height: 64px;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  list-style: none;
  cursor: pointer;
  color: var(--text);
  background: var(--card);
  -webkit-tap-highlight-color: transparent;
}
.relay-advanced > summary::-webkit-details-marker { display: none; }
.relay-advanced > summary:hover { background: var(--surface-2); }
.relay-advanced > summary:focus-visible {
  outline: none;
  box-shadow: inset var(--focus-ring);
}
.relay-summary-icon,
.relay-group-icon,
.hint-icon,
.xfer-empty-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--primary);
  background: var(--primary-tint);
}
.relay-summary-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
}
.relay-summary-icon img,
.relay-group-icon img { width: 22px; height: 22px; }
.relay-summary-copy {
  min-width: 0;
  flex: 1 1 auto;
  display: grid;
  gap: var(--sp-1);
}
.relay-summary-copy strong {
  color: var(--text-strong);
  font-size: 15px;
  line-height: 20px;
  font-weight: 600;
}
.relay-summary-copy > span {
  color: var(--muted);
  font-size: 12px;
  line-height: 16px;
}
.relay-summary-chevron {
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  border-radius: var(--r-pill);
  transition: transform 180ms ease;
}
.relay-summary-chevron img { width: 20px; height: 20px; }
.relay-advanced[open] .relay-summary-chevron { transform: rotate(180deg); }
.relay-advanced-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-3);
  padding: var(--sp-3);
  border-top: 1px solid var(--border);
  background: var(--bg);
}
.relay-advanced-group {
  min-width: 0;
  padding: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
}
.relay-group-title {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.relay-group-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
}
.relay-group-title > div,
.xfer-files-head > div {
  min-width: 0;
  display: grid;
  gap: var(--sp-1);
}
.relay-group-title strong,
.xfer-files-head strong {
  color: var(--text-strong);
  font-size: 16px;
  line-height: 22px;
  font-weight: 600;
}
.relay-group-title div > span,
.xfer-files-head div > span {
  color: var(--muted);
  font-size: 12px;
  line-height: 16px;
}
.xfer-cmd {
  position: relative;
  min-height: 116px;
  margin-top: var(--sp-3);
  overflow: hidden;
  border: 1px solid var(--code-border);
  border-radius: var(--r-sm);
  background: var(--code-bg);
}
.xfer-code-scroll {
  width: 100%;
  min-height: 116px;
  padding: 64px var(--sp-3) var(--sp-4);
  overflow-x: auto;
  overscroll-behavior-x: contain;
}
.xfer-cmd code {
  display: block;
  width: max-content;
  min-width: 100%;
  color: var(--code-text);
  font-family: ui-monospace, "SFMono-Regular", "Cascadia Code", "Roboto Mono", monospace;
  font-size: 13px;
  line-height: 20px;
  white-space: nowrap;
}
.xfer-copy-btn {
  position: absolute;
  z-index: 1;
  top: var(--sp-2);
  right: var(--sp-2);
  min-width: 120px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 0 var(--sp-3);
  border: 1px solid var(--code-control-hover);
  border-radius: var(--r-sm);
  background: var(--code-control);
  color: var(--code-text);
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  cursor: pointer;
}
.xfer-copy-btn:hover,
.xfer-copy-btn.copied { background: var(--code-control-hover); }
.xfer-copy-btn img { width: 18px; height: 18px; }
.xfer-copy-btn:focus-visible,
.xfer-reset-btn:focus-visible,
.xfer-refresh-btn:focus-visible,
.xfer-file-action:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.xfer-hints {
  display: grid;
  gap: var(--sp-2);
  margin: var(--sp-3) 0 0;
  padding: 0;
  list-style: none;
}
.xfer-hints li {
  min-height: 28px;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--text);
  font-size: 13px;
  line-height: 18px;
}
.hint-icon {
  width: 28px;
  height: 28px;
  border-radius: var(--r-pill);
}
.hint-icon img { width: 16px; height: 16px; }
.xfer-token-row {
  min-height: 60px;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding: var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}
.xfer-rotate-line {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--muted);
  font-size: 12px;
  line-height: 16px;
}
.xfer-rotate-line img { width: 18px; height: 18px; flex: 0 0 auto; }
.xfer-reset-btn {
  min-width: 128px;
  height: 44px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 0 var(--sp-3);
  border: 1px solid var(--danger-button-border);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--danger);
  font-size: 13px;
  line-height: 18px;
  font-weight: 600;
  cursor: pointer;
}
.xfer-reset-btn:hover { background: var(--danger-tint); border-color: var(--danger); }
.xfer-reset-btn:active { background: var(--danger-tint-pressed); }
.xfer-reset-btn img { width: 18px; height: 18px; }
.xfer-danger-helper {
  margin-top: var(--sp-1);
  color: var(--danger);
  font-size: 12px;
  line-height: 16px;
  text-align: right;
}
.xfer-files-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
}
.xfer-refresh-btn {
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--text);
  cursor: pointer;
}
.xfer-refresh-btn:hover { color: var(--primary); background: var(--surface-2); }
.xfer-refresh-btn:active { background: var(--neutral-pressed); }
.xfer-refresh-btn img { width: 20px; height: 20px; }
.xfer-files-note {
  min-height: 40px;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--primary-tint);
  color: var(--muted);
  font-size: 12px;
  line-height: 16px;
}
.xfer-files-note img { width: 18px; height: 18px; flex: 0 0 auto; }
.xfer-file-list {
  margin-top: var(--sp-3);
  overflow: hidden;
  border: 1px solid var(--divider);
  border-radius: var(--r-sm);
  background: var(--card);
}
.xfer-file-row {
  min-height: 64px;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2);
  border-bottom: 1px solid var(--divider);
}
.xfer-file-row:last-child { border-bottom: 0; }
.xfer-file-row .file-icon {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-sm);
}
.xfer-file-row .file-icon img { width: 24px; height: 24px; }
.xfer-file-row.file-row .file-icon { color: var(--file-text); background: var(--file-text-soft); }
.xfer-file-row.pdf-row .file-icon { color: var(--file-pdf); background: var(--file-pdf-soft); }
.xfer-file-row.archive-row .file-icon { color: var(--file-archive); background: var(--file-archive-soft); }
.xfer-file-row.text-row .file-icon { color: var(--file-text); background: var(--file-text-soft); }
.xfer-file-copy { min-width: 0; flex: 1 1 auto; }
.xfer-file-copy .file-name {
  overflow: hidden;
  color: var(--text);
  font-size: 13px;
  line-height: 18px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.xfer-file-copy .file-meta {
  margin-top: 2px;
  color: var(--muted);
  font-size: 12px;
  line-height: 16px;
}
.xfer-file-actions { flex: 0 0 auto; display: flex; gap: var(--sp-1); }
.xfer-file-action {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--primary);
  cursor: pointer;
}
.xfer-file-action.danger {
  color: var(--danger);
  border-color: var(--danger-button-border);
}
.xfer-file-action:hover { background: var(--surface-2); }
.xfer-file-action.danger:hover { background: var(--danger-tint); border-color: var(--danger); }
.xfer-file-action img { width: 18px; height: 18px; }
.xfer-empty {
  min-height: 108px;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
}
.xfer-empty-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--r-md);
}
.xfer-empty-icon img { width: 24px; height: 24px; }
.xfer-empty-copy { min-width: 0; display: grid; gap: var(--sp-1); }
.xfer-empty-copy strong {
  color: var(--text-strong);
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
}
.xfer-empty-copy span {
  color: var(--muted);
  font-size: 12px;
  line-height: 16px;
}
.xfer-load-error .xfer-empty-icon { color: var(--danger); background: var(--danger-tint); }
.xfer-load-error { cursor: pointer; }
@media (min-width: 1024px) {
  /* 桌面容器宽度：随视口增长，上限 1600（大屏不再只占中间一小条；要调宽窄只改这一行） */
  :root { --desk-w: min(1600px, 100%); }
  /* 「使用说明」在桌面顶栏常驻：原来只在二维码 tab 显示(body.qr-tab)，切到快传/聊天/中转就消失了。
     桌面顶栏空间充足，应任何 tab 都能点开说明。（手机顶栏窄，仍保持只在二维码 tab 显示） */
  #helpBtn { display: inline-flex !important; }
  .relay-advanced {
    max-width: 1200px;
    margin-left: auto;
    margin-right: auto;
  }
  .relay-advanced > summary { min-height: 72px; padding: var(--sp-4) var(--sp-6); }
  .relay-advanced-body {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-6);
    padding: var(--sp-6);
  }
  .relay-advanced-group { padding: var(--sp-6); }
  .xfer-cmd,
  .xfer-code-scroll { min-height: 132px; }
}

/* 06 状态胶囊示例态（供文件行右侧手工/演示态用） */
.file-row .status-pill { flex: 0 0 auto; align-self: center; }

/* 房间过渡态：点「创建/加入房间」后立刻出现，直到 created/joined 回来（真机/弱网可能等 1~3 秒）。
   以前这段时间房间容器是 8px 高的空白、状态文字又在隐藏容器里，看着像点了没反应。 */
.room-loading {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
  min-height: 88px;
  box-sizing: border-box;
}
.room-loading .rl-spinner {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%;
  border: 3px solid var(--primary-tint); border-top-color: var(--primary);
  animation: deviceOrbit .8s linear infinite;
}
.room-loading .rl-copy { display: grid; gap: 2px; min-width: 0; flex: 1 1 auto; }
/* 取消按钮：与等待态/已连接态同一套危险描边样式（80×44，中文「取消」两字够放） */
.room-loading .rl-cancel {
  flex: 0 0 auto; width: 80px; height: 44px; padding: 0 var(--sp-2);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1);
  background: var(--card); border: 1px solid var(--danger-button-border); border-radius: var(--r-sm);
  color: var(--danger); font-size: 13px; font-weight: 600; white-space: nowrap; cursor: pointer;
}
.room-loading .rl-cancel:hover { background: var(--danger-tint); }
.room-loading .rl-cancel:focus-visible { outline: 0; box-shadow: var(--focus-ring); }
.room-loading .rl-cancel .cancel-icon {
  width: 14px; height: 14px; background: currentColor;
  -webkit-mask: url(/icons/x.svg) center/14px 14px no-repeat; mask: url(/icons/x.svg) center/14px 14px no-repeat;
}
.room-loading strong { font-size: 16px; line-height: 24px; font-weight: 600; color: var(--text-strong); }
.room-loading small { font-size: 12px; line-height: 18px; color: var(--muted); }
@media (prefers-reduced-motion: reduce) { .room-loading .rl-spinner { animation: none; } }

/* ===== 06（第 21 批契约）：合并后的「连接上下文区」 =====
   原来是「hero 90 + 连接卡 189」两块、「已连接」出现 3 次、到主任务卡 343px；
   现在合并成一块（手机 132 / 桌面 104），状态只在胶囊出现一次，到主任务卡 手机 200 / 桌面 188。 */
.connection-hero {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-3);
  background: var(--primary-tint);
  border: 1px solid var(--primary-soft-border);
  border-radius: var(--r-md);
}
.connection-hero .connection-top { display: flex; align-items: center; gap: var(--sp-2); min-height: 44px; }
.connection-hero .connection-identity { display: flex; flex-direction: column; gap: var(--sp-1); flex: 1 1 auto; min-width: 0; }
.connection-hero .screen-title { font-size: 18px; line-height: 22px; font-weight: 600; color: var(--text-strong); }
.connection-hero .peer-device-name {
  display: flex; align-items: center; gap: var(--sp-1); min-width: 0;
  font-size: 13px; line-height: 18px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.connection-hero .peer-device-name svg { flex: 0 0 auto; width: 16px; height: 16px; color: var(--muted); }
/* 收藏：未收藏=可点描边钮；已收藏=状态展示（不可点，取消收藏去「我的设备」） */
.connection-hero .favorite-device {
  flex: 0 0 auto; width: 44px; height: 44px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1);
  border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card);
  color: var(--text); cursor: pointer;
}
.connection-hero .favorite-device img { width: 20px; height: 20px; }
.connection-hero .favorite-device .fav-label { display: none; }
.connection-hero .favorite-device .favorite-filled { display: none; }
.connection-hero .favorite-device:hover { background: var(--primary-tint); border-color: var(--primary); }
.connection-hero .favorite-device:focus-visible { outline: 0; box-shadow: var(--focus-ring); }
.connection-hero .favorite-device[aria-pressed="true"] {
  background: var(--primary-tint); border-color: var(--primary-soft-border); color: var(--primary); cursor: default;
}
.connection-hero .favorite-device[aria-pressed="true"] .favorite-empty { display: none; }
.connection-hero .favorite-device[aria-pressed="true"] .favorite-filled { display: inline-block; }
/* 退出房间：契约给 80×44，但中文「退出房间」四字放不下（会折成两行）→ 104 宽 */
.connection-hero .cancel-room-btn {
  flex: 0 0 auto; width: 104px; height: 44px; padding: 0 var(--sp-2);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1);
  background: var(--card); border: 1px solid var(--danger); border-radius: var(--r-sm);   /* 契约：--qd-danger 强红 */
  color: var(--danger); font-size: 13px; font-weight: 600; white-space: nowrap; cursor: pointer;
}
.connection-hero .cancel-room-btn .cancel-icon {
  flex: 0 0 auto; width: 16px; height: 16px; background: currentColor;
  -webkit-mask: url(/icons/x.svg) center/16px 16px no-repeat; mask: url(/icons/x.svg) center/16px 16px no-repeat;
}
.connection-hero .cancel-room-btn:hover { background: var(--danger-tint); }
.connection-hero .cancel-room-btn:active { background: var(--danger-tint-pressed); }
.connection-hero .cancel-room-btn:focus-visible { outline: 0; box-shadow: var(--focus-ring); }
.connection-hero .connection-state-row { display: flex; align-items: center; gap: var(--sp-2); min-height: 24px; flex-wrap: wrap; }
.connection-hero .room-code-group { display: none; align-items: center; gap: 6px; margin-left: auto; }
.connection-hero .room-code-label { font-size: 11px; line-height: 16px; color: var(--muted); white-space: nowrap; }
.connection-hero .room-code { font-size: 13px; line-height: 18px; font-weight: 600; letter-spacing: .04em; color: var(--primary); }
.connection-hero .copy-code-btn {
  width: 40px; height: 40px; padding: 0; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--primary); cursor: pointer;
}
.connection-hero .copy-code-btn svg { width: 18px; height: 18px; }
.connection-hero .connection-privacy-row {
  display: flex; align-items: center; gap: var(--sp-2); min-height: 32px; flex-wrap: wrap;
  font-size: 12px; line-height: 16px; color: var(--muted);
}
.connection-hero .privacy-divider { flex: 0 0 auto; width: 1px; height: 16px; background: var(--primary-soft-border); }
.connection-hero .encryption-detail { display: inline-flex; align-items: center; gap: var(--sp-1); color: var(--primary); font-weight: 500; }
.connection-hero .encryption-detail svg { width: 16px; height: 16px; }
/* 状态胶囊四态：绿=已连接 / 蓝=重连中 / 红=对方离开 / 琥珀=等待局域网直连（配色策略见契约 statusColorPolicy） */
.connection-hero .connection-status-pill svg { width: 16px; height: 16px; }
/* 胶囊图标按状态换：四态都用「✓」的话，「重连中」显示对勾语义错、颜色也怪（用户实测反馈）。
   用 mask + currentColor，图标自动跟随胶囊配色。 */
.connection-hero .connection-status-pill .pill-ico {
  flex: 0 0 auto; width: 16px; height: 16px; background: currentColor;
  -webkit-mask: url(/icons/check-circle-filled.svg) center/16px 16px no-repeat;
  mask: url(/icons/check-circle-filled.svg) center/16px 16px no-repeat;
}
.connection-hero[data-connection-state="reconnecting"] .connection-status-pill .pill-ico {
  -webkit-mask-image: url(/icons/refresh.svg); mask-image: url(/icons/refresh.svg);
  animation: deviceOrbit 1.1s linear infinite;
}
.connection-hero[data-connection-state="peerLeft"] .connection-status-pill .pill-ico {
  -webkit-mask-image: url(/icons/alert-filled.svg); mask-image: url(/icons/alert-filled.svg);
}
.connection-hero[data-connection-state="lanWaiting"] .connection-status-pill .pill-ico {
  -webkit-mask-image: url(/icons/clock.svg); mask-image: url(/icons/clock.svg);
}
@media (prefers-reduced-motion: reduce) { .connection-hero .connection-status-pill .pill-ico { animation: none; } }

/* ===== 06 纠正版：文件核心卡 + 折叠共享文本 ===== */
/* 历史注记（v1.138.0 起 .active-hero 结构已废弃，改为 .connection-hero 合并区）：
   这条曾写 flex-direction:column + height:88，位置在前面 .waiting-hero 之后
   → 把那条的 row + wrap 压掉了。加退出按钮后表现为「按钮和隐私行被排到右边、隐私文字被截」
   （column + wrap = 换列而不是换行）。现在与 05 等待态统一：横向排列 + 允许换行，
   标题列自适应、隐私行占满第二行；高度用 min-height 以容纳英文两行文案。 */
/* 多文件卡为核心：更重阴影 + 品牌浅边 + 核心徽标 + 20px 标题 */
.file-transfer-card.core { border-color: var(--primary-soft-border); box-shadow: var(--sh-2); }
.file-transfer-card .card-title { font-size: 20px; }
.file-transfer-card .core-badge { display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: var(--r-pill); background: var(--primary-tint); color: var(--primary); font-size: 12px; font-weight: 600; white-space: nowrap; }
/* 文件列表容器（有内容才显示） */
.file-list { box-sizing: border-box; border: 1px solid var(--divider); border-radius: var(--r-sm); margin-top: 8px; padding: 0 12px; max-height: 240px; overflow-y: auto; }
.file-list:empty { display: none; }
.file-list .file-row { padding: 8px 0; min-height: 52px; }
/* 折叠共享文本（附属功能） */
.shared-text-card .shared-toggle-head { cursor: pointer; }
.shared-text-card.collapsed .card-head { margin-bottom: 0; }
.shared-toggle-head .card-title { font-size: 15px; font-weight: 600; }
.shared-text-card .ct-ico.muted { color: var(--text-tertiary); }
.shared-toggle-head .card-helper { margin-left: auto; margin-right: 4px; font-size: 12px; color: var(--muted); }
.shared-text-card .collapse-toggle { flex: 0 0 auto; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--muted); cursor: pointer; transition: transform .2s; }
.shared-text-card .collapse-toggle svg { width: 20px; height: 20px; }
.shared-text-card:not(.collapsed) .collapse-toggle { transform: rotate(180deg); }
.shared-text-card.collapsed .shared-body { display: none; }
.shared-text-card:not(.collapsed) .shared-toggle-head .card-helper { display: none; }

/* ---- 三色状态胶囊（供快传等后续复用） ---- */
.status-pill { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 8px; border-radius: var(--r-pill); font-size: 12px; font-weight: 500; }
.status-pill.ok { background: var(--ok-tint); color: var(--ok); }
.status-pill.connecting { background: var(--warn-tint); color: var(--warn); }
.status-pill.off { background: var(--danger-tint); color: var(--danger); }

/* 契约排序：#p2pHome(hero+三步+创建/加入)=1 → 我的设备/设备连接态=3 → 使用说明=4 */
#panelP2p > #p2pHome { order: 1; }
#panelP2p > .devices-empty-nudge,
#panelP2p > .my-devices-shell,
#panelP2p > .my-device-state { order: 3; }
#panelP2p > .first-use { order: 4; }

/* ===== 17 · 我的设备（第 20 批重做）=====
   契约要点：①零收藏只留一行 44px 提示，外壳整块隐藏（主任务不下移）
   ②「开始新连接」是动作 → 描边按钮、在标题行、位于 tablist 之外，绝不做成页签
   ③页签是独立圆角卡片（不再是浏览器式贴边页签框），状态用「文字 + 颜色点」双通道 */
.devices-empty-nudge {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  min-height: 44px;
  margin-top: var(--sp-4);
  padding: var(--sp-1) var(--sp-3);
  flex-wrap: wrap;   /* 桌面把隐私说明摊开时可能两行，别被 44 卡死 */
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-2);   /* = qd-neutral-50 #f8fafc */
  color: var(--muted);
  font-size: 12px;
  line-height: 18px;
  box-sizing: border-box;
}
.devices-empty-nudge > img { width: 18px; height: 18px; opacity: .75; }
.devices-empty-nudge > span[data-i18n] { flex: 1; min-width: 0; }
.devices-empty-nudge .privacy-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--primary);
  cursor: pointer;
}
.devices-empty-nudge .privacy-trigger:hover { background: var(--primary-tint); }
.devices-empty-nudge .privacy-trigger img { width: 16px; height: 16px; }
.devices-empty-nudge .privacy-tip {
  position: absolute;
  z-index: 30;
  right: 8px;
  bottom: calc(100% + 6px);
  width: 240px;
  padding: var(--sp-2);
  border-radius: var(--r-sm);
  background: var(--text-strong);
  color: #fff;
  font-size: 11px;
  line-height: 16px;
  box-shadow: var(--sh-2);
}
.my-devices-shell {
  position: relative;
  display: block;                   /* 契约：块级 + 各行显式 margin（gap 会把隐私说明的 8 也撑成 12） */
  width: 100%;
  margin-top: var(--sp-6);          /* 契约 24（--sp-5 在本项目不存在，曾落空成 0） */
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
  box-sizing: border-box;
}
.my-devices-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  min-height: 48px;
}
.my-devices-title { color: var(--text-strong); font-size: 16px; line-height: 24px; font-weight: 700; }
.my-devices-subtitle { color: var(--muted); font-size: 12px; line-height: 18px; }
/* 动作按钮：描边可点视觉，不与页签混淆 */
.device-new-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
  width: 128px;                     /* 契约手机 128×36；桌面覆盖成 144×40 */
  height: 36px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--primary);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--primary);
  font-size: 13px;
  line-height: 18px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.device-new-action:hover { background: var(--primary-tint); }
.device-new-action img { width: 16px; height: 16px; }
.device-tab-scroll {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-width: 0;
  min-height: 48px;
  margin-top: var(--sp-3);          /* 契约 12 */
  overflow-x: auto;                 /* 契约把横向滚动放在轨道上 */
  scrollbar-width: none;
}
.device-tab-scroll::-webkit-scrollbar { display: none; }
.device-tabs-scroll {
  display: flex;
  align-items: stretch;
  gap: var(--sp-2);
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
}
.device-tabs-scroll::-webkit-scrollbar { display: none; }
.device-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
  min-width: 144px;
  max-width: 184px;
  height: 48px;
  padding: 0 8px 0 12px;
  border: 1px solid var(--divider);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--text-strong);
  scroll-snap-align: start;
  cursor: pointer;
  transition: background .16s, border-color .16s;
  box-sizing: border-box;
}
.device-tab:hover { background: var(--neutral-100); }
.device-tab:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.device-tab[data-status="connected"] { border-color: var(--ok-border); }
.device-tab.is-selected { background: var(--primary-tint); border-color: var(--primary); }
.device-tab-copy { display: grid; gap: 1px; min-width: 0; flex: 1; text-align: left; }
.device-tab-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-strong);
  font-size: 13px;
  line-height: 18px;
  font-weight: 600;
}
.device-tab-status { color: var(--text-tertiary); font-size: 11px; line-height: 15px; white-space: nowrap; }
.device-tab[data-status="connected"] .device-tab-status { color: var(--ok); }
.device-tab.is-selected .device-tab-status { color: var(--muted); }
.device-tab.is-selected[data-status="connected"] .device-tab-status { color: var(--ok); }
.device-status-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-tertiary);
  box-shadow: 0 0 0 3px var(--neutral-100);
}
.device-tab[data-status="connected"] .device-status-dot { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-tint); }
.device-tab[data-status="connecting"] .device-status-dot {
  background: var(--warn);
  box-shadow: 0 0 0 3px var(--warn-tint);
  animation: devicePulse 1.4s ease-in-out infinite;
}
.device-tab-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
}
.device-tab-close:hover,
.device-tab-close:focus-visible { background: var(--danger-tint); color: var(--danger); }
.device-tab-close img { width: 14px; height: 14px; }
.device-overflow-btn {
  display: none;           /* 手机：横向滚动，不出「更多」按钮 */
  align-items: center;
  justify-content: center;
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  border: 1px solid var(--divider);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--muted);
  cursor: pointer;
}
.device-overflow-btn img { width: 18px; height: 18px; }
.device-overflow-btn:hover { color: var(--text-strong); background: var(--neutral-100); }
.device-overflow-menu {
  position: absolute;
  z-index: 20;
  top: 96px;
  right: var(--sp-3);
  width: min(240px, calc(100% - 24px));
  padding: 6px;
  border: 1px solid var(--divider);
  border-radius: var(--r-md);
  background: var(--card);
  box-shadow: var(--sh-2);
}
.device-overflow-menu button {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.device-overflow-menu button:hover { background: var(--neutral-100); }
.device-overflow-menu .device-status-dot { margin-left: auto; }
/* 有设备态的常驻隐私微文案（空态改由提示行尾的盾牌承担） */
.device-privacy-note {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 24px;
  margin-top: var(--sp-2);          /* 契约 8 */
  color: var(--muted);
  font-size: 11px;
  line-height: 16px;
}
.device-privacy-note img { width: 16px; height: 16px; }

/* 桌面提示行：隐私说明直接摊开、不必点盾牌。
   **必须写在上面这些手机规则之后** —— 放进前面的 @media 块里会被后面的同权重手机规则压掉
   （本项目已在这个顺序坑上摔过四次：桌面导航、聊天首页双栏、06 合并区、这里）。 */
@media (min-width: 1024px) {
  .devices-empty-nudge { width: auto; max-width: 760px; }
  .devices-empty-nudge .privacy-trigger { display: none; }
  .devices-empty-nudge .privacy-tip {
    position: static; display: inline; width: auto; padding: 0; margin-left: 6px;
    background: none; color: var(--muted); box-shadow: none; font-size: 12px; line-height: 18px;
  }
  .devices-empty-nudge .privacy-tip[hidden] { display: inline !important; }
}

/* 收藏设备连接态：明确不含房间码与二维码。 */
.my-device-state {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: center;
  width: 100%;
  padding: var(--sp-6);
  border: 1px solid var(--primary-soft-border);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--sh-2);
}
.my-device-state[hidden] { display: none; }
.device-state-visual {
  position: relative;
  display: grid;
  place-items: center;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: var(--primary-tint);
  color: var(--primary);
}
.device-state-visual img { position: relative; z-index: 1; width: 34px; height: 34px; }
.device-orbit {
  position: absolute;
  inset: 8px;
  border: 2px solid var(--primary-soft-border);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: deviceOrbit 1.8s linear infinite;
}
.my-device-state[data-state="failed"] { border-color: var(--danger); }
.my-device-state[data-state="failed"] .device-state-visual { background: var(--danger-tint); color: var(--danger); }
.my-device-state[data-state="failed"] .device-orbit { animation: none; border-color: var(--danger); }
.my-device-state[data-state="connected"] { border-color: var(--ok); }
.my-device-state[data-state="connected"] .device-state-visual { background: var(--ok-tint); color: var(--ok); }
.my-device-state[data-state="connected"] .device-orbit { animation: none; border-color: var(--ok); }
.device-state-copy { min-width: 0; }
.device-state-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 24px;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: var(--warn-tint);
  color: var(--warn);
  font-size: 11px;
  line-height: 16px;
}
.device-state-badge span { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.my-device-state[data-state="failed"] .device-state-badge { background: var(--danger-tint); color: var(--danger); }
.my-device-state[data-state="connected"] .device-state-badge { background: var(--ok-tint); color: var(--ok); }
.device-state-copy h2 { margin: 10px 0 4px; color: var(--text-strong); font-size: 22px; line-height: 30px; }
.device-state-copy p { margin: 0; color: var(--muted); font-size: 13px; line-height: 20px; }
.device-state-progress {
  height: 4px;
  margin-top: var(--sp-4);
  border-radius: var(--r-pill);
  background: var(--neutral-100);
  overflow: hidden;
}
.device-state-progress span {
  display: block;
  width: 42%;
  height: 100%;
  border-radius: inherit;
  background: var(--primary);
  animation: deviceProgress 1.8s ease-in-out infinite;
}
.my-device-state[data-state="failed"] .device-state-progress,
.my-device-state[data-state="connected"] .device-state-progress { display: none; }
.device-state-actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-4); }
.device-state-actions button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 40px;
  padding: 0 16px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 650;
  cursor: pointer;
}
.device-primary-action { border: 0; background: var(--primary); color: #fff; }
.device-secondary-action { border: 1px solid var(--divider); background: var(--card); color: var(--muted); }
.device-state-actions img { width: 17px; height: 17px; }
.device-manage-card {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--divider);
}
.device-manage-card > span { display: grid; gap: 2px; min-width: 0; }
.device-manage-card strong { color: var(--text-strong); font-size: 13px; line-height: 19px; }
.device-manage-card small { color: var(--muted); font-size: 11px; line-height: 16px; }
.device-manage-card > div { display: flex; gap: 6px; }
.device-manage-card button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 10px;
  border: 1px solid var(--divider);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.device-manage-card button:hover { background: var(--neutral-100); color: var(--text-strong); }
.device-manage-card button.danger { color: var(--danger); }
.device-manage-card button.danger:hover { background: var(--danger-tint); border-color: var(--danger); }
.device-manage-card button img { width: 16px; height: 16px; }
.device-zero-knowledge {
  grid-column: 1 / -1;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: var(--primary-tint);
  color: var(--muted);
  font-size: 11px;
  line-height: 17px;
}
.device-zero-knowledge img { flex: 0 0 auto; width: 16px; height: 16px; color: var(--primary); }

/* 连接成功后的收藏入口：空心/实心星两态。 */
.favorite-device-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 54px;
  margin-top: var(--sp-3);
  padding: 9px 12px;
  border: 1px solid var(--primary-soft-border);
  border-radius: var(--r-md);
  background: var(--primary-tint);
  color: var(--primary);
  text-align: left;
  cursor: pointer;
}
.favorite-device-btn:hover { border-color: var(--primary); }
.favorite-device-btn > img { flex: 0 0 auto; width: 22px; height: 22px; }
.favorite-device-btn .favorite-filled { display: none; }
.favorite-device-btn > span { display: grid; gap: 1px; }
.favorite-device-btn strong { color: var(--text-strong); font-size: 13px; line-height: 18px; }
.favorite-device-btn small { color: var(--muted); font-size: 11px; line-height: 16px; }
.favorite-device-btn[aria-pressed="true"] { background: var(--ok-tint); border-color: var(--ok); color: var(--ok); }
.favorite-device-btn[aria-pressed="true"] .favorite-empty { display: none; }
.favorite-device-btn[aria-pressed="true"] .favorite-filled { display: block; }
.device-rename-modal { gap: var(--sp-3); }
.device-rename-input {
  width: 100%;
  min-height: 46px;
  padding: 0 12px;
  border: 1px solid var(--divider);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--text-strong);
  font: inherit;
  outline: 0;
}
.device-rename-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-tint); }

@keyframes devicePulse { 50% { opacity: .42; transform: scale(.82); } }
@keyframes deviceOrbit { to { transform: rotate(360deg); } }
@keyframes deviceProgress { 0% { transform: translateX(-110%); } 55%,100% { transform: translateX(250%); } }

@media (max-width: 869px) {
  .my-devices-shell { padding: var(--sp-3); border-radius: var(--r-md); }
  .my-devices-header { align-items: center; }
  .device-new-action { height: 36px; }
  .device-overflow-btn { display: none !important; }   /* 手机只横向滚动 */
  .device-overflow-menu { display: none !important; }
  .my-device-state { grid-template-columns: 64px minmax(0, 1fr); padding: var(--sp-4); }
  .device-state-visual { width: 60px; height: 60px; }
  .device-state-visual img { width: 28px; height: 28px; }
  .device-state-copy h2 { font-size: 18px; line-height: 26px; }
  .device-manage-card { align-items: flex-start; }
  .device-manage-card > div { flex-direction: column; }
  .device-manage-card button { min-width: 96px; justify-content: flex-start; }
}

@media (min-width: 1024px) {
  .my-devices-shell,
  .my-device-state { width: 100%; }
  .my-devices-shell { padding: var(--sp-4); }
  .device-new-action { width: 144px; height: 40px; }
  .device-tab { min-width: 160px; max-width: 200px; }
  /* 桌面：关闭按钮只在选中 / hover / 内部聚焦时露出，平时不噪 */
  .device-tab .device-tab-close { opacity: 0; }
  .device-tab.is-selected .device-tab-close,
  .device-tab:hover .device-tab-close,
  .device-tab:focus-within .device-tab-close { opacity: 1; }
  .device-overflow-btn:not([hidden]) { display: inline-flex; }
  .my-device-state {
    grid-template-columns: 112px minmax(0, 1fr) 320px;
    padding: var(--sp-6);
  }
  .device-state-visual { width: 96px; height: 96px; }
  .device-manage-card {
    grid-column: 3;
    grid-row: 1;
    align-self: stretch;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    padding: var(--sp-4);
    border: 1px solid var(--divider);
    border-radius: var(--r-md);
    background: var(--surface-2);
  }
  .device-manage-card > div { margin-top: var(--sp-3); }
  .device-manage-card button { flex: 1; justify-content: center; }
  .device-zero-knowledge { grid-column: 1 / -1; }
  .favorite-device-btn { max-width: 420px; margin-left: auto; }
}
