/* =============================================================
   五岔 · 云匣子 · 布局层（v4 石墨极简）
   -------------------------------------------------------------
   · 纯白应用框：侧边栏 / 顶栏 / 内容 / 右栏全部白底，
     分区只靠**加强的发丝描边**（#d8dbe2），轮廓清晰；
   · 三栏包裹式排版：左导航 292 ｜ 中列表（≤780）｜ 右栏 320；
   · 右栏 = 目录树 + 分享速查 + 回收站速查，可动态展开/收缩；
   · 折叠态与右栏开合都是短促精准的宽度动画。
   ============================================================= */

#app {
  position: relative;
  z-index: var(--z-app);
  height: 100%;
}

.shell {
  display: flex;
  height: 100vh;
  height: 100dvh;
  background: transparent;
  /* 浮动卡片式排布：侧边栏 / 主面板都是圆角悬浮纸片，之间留缝 */
  padding: 16px;
  gap: 14px;
  max-width: 2560px;
  margin: 0 auto;
}

/* =============================================================
   左侧导航（白底 + 右侧发丝线）
   ============================================================= */
.sidebar {
  position: relative;
  z-index: var(--z-sticky);
  flex: 0 0 auto;
  width: var(--sidebar-w);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid transparent;
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-s);
  transition: width var(--dur-4) var(--ease-io), transform var(--dur-4) var(--ease);
  overflow: hidden;
}

/* ---------- 品牌区 ---------- */
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  /* 品牌区整体下移，别贴着顶 */
  height: calc(var(--topbar-h) + 34px);
  padding: 20px 18px 0;
  flex: 0 0 auto;
  border-bottom: 1px solid var(--line-soft);
  transition: padding var(--dur-3) var(--ease), gap var(--dur-3) var(--ease);
}

.brand-mark {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: transparent;
  box-shadow: 0 4px 14px rgba(12, 14, 20, 0.22);
  display: grid;
  place-items: center;
  overflow: hidden;
  transition: transform var(--dur-2) var(--ease-back), box-shadow var(--dur-3) var(--ease);
}

.brand:hover .brand-mark {
  transform: rotate(-6deg) scale(1.08);
  box-shadow: 0 8px 24px rgba(12, 14, 20, 0.32);
}

.brand-mark .brand-img {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: inherit;
}

/* 命令行（黑底终端）标题栏的品牌标：用【白底黑字】版本 */
.cli-mark {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  display: block;
  flex: 0 0 auto;
}

.brand-text {
  min-width: 0;
  white-space: nowrap;
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-3) var(--ease);
}

.brand-name {
  font-size: 15.5px;
  font-weight: 800;
  letter-spacing: 0.2px;
  line-height: 1.15;
  background: var(--grad-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.brand-sub {
  margin-top: 1px;
  font-size: 11px;
  font-weight: 550;
  color: var(--text-4);
  letter-spacing: 0.5px;
}

/* ---------- 导航 ---------- */
.nav {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  padding: 10px 12px;
}

.nav-group-title {
  position: relative;
  height: 28px;
  padding: 0 10px;
  display: flex;
  align-items: center;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.5px;
  color: var(--text-4);
  white-space: nowrap;
  overflow: hidden;
  transition: opacity var(--dur-2) var(--ease), height var(--dur-3) var(--ease);
}

.nav-group-title::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  margin-left: 10px;
  background: var(--line-soft);
}

/* 滑动高亮：渐变胶囊 + 光晕 */
.nav-pill {
  position: absolute;
  top: 0;
  left: 12px;
  right: 12px;
  height: var(--nav-item-h);
  border-radius: 13px;
  background: var(--grad-pill);
  box-shadow: var(--shadow-xs);
  transform: translateY(0);
  will-change: transform;
  transition: transform var(--dur-3) var(--ease-spring), height var(--dur-3) var(--ease),
    opacity var(--dur-2) linear;
  pointer-events: none;
}

.nav.no-anim .nav-pill {
  transition: opacity var(--dur-2) linear;
}

.nav-pill::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 50%;
  width: 3px;
  height: 20px;
  margin-top: -10px;
  border-radius: 0 4px 4px 0;
  background: var(--grad-brand);
  box-shadow: 0 0 10px rgba(91, 108, 255, 0.55);
}

.nav-item {
  position: relative;
  z-index: 1;
  width: 100%;
  height: var(--nav-item-h);
  padding: 0 10px;
  display: flex;
  align-items: center;
  gap: 11px;
  border-radius: 13px;
  color: var(--text-2);
  font-size: 13.5px;
  font-weight: 550;
  white-space: nowrap;
  overflow: hidden;
  transition: color var(--dur-2) var(--ease), font-size var(--dur-2) var(--ease);
}

/* 悬停效果：不做灰底 —— 字体微微放大 + 变蓝（当前分类悬停无此效果） */
.nav-item:hover {
  color: var(--brand-1);
  background: transparent;
  transform: none;
  font-size: 14.3px;
}

.nav-item.is-active:hover {
  color: var(--text-1);
  background: transparent;
  font-size: 13.5px;
}

.nav-item:active {
  transform: scale(0.98);
  transition-duration: var(--dur-instant);
}

.nav-item.is-active {
  color: var(--text-1);
  font-weight: 700;
}

.nav-item .ico {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  color: var(--text-4);
  transition: color var(--dur-2) var(--ease);
}

.nav-item:hover .ico {
  color: var(--brand-1);
}

.nav-item.is-active .ico,
.nav-item.is-active:hover .ico {
  color: var(--brand-1);
}

.nav-item.is-active:hover {
  color: var(--text-1);
}

.nav-item .ico svg {
  width: 17px;
  height: 17px;
}

.nav-label {
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  /* max-width 参与过渡：它是可动画的，能从 100% 平滑收到 0 */
  max-width: 100%;
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-3) var(--ease),
    max-width var(--dur-3) var(--ease);
}

/* ★ 左侧导航**常显**：「收起侧边栏」功能已按用户要求删除，
   原先这里那一整套 .shell.is-fold 收起态样式（label/badge/item/宽度）
   已随之清理，不再需要"文字真正从布局里收掉"那套处理。 */

.nav-badge {
  flex: 0 0 auto;
  min-width: 19px;
  height: 18px;
  padding: 0 6px;
  border-radius: var(--r-full);
  background: var(--surface-3);
  border: 1px solid var(--line-soft);
  color: var(--text-3);
  font-size: 10.5px;
  font-weight: 700;
  display: grid;
  place-items: center;
  transition: opacity var(--dur-2) var(--ease);
}

/* ---------- 分割线（柔和渐变，不是硬线） + 命令行入口 ---------- */
.nav-div {
  height: 1px;
  margin: 8px 16px;
  background: linear-gradient(90deg, transparent, rgba(91, 108, 255, 0.3), rgba(236, 72, 153, 0.2), transparent);
}

.nav-cli-wrap {
  flex: 0 0 auto;
  padding: 0 12px 8px;
}

.ico-cli {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -1px;
}

/* ---------- 存储用量（侧边栏底部，描边卡片） ---------- */
.storage-card {
  flex: 0 0 auto;
  margin: 0 12px 12px;
  padding: 14px 16px;
  border-radius: var(--r-l);
  background: var(--surface);
  border: 1px solid transparent;
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--dur-2) var(--ease), transform var(--dur-2) var(--ease),
    margin var(--dur-4) var(--ease), padding var(--dur-4) var(--ease);
}

.storage-card:hover {
  box-shadow: var(--shadow-s);
  transform: translateY(-1px);
}

.storage-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 9px;
  white-space: nowrap;
}

.storage-title {
  font-size: 11.5px;
  font-weight: 650;
  color: var(--text-3);
  transition: opacity var(--dur-2) var(--ease);
}

.storage-pct {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-1);
}

.storage-bar {
  position: relative;
  height: 5px;
  border-radius: var(--r-full);
  background: var(--surface-3);
  border: 1px solid var(--line-soft);
  overflow: hidden;
  /* ⚠ 这里**不要**做 hover 变化（既不要改 height，也不要加 filter/opacity）：
     ① 改 height 会真的改变布局 → 把上面的按钮顶上去（用户报过）；
     ② 加 filter 会连带影响子元素渲染，而 .sheen 是子元素 ——
        两者叠加会让灰色轨道在 hover 时"消失"（用户报过）。
     卡片的 hover 反馈（阴影 + 上浮 1px）已经足够，进度条保持静止。 */
}

.storage-bar > i {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: var(--r-full);
  background: var(--grad-brand);
  background-size: 200% 100%;
  transition: width var(--dur-5) var(--ease);
}

.storage-bar > i > .sheen {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 46px;
  border-radius: inherit;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0));
  animation: bar-sheen 5.5s var(--ease-soft) infinite;
}

@keyframes bar-sheen {
  0% { transform: translateX(-52px) }
  55%, 100% { transform: translateX(220px) }
}

.storage-foot {
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 11px;
  color: var(--text-4);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: opacity var(--dur-2) var(--ease);
}

/* =============================================================
   主区域
   ============================================================= */
.main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 0;
}

/* ---------- 顶栏 ---------- */
.topbar {
  flex: 0 0 auto;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 6px;
  background: transparent;
}

.icon-btn {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: var(--r-s);
  border: 1px solid transparent;
  color: var(--text-3);
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease), transform var(--dur-2) var(--ease);
}

.icon-btn:hover {
  background: var(--brand-soft);
  border-color: transparent;
  color: var(--brand-ink);
  transform: translateY(-1px);
}

.icon-btn:active {
  transform: scale(0.94);
  transition-duration: var(--dur-instant);
}

.icon-btn.is-on {
  background: var(--brand-soft);
  border-color: var(--line);
  color: var(--text-1);
}

.icon-btn svg {
  width: 16px;
  height: 16px;
}

/* 面包屑：纯文本 + 箭头 */
.crumb-line {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  overflow: hidden;
}

.crumb-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  max-width: 240px;
  padding: 0 8px;
  border-radius: var(--r-s);
  font-size: 13px;
  font-weight: 550;
  color: var(--text-3);
  background: transparent;
  border: 1px solid transparent;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease), transform var(--dur-2) var(--ease);
}

.crumb-chip:hover {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--text-1);
  transform: translateY(-1px);
}

.crumb-chip:active {
  transform: translateY(0) scale(0.98);
  transition-duration: var(--dur-instant);
}

.crumb-chip.is-current {
  background: transparent;
  color: var(--text-1);
  font-weight: 700;
}

.crumb-sep {
  flex: 0 0 auto;
  color: var(--text-4);
  display: grid;
  place-items: center;
  transition: color var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}

.crumb-line:hover .crumb-sep {
  color: var(--text-3);
  transform: translateX(2px);
}

.crumb-sep svg {
  width: 12px;
  height: 12px;
}

.crumb-ellipsis {
  flex: 0 0 auto;
  color: var(--text-4);
  letter-spacing: 1px;
  padding: 0 2px;
  cursor: default;
  transition: color var(--dur-2) var(--ease);
}

.crumb-ellipsis:hover {
  color: var(--text-1);
}

/* ---------- 搜索（描边输入框，聚焦微扩） ---------- */
.search {
  position: relative;
  flex: 0 1 340px;
  min-width: 180px;
  transition: flex-basis var(--dur-3) var(--ease);
}

.search:focus-within {
  flex-basis: 430px;
}

.search input {
  width: 100%;
  height: 34px;
  padding: 0 32px;
  border-radius: var(--r-full);
  background: var(--surface);
  border: 1px solid transparent;
  box-shadow: var(--shadow-xs);
  font-size: 12.8px;
  transition: background var(--dur-1) var(--ease), box-shadow var(--dur-2) var(--ease),
    border-color var(--dur-1) var(--ease);
}

.search input::placeholder {
  color: var(--text-4);
}

.search input:hover {
  box-shadow: var(--shadow-s);
}

.search input:focus {
  outline: none;
  background: var(--surface);
  border-color: transparent;
  box-shadow: var(--shadow-accent);
}

.search .s-ico {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-4);
  pointer-events: none;
  transition: color var(--dur-2) var(--ease);
}

.search:focus-within .s-ico {
  color: var(--text-1);
}

.search .s-ico svg {
  width: 15px;
  height: 15px;
}

.search .s-kbd {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  height: 18px;
  padding: 0 5px;
  border-radius: 5px;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--text-4);
  font-size: 10px;
  font-weight: 600;
  display: grid;
  place-items: center;
  pointer-events: none;
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}

.search:focus-within .s-kbd {
  opacity: 0;
  transform: translateY(-50%) scale(0.8);
}

/* ---------- 用户区 ----------
   ★ 2026-10-16（用户要求）：原来背景透明、只有一行字"显得难受"，而且悬停时
     白色底正好卡着文字边缘。改成：**常驻一个描边小胶囊把内容框住**，
     悬停/焦点/展开时换"品牌光晕"效果（浅品牌底 + 品牌描边 + 柔阴影），
     整体高度 34→42px，上下留出呼吸感。 */
.user-chip {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 42px;
  padding: 0 14px;
  min-width: 0;
  border-radius: var(--r-m);
  background: var(--surface-2);
  border: 1px solid var(--line);
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}

.user-chip:hover {
  background: var(--brand-soft);
  border-color: rgba(91, 108, 255, 0.35);
  box-shadow: 0 6px 18px rgba(91, 108, 255, 0.16);
  transform: translateY(-1px);
}

/* 键盘焦点与鼠标悬停同款"另一种效果"，再加一圈柔和焦点环 */
.user-chip:focus-visible {
  outline: none;
  background: var(--brand-soft);
  border-color: rgba(91, 108, 255, 0.45);
  box-shadow: 0 0 0 4px rgba(91, 108, 255, 0.14);
}

.user-chip:active {
  transform: translateY(0) scale(0.98);
  transition-duration: var(--dur-instant);
}

.user-name {
  font-size: 12.8px;
  font-weight: 600;
  color: var(--text-2);
  white-space: nowrap;
}

/* =============================================================
   内容区：workarea = 中列表 + 右栏（两侧包裹列表）
   ============================================================= */
.workarea {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: stretch;
  gap: 14px;
  /* 内容整体只往下压一点点 */
  margin-top: 6px;
}

/* ---------- 中：文件列表纸（悬浮白卡，吃满左右之间的空间） ---------- */
.panel {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--surface);
  border: 1px solid transparent;
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-s);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

.panel-view {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.view-enter {
  animation: rise-in var(--dur-3) var(--ease) backwards;
}

/* =============================================================
   右栏：目录树 + 分享/回收站速查（可动态展开/收缩）
   ============================================================= */
.rail {
  flex: 0 0 auto;
  width: var(--rail-w);
  min-width: 0;
  overflow: hidden;
  opacity: 1;
  transition: width var(--dur-4) var(--ease-io), opacity var(--dur-3) var(--ease);
}

.rail-inner {
  width: var(--rail-w);
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.rail-card {
  display: flex;
  flex-direction: column;
  /* 三个面板固定等高分满右栏，内部各自滚动 */
  flex: 1 1 0;
  min-height: 0;
  background: var(--surface);
  border: 1px solid transparent;
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-s);
  animation: fade-rise-in var(--dur-3) var(--ease) backwards;
  transition: box-shadow var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}

.rail-card:hover {
  box-shadow: var(--shadow-m);
  transform: translateY(-2px);
}


.rail-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 42px;
  padding: 0 8px 0 14px;
  border-bottom: 1px solid var(--line-soft);
}

.rail-title {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-1);
}

.rail-title svg {
  width: 14px;
  height: 14px;
  color: var(--text-3);
}

.rail-sub {
  font-size: 11px;
  color: var(--text-4);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.rail-more {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  height: 26px;
  padding: 0 8px;
  border-radius: var(--r-xs);
  font-size: 11.5px;
  font-weight: 650;
  color: var(--text-3);
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease),
    transform var(--dur-2) var(--ease);
}

.rail-more:hover {
  background: var(--surface-3);
  color: var(--text-1);
  transform: translateY(-1px);
}

.rail-more:active {
  transform: translateY(0) scale(0.94);
  transition-duration: var(--dur-instant);
}

.rail-more svg {
  transition: transform var(--dur-2) var(--ease);
}

.rail-more:hover svg {
  transform: translateX(2px);
}

/* ---------- 速查列表 ---------- */
.rail-list {
  flex: 1 1 auto;
  min-height: 0;
  padding: 6px;
}

.rail-foot {
  flex: 0 0 auto;
  padding: 8px;
  border-top: 1px solid var(--line-soft);
}

.qrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  border-radius: var(--r-s);
  transition: background var(--dur-1) var(--ease), transform var(--dur-2) var(--ease);
}

.qrow:hover {
  background: var(--surface-2);
  transform: translateX(2px);
}

.q-ico {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: var(--r-s);
  border: 1px solid var(--line);
  background: var(--surface-2);
  display: grid;
  place-items: center;
  color: var(--text-3);
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}

.qrow:hover .q-ico {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

.q-ico.is-warn {
  color: var(--warn);
  border-color: rgba(183, 121, 31, 0.4);
  background: var(--warn-soft);
}

.q-ico svg {
  width: 13px;
  height: 13px;
}

.q-main {
  flex: 1 1 auto;
  min-width: 0;
}

.q-name {
  font-size: 12.2px;
  font-weight: 600;
  color: var(--text-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.q-sub {
  margin-top: 1px;
  font-size: 10.8px;
  color: var(--text-4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}

.q-sub.is-urgent {
  color: var(--danger);
  font-weight: 650;
}

.q-act {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: var(--r-xs);
  border: 1px solid transparent;
  color: var(--text-4);
  opacity: 0;
  transition: all var(--dur-1) var(--ease);
}

.qrow:hover .q-act {
  opacity: 1;
}

.q-act:hover {
  background: var(--surface);
  border-color: var(--line);
  color: var(--text-1);
  transform: translateY(-1px);
}

.q-act:active {
  transform: scale(0.92);
  transition-duration: var(--dur-instant);
}

.rail-empty {
  padding: 16px 10px;
  text-align: center;
  font-size: 11.5px;
  color: var(--text-4);
}

/* ---------- 命令行面板（黑色终端 · 全中文 · 铺满主面板） ---------- */
.cli {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  background: var(--ink);
  border: 0;
  border-radius: 0;
  overflow: hidden;
  animation: fade-rise-in var(--dur-3) var(--ease) backwards;
}

.cli-head {
  border-bottom: 1px solid var(--ink-line);
}

.cli .rail-title {
  color: var(--ink-text);
}

.cli .rail-title svg,
.cli .rail-sub {
  color: var(--ink-text-2);
}

.cli .rail-more {
  color: var(--ink-text-2);
}

.cli .rail-more:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  transform: none;
}

.cli-screen {
  flex: 1 1 auto;
  min-height: 0;
  padding: 18px 22px;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.8;
}

.cli-line {
  white-space: pre-wrap;
  word-break: break-all;
  color: var(--ink-text-2);
  animation: fade-rise-in var(--dur-2) var(--ease) backwards;
}

.cli-line.is-cmd { color: #ffffff; font-weight: 700; }
.cli-line.is-sys { color: var(--ink-text-2); }
.cli-line.is-out { color: var(--ink-text); }
.cli-line.is-ok  { color: #7edaa0; }
.cli-line.is-err { color: #eda3a0; }

.cli-input {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border-top: 1px solid var(--ink-line);
}

.cli-prompt {
  color: #7edaa0;
  font-family: var(--font-mono);
  font-weight: 700;
}

.cli-input input {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: 0;
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12.5px;
}

.cli-input input::placeholder {
  color: rgba(255, 255, 255, 0.32);
}

.cli-input input:focus {
  outline: none;
}

.cli-busy {
  font-size: 11px;
  color: var(--ink-text-2);
  font-family: var(--font-mono);
}

/* ---------- 视图切换过渡 ---------- */
.viewswap-enter-active {
  transition: opacity var(--dur-3) var(--ease), transform var(--dur-3) var(--ease);
}

.viewswap-leave-active {
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
  position: absolute;
  inset: 0;
}

.viewswap-enter-from {
  opacity: 0;
  transform: translate3d(0, 10px, 0) scale(0.995);
}

.viewswap-leave-to {
  opacity: 0;
  transform: translate3d(0, -5px, 0) scale(0.995);
}

/* ---------- 响应式 ---------- */
/* =============================================================
   ★ 移动端底部导航
   ---------------------------------------------------------------
   默认 display:none —— 桌面端完全不受影响，只有窄屏（见文件末尾的
   @media max-width:860px）才出现。
   为什么是底部导航而不是"汉堡抽屉"：用户要求"移动端靠响应式、
   不要手动开关"。底部导航常显、所有目的地一眼可见、拇指够得着；
   汉堡抽屉必须先点一下才能看到导航。
   ============================================================= */
.tabbar {
  display: none;
}

.tabbtn {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  /* 触摸目标不小于 44px（可点击区域整列都是，比图标大得多） */
  min-height: 52px;
  padding: 6px 2px 4px;
  border-radius: 12px;
  color: var(--text-3);
  font-size: 10.5px;
  font-weight: 600;
  transition: color var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}

.tabbtn .tb-ico {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  transition: transform var(--dur-2) var(--ease);
}

.tabbtn .tb-ico svg {
  width: 20px;
  height: 20px;
}

.tabbtn .tb-label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tabbtn.is-active {
  color: var(--brand-1);
  font-weight: 750;
}

.tabbtn.is-active .tb-ico {
  transform: translateY(-1px) scale(1.06);
}

.tabbtn:active {
  background: var(--surface-3);
}

.tabbtn .tb-badge {
  position: absolute;
  top: 3px;
  left: 50%;
  margin-left: 4px;
  min-width: 16px;
  height: 15px;
  padding: 0 4px;
  border-radius: var(--r-full);
  background: var(--danger, #e5484d);
  color: #fff;
  font-size: 9.5px;
  font-weight: 800;
  line-height: 15px;
  text-align: center;
}

@media (max-width: 1280px) {
  .rail {
    position: fixed;
    right: 18px;
    top: calc(var(--topbar-h) + 12px);
    bottom: 18px;
    z-index: var(--z-sticky);
  }
}

@media (max-width: 1080px) {
  .search {
    flex-basis: 170px;
  }
  .search:focus-within {
    flex-basis: 210px;
  }
  .user-name {
    display: none;
  }
  .user-chip {
    padding: 0 6px;
  }
}

@media (max-width: 860px) {
  .main {
    padding: 0 10px 10px;
    /* 给底部导航让出空间（含 iPhone 安全区），否则最后一行会被挡住 */
    padding-bottom: calc(78px + env(safe-area-inset-bottom, 0px));
  }
  /* ★ 窄屏不再用侧边栏：导航整体交给底部 tabbar。
     （CSS 里原来那套"抽屉 + is-mobile-open"从未被 JS 打开过 ——
      抽屉永远关着、又没有开关，等于手机上完全没有导航。已改成常显的底部导航。） */
  .sidebar {
    display: none;
  }
  /* 右栏是固定定位的浮层，窄屏会盖住大半屏幕 → 收起。
     上传任务的进度在手机上暂不显示（已知限制，见对接文档）。 */
  .rail {
    display: none;
  }
  .shell {
    max-width: none;
  }
  .search {
    display: none;
  }
  /* 底部导航常显 */
  .tabbar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-sticky);
    gap: 2px;
    padding: 4px 6px calc(4px + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
    border-top: 1px solid var(--line);
    box-shadow: 0 -2px 12px rgba(30, 40, 80, 0.06);
  }
}

/* =============================================================
   ★ 窄屏上传进度浮标（2026-10-07）
   ---------------------------------------------------------------
   桌面端右栏（.rail）已有完整任务列表 → 这里默认隐藏，不打扰。
   窄屏右栏被隐藏 → 在底部导航上方浮一个小条，显示"数量 + 百分比 + 速度"，
   否则手机上点完上传**完全看不到进度**（不知道在传、还是卡住了）。
   ============================================================= */
.up-fab {
  display: none;
}

@media (max-width: 860px) {
  .up-fab {
    display: flex;
    align-items: center;
    gap: 8px;
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    /* 底部导航高约 62px；再让出 iPhone 安全区，否则会压在导航上 */
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    z-index: 60;
    max-width: calc(100vw - 24px);
    padding: 8px 14px;
    border-radius: var(--r-full);
    background: var(--ink);
    color: var(--ink-text);
    font-size: 12px;
    font-weight: 650;
    box-shadow: var(--shadow-l);
    animation: rise-in var(--dur-3) var(--ease) backwards;
  }

  .up-fab-ring {
    flex: 0 0 auto;
    width: 34px;
    height: 4px;
    border-radius: var(--r-full);
    background: rgba(127, 127, 127, 0.4);
    overflow: hidden;
  }

  .up-fab-ring i {
    display: block;
    height: 100%;
    background: var(--brand, #2f6df6);
    transition: width var(--dur-2) linear;
  }

  .up-fab-txt {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ★★ 上传列表弹层（2026-10-07 用户要求）
   原来「任务列表」是右栏一个卡片，用户要求：搬到顶栏搜索框右边，用图标点开一个小框；
   打开时**除按钮与弹层本身外全部压暗**，点暗处即关。 */
.up-menu-slot {
  display: flex;
  align-items: center;
  margin-left: 8px;
}

.up-menu-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
    background var(--dur-1) var(--ease);
}

.up-menu-btn:hover {
  color: var(--brand-1);
  border-color: var(--brand-1);
  background: var(--brand-soft);
}

/* ★★ 2026-10-16（用户实测反馈：弹层亮、按钮却被压暗）
   根因：打开时按钮底色是 **半透明** 的 brand-soft（10% 透明度），
   而按钮浮在压暗层**上面** —— 暗底从这 90% 的透明度里透过来，
   按钮区域看起来就被压暗了（面板是不透明的白底，所以面板是亮的）。
   修法：打开态改成**不透明**的表面底 + 品牌描边/字色 —— 与面板同亮度。 */
.up-menu-btn.is-open {
  color: var(--brand-1);
  border-color: var(--brand-1);
  background: var(--surface);
  box-shadow: 0 6px 18px rgba(91, 108, 255, 0.16);
}

/* 有正在上传的任务时右上角一个小数字 */
.up-menu-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--brand-1);
  color: #fff;
  font-size: 10.5px;
  line-height: 17px;
  text-align: center;
}

/* 压暗层：盖住整屏，但**弹层自己**在它上面（z-index 更高），按钮在顶栏也抬起来 */
.up-menu-dim {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(16, 18, 30, 0.42);
  animation: fade-in var(--dur-2) var(--ease);
}

/* 弹层：贴在图标的左下方展开（top/left 由 JS 按按钮位置 + 视口宽度算，见 rail.js 的 popStyle）
   ★★ 宽度写成 min(340px, 100vw - 24px)：
      固定 340px 在比它更窄的屏幕上（极窄的手机 / 分屏）一定溢出，
      这里让它在窄屏自动收窄，左右各留 12px 边距。
      ⚠ 这个算式必须与 rail.js 里 popStyle() 的 POP_W / POP_MARGIN 保持一致。 */
.up-menu-pop {
  position: fixed;
  z-index: 301;
  left: var(--up-menu-left, 240px);
  width: min(340px, calc(100vw - 24px));
  max-height: min(60vh, 460px);
  flex: 0 0 auto;
  overflow: hidden;
}

/* ★★ 2026-10-08（用户实测反馈：点开图标后"连图标自己也被压暗了"）
   ---------------------------------------------------------------
   根因：#app 上有 `position: relative; z-index: var(--z-app)`（见本文件顶部），
         它**自己就创建了一个层叠上下文** —— 于是里面的 .up-menu-slot 无论
         z-index 提到多高，都只能在 #app 内部比大小，永远盖不过 Teleport 到
         body 的压暗层（z-index 300）。下面那条 `:has()` 规则因此一直是**空转**的：
         实测（无头浏览器 elementFromPoint(图标中心)）改前返回 `div.up-menu-dim`。
   修法：**只在弹层打开期间**让 #app 不再是层叠上下文（z-index: auto），
         槽位的 301 就真正参与根上下文的排序 —— 图标亮、面板亮、其余照旧被压暗。
   ⚠ 只在 `.up-menu-btn.is-open` 期间生效：弹层一关，#app 立刻恢复原来的
     `z-index: var(--z-app)`，其它任何层级关系都不受影响。 */
body:has(.up-menu-btn.is-open) #app {
  z-index: auto;
}

/* 弹层打开时，图标按钮要浮在压暗层之上，否则会被盖住。
   ⚠ 这条要靠上面那条 `body:has(...) #app { z-index: auto }` 才真正生效 ——
     #app 若仍是层叠上下文，这里的 301 再高也出不了 #app 的层叠上下文。 */
.up-menu-slot:has(.up-menu-btn.is-open) {
  position: relative;
  z-index: 301;
}
/* ★ 小铃铛红点：只要还有任意一条未读就显示；全部已读由 v-if 摘掉 */
.up-menu-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--danger);
  box-shadow: 0 0 0 2px var(--surface);
}

/* 未读通知行：左侧竖条 + 标题加粗，静默区分（不做动画） */
.qrow.is-unread .q-name {
  font-weight: 600;
}

/* =============================================================
   ★ 窄屏搜索入口（2026-10-23 修复 P3-12）
   ---------------------------------------------------------------
   原来 ≤860px 直接 .search{display:none}，手机上没有任何搜索入口。
   现在：顶栏出现搜索图标按钮（.m-search-btn，默认桌面隐藏），
   点一下在顶栏下方展开搜索条；桌面端样式完全不受影响。
   ============================================================= */
/* 提高选择器权重（0,2,0），保证压过 components.css 里 .icon-btn 的 display */
.icon-btn.m-search-btn {
  display: none;
}

@media (max-width: 860px) {
  .icon-btn.m-search-btn {
    display: inline-flex;
    flex: 0 0 auto;
  }

  .search {
    display: none;
    position: fixed;
    left: 10px;
    right: 10px;
    top: calc(var(--topbar-h) + 8px);
    z-index: var(--z-sticky);
    flex-basis: auto;
    min-width: 0;
    padding: 7px 10px;
    border-radius: var(--r-m);
    background: var(--surface);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-l);
  }

  .search.is-open {
    display: block;
  }

  /* 手机上没有 "/" 快捷键，占位提示没意义 */
  .search .s-kbd {
    display: none;
  }
}