/* ============================================================
   Riva 工作区 · 对话主区 + 右侧卡片工作区
   ------------------------------------------------------------
   视觉基准是卡片式助手界面：暖白页底 + 独立圆角卡片 + 四周留白。

   右侧不是固定信息栏，也不是 Tab 页：它是一个「最近激活卡片栈」。
   顺序、容量、高度全部由 assistant-workspace-layout.js 的确定性规则算出，
   这里只负责把算好的 top/height 画出来。

   这份样式完全独立于 assistant.css，全部收在 `.assistant-ws`
   （和整理空间的 `.assistant-home-mode`）下面。assistant.css 有 8400 行、
   172 个重复选择器，在里面加规则一定会被后面的重复块盖掉。

   开关条件（由 UI 层加/去 `.assistant-ws`）：
     视口 ≥ 721px + 对话态 + 不在整理空间全区模式。
   任何一条不满足就退回 assistant.css 原本的响应式，移动端不受影响。
   ============================================================ */

/* 首屏接管期间只呈现与最终页面一致的暖白画布，不让 assistant.css 的旧版
   对话壳、图标轨或抽屉抢先绘制。这里没有淡入动画；UI 完成布局后直接解除，
   后续脚本若失败则由 boot 脚本的超时保护自动解除。 */
html.assistant-ws-booting {
  background: #F8F7F3;
}

html.assistant-ws-booting body.assistant-page {
  opacity: 0;
  pointer-events: none;
}

/* 注册成 <number>，否则「仅由自定义属性引起的变化」建立不了插值对，
   比例切换会是硬跳而不是过渡。 */
@property --ws-ratio {
  syntax: "<number>";
  inherits: true;
  initial-value: 0.7;
}

/* ============================================================
   1 · Token
   ============================================================ */
.assistant-page.assistant-ws,
.assistant-page.assistant-home-mode {
  --assistant-radius-control: 10px;
  --assistant-radius-card: 18px;
  --assistant-radius-input: 26px;
  --assistant-radius-pill: 999px;

  --radius-xs: 6px;
  --radius-sm: var(--assistant-radius-control);
  --radius-md: 14px;
  --radius-lg: var(--assistant-radius-card);
  --radius-xl: var(--assistant-radius-input);
  --radius-pill: var(--assistant-radius-pill);

  --ws-pad: 20px;
  --ws-gap: 12px;
  --ws-card-gap: 10px;
  --ws-header-h: 56px;

  --ws-card-bg: #FCFBF7;
  --ws-card-border: rgba(28, 28, 30, 0.07);
  --ws-card-shadow:
    0 1px 2px rgba(27, 27, 24, 0.028),
    0 10px 26px -20px rgba(27, 27, 24, 0.18);
  --ws-hairline: rgba(28, 28, 30, 0.07);

  --ws-ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* 卡片重排 300ms（规范 280–340）；Dock 高亮 140ms；hover 140ms。 */
  --ws-reorder-motion: 300ms;
  --ws-motion: 220ms;
  --ws-dock-motion: 140ms;
  --ws-hover-motion: 140ms;
}

/* ============================================================
   2 · 几何
   ------------------------------------------------------------
   左右只有 --ws-ratio 一个数在变；右侧每张卡的 top/height 由 JS
   按「卡片数量 + 各自比例」算成 px 写进来，元素按槽位读。
   槽位一换，值就换成另一组 —— 加上 transition 就是同一空间里的重排。
   ============================================================ */
.assistant-page.assistant-ws {
  --ws-ratio: 0.7;
  --ws-avail-w: calc(100vw - 2 * var(--ws-pad));
  --ws-avail-h: calc(100dvh - var(--ws-header-h) - var(--ws-pad));
  --ws-pane-w: calc(var(--ws-avail-w) - var(--ws-gap));
  --ws-conv-w: calc(var(--ws-pane-w) * var(--ws-ratio));
  --ws-panel-w: calc(var(--ws-pane-w) - var(--ws-conv-w));

  --ws-conv-left: var(--ws-pad);
  --ws-conv-width: var(--ws-conv-w);
  --ws-panel-left: calc(var(--ws-pad) + var(--ws-conv-w) + var(--ws-gap));
  --ws-split-left: calc(var(--ws-pad) + var(--ws-conv-w));

  --ws-right-top: var(--ws-header-h);
  --ws-right-height: var(--ws-avail-h);

  /* 上下阅读：同一个 --ws-ratio，只是换一根轴 —— 对话在上占 ratio，
     卡片排到下面那条横带里，彼此左右并排。 */
  --ws-pane-h: calc(var(--ws-avail-h) - var(--ws-gap));
  --ws-conv-h: calc(var(--ws-pane-h) * var(--ws-ratio));
  --ws-panel-h: calc(var(--ws-pane-h) - var(--ws-conv-h));
  --ws-panel-top: calc(var(--ws-header-h) + var(--ws-conv-h) + var(--ws-gap));
  --ws-split-top: calc(var(--ws-header-h) + var(--ws-conv-h));

  /* 三个槽位：-a 是沿堆叠轴的起点，-s 是沿堆叠轴的尺寸。
     左右并排时是 top/height，上下阅读时是 left/width —— JS 只算一套数，
     由下面的方向规则决定它落到哪根轴上。 */
  --ws-c0-a: var(--ws-right-top);
  --ws-c0-s: var(--ws-right-height);
  --ws-c1-a: var(--ws-right-top);
  --ws-c1-s: 0px;
  --ws-c2-a: var(--ws-right-top);
  --ws-c2-s: 0px;
}

/* 上下阅读：卡片带铺满整个宽度，槽位起点从页边距开始。 */
.assistant-page.assistant-ws[data-ws-orientation="vertical"] {
  --ws-conv-width: var(--ws-avail-w);
  --ws-c0-a: var(--ws-pad);
  --ws-c0-s: var(--ws-avail-w);
  --ws-c1-a: var(--ws-pad);
  --ws-c2-a: var(--ws-pad);
}

.assistant-page.assistant-ws[data-ws-orientation="vertical"].assistant-ws-panel-empty {
  --ws-conv-h: var(--ws-avail-h);
}

/* 右侧一张卡都没有：对话卡吃满内容区。 */
.assistant-page.assistant-ws.assistant-ws-panel-empty {
  --ws-conv-width: var(--ws-avail-w);
}

.assistant-page.assistant-ws.assistant-ws-ready {
  transition: --ws-ratio var(--ws-motion) var(--ws-ease);
}

.assistant-page.assistant-ws.assistant-ws-dragging {
  transition: none;
}

/* 页面本身不滚，滚动交给对话卡自己那一层。 */
.assistant-page.assistant-ws {
  height: 100dvh;
  overflow: hidden;
  background: var(--page-bg);
}

.assistant-page.assistant-ws .assistant-main {
  min-height: 0;
  height: 100%;
  background: transparent;
}

/* ============================================================
   3 · 顶栏
   ============================================================ */
.assistant-ws-header {
  display: none;
}

.assistant-page.assistant-ws .assistant-ws-header {
  /* 账户区按**顶栏自己的可用宽度**收缩，不是按 viewport ——
     顶栏是 100vw 减两侧 20px 内边距，两者不是一个数，而且以后顶栏
     真被放进别的容器里时，按容器判断才不会失效。 */
  container-type: inline-size;
  container-name: ws-header;
  position: fixed;
  z-index: 40;
  top: 0;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  column-gap: 16px;
  height: var(--ws-header-h);
  padding: 0 var(--ws-pad);
  background: transparent;
}

/* ---- 左上角：产品空间入口 ----
   文字在前、图标在后，整块是一个按钮。不是返回键，所以没有箭头；
   也不是下拉，所以没有小三角。静止无底色、无边框、无阴影，
   圆角走 --radius-sm（10px），不做成大胶囊。 */
.assistant-ws-overview {
  justify-self: start;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 10px;
  color: rgba(36, 51, 47, 0.7);
  background: none;
  border: 0;
  font-family: inherit;
  cursor: pointer;
  transition: color var(--ws-dock-motion) ease;
}

.assistant-ws-overview__label {
  font-size: var(--fs-14, 14px);
  /* 550 在多数字体里会落到 500 或 600；这里要的是「比正文稍重、又不到粗体」。 */
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* 按钮外壳只长在图标上，而且**只在 hover / 焦点时出现**：
   静止态完全透明、没有边、没有底 —— 常驻的底色在暖白顶栏上会被读成一块阴影，
   顶栏里唯一该有重量的是当前对话。 */
/* 图标这一格在**布局上**就是图形本身的大小（18×18）。
   这样 gap: 8px 量出来的就是「文字到图形」的距离，眼睛看到的也是 8px ——
   给它一个更大的盒子，gap 就会被盒子里的余量额外撑开。 */
.assistant-ws-overview__mark {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  background: none;
  border: 0;
}

/* 这一格没有任何底色块 —— 顶栏左上角是产品身份，一块浮起来的方底会把它
   读成「被按下了」。反馈改成纯高亮：图形本身变色。
   伪元素只剩一个作用：把命中区从 18px 扩到 38×38，和 Dock 那排一样好点。
   它永远是透明的。 */
.assistant-ws-overview__mark::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 38px;
  height: 38px;
  transform: translate(-50%, -50%);
}

/* 图形要盖在那块底之上：伪元素是定位元素，默认会压在普通子元素上面。 */
.assistant-ws-overview__mark svg {
  position: relative;
  z-index: 1;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.assistant-ws-heading {
  justify-self: center;
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}

.assistant-ws-heading__title {
  margin: 0;
  min-width: 0;
  overflow: hidden;
  color: var(--ink);
  font-size: var(--fs-16, 16px);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: 1;
  transition: opacity 160ms var(--ws-ease);
}

.assistant-ws-heading__title.is-changing {
  opacity: 0;
}

.assistant-ws-heading__state {
  flex: 0 0 auto;
  color: rgba(36, 51, 47, 0.42);
  font-size: var(--fs-12);
}

.assistant-ws-heading__state[hidden] {
  display: none;
}

.assistant-ws-heading__title {
  min-width: 0;
  padding: 4px 6px;
  margin: -4px -6px;
  color: inherit;
  font: inherit;
  text-align: inherit;
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-ws-heading__title:hover {
    background: rgba(18, 83, 72, 0.055);
  }
}

.assistant-ws-tools {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 14px;
}

/* ============================================================
   4 · Dock
   ============================================================ */
.assistant-ws-dock {
  display: flex;
  align-items: center;
  gap: 2px;
}

.assistant-ws-dock__item {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  color: rgba(36, 51, 47, 0.56);
  background: none;
  border: 0;
  /* 圆角常驻。写在 hover 里的话，鼠标移开时 border-radius 立刻跳回 0，
     而底色还在淡出 —— 就会看见一个方块在褪色。底色透明，静止态看不出来。 */
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--ws-dock-motion) ease, background var(--ws-dock-motion) ease;
}

.assistant-ws-dock__item svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.assistant-ws-dock__item[hidden] {
  display: none;
}

/* tooltip：延迟约 450ms 才出现，跟手时不打扰。 */
.assistant-page.assistant-ws [data-ws-tip]::after {
  content: attr(data-ws-tip);
  position: absolute;
  z-index: 61;
  top: calc(100% + 4px);
  left: 50%;
  padding: 4px 8px;
  color: var(--paper-on-dark, #FFFFFF);
  background: rgba(36, 51, 47, 0.9);
  border-radius: var(--radius-xs);
  font-size: var(--fs-12);
  line-height: 1.4;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%);
  transition: opacity var(--ws-hover-motion) ease;
  transition-delay: 0ms;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-page.assistant-ws [data-ws-tip]:hover::after {
    opacity: 1;
    transition-delay: 450ms;
  }

  /* 点下去之后 tooltip 必须让路：面板就从这颗按钮下面展开，
     两块浮层叠在一起谁也读不清。
     · :active 管住按下的那一刻
     · aria-expanded/aria-pressed 管住「点开之后鼠标还停在原处」
     用 display:none 而不是 opacity:0 —— 后者还留着 450ms 的淡出。 */
  .assistant-page.assistant-ws [data-ws-tip]:active::after,
  .assistant-page.assistant-ws [data-ws-tip][aria-expanded="true"]::after,
  .assistant-page.assistant-ws [data-ws-tip][data-ws-tip-mute]::after {
    display: none;
  }

  .assistant-ws-dock__item:hover {
    color: rgba(36, 51, 47, 0.88);
    /* 极浅：静止是完全透明的，hover 只是让它显出可点，不是一块常驻底。 */
    background: rgba(64, 58, 46, 0.05);
  }

  /* 文字和图标的 hover 是**分开**的，尽管点哪儿都去同一个地方：
     · 移到任意一处 —— 整体颜色加深（文字和图形一起亮起来）
     · 只有真的移到图标上 —— 那颗按钮才长出底色
     移到文字上时图标绝不该出现底色块：那读起来像它被按下了。 */
  .assistant-ws-overview:hover {
    color: rgba(36, 51, 47, 0.92);
  }

  .assistant-ws-overview__mark:hover {
    color: var(--brand-green);
  }

  .assistant-ws-dock__item[aria-pressed="true"]:hover {
    color: var(--brand-green);
    background: rgba(18, 83, 72, 0.07);
  }
}

.assistant-page.assistant-ws [data-ws-tip]:focus-visible::after {
  opacity: 1;
  transition-delay: 450ms;
}

.assistant-ws-dock__item:focus-visible {
  color: var(--brand-green);
  background: rgba(18, 83, 72, 0.08);
  outline: none;
}

.assistant-ws-overview:focus-visible {
  color: var(--brand-green);
  outline: none;
}

.assistant-ws-overview:focus-visible .assistant-ws-overview__mark {
  color: var(--brand-green);
}

/* 顶栏太窄时先收文字，图标留着 —— 身份靠 tooltip 和 aria-label 补全。 */
@container ws-header (max-width: 1039px) {
  .assistant-ws-overview__label {
    display: none;
  }

  .assistant-ws-overview {
    padding: 0 8px;
  }
}

/* 卡片在工作区里：只把图标点绿，不加底色块（底色留给 hover）。 */
.assistant-ws-dock__item[aria-pressed="true"] {
  color: var(--brand-green);
  background: none;
}

/* 自由布局：布局键常亮，它是这个编辑模式唯一的持续指示。 */
.assistant-page.assistant-ws.assistant-ws-free [data-ws-layout-toggle] {
  color: var(--brand-green);
}

/* 未读：一个很轻的点。和「在工作区里」那种高亮是两回事 ——
   整理在后台更新时用它提示，不抢用户正在做的事。 */
.assistant-ws-dock__dot {
  position: absolute;
  top: 7px;
  right: 8px;
  width: 5px;
  height: 5px;
  border-radius: var(--radius-pill);
  background: rgba(18, 83, 72, 0.55);
}

.assistant-ws-dock__dot[hidden] {
  display: none;
}

/* 账户单独放在最右，与功能 Dock 之间有一条线。 */
.assistant-ws-account {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-left: 14px;
  border-left: 1px solid var(--ws-hairline);
  /* 一个下限，不是定宽：定宽是为那颗未登录胶囊配的，胶囊撤掉之后
     再占住 178px 会让「登录」两个字孤零零飘在一大片空槽的右边。
     下限约等于「头像 + 一个中等长度的名字」，够挡住大部分抖动。 */
  min-width: 108px;
}

/* 未登录与检查中只占一颗胶囊的真实宽度；不要借用已登录姓名的 108px 槽位。 */
.assistant-ws-account:has(.assistant-ws-account__button[data-auth-state="anonymous"]),
.assistant-ws-account:has(.assistant-ws-account__button[data-auth-state="pending"]) {
  min-width: 0;
  /* 左侧可见的 Flusso 文字从 20px 顶栏内边距再缩进 10px 开始；
     未登录胶囊用外边界与它镜像，因此右侧也留 30px。 */
  margin-right: 10px;
}

.assistant-ws-account:has(.assistant-ws-account__button[data-auth-state="authenticated"]) {
  /* 已登录按钮自身有 8px 右内边距。外壳再留 2px，姓名文字的可见右边
     就同样落在距视口 30px 的镜像基线上。 */
  margin-right: 2px;
}

.assistant-ws-account__button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  max-width: 100%;
  height: 34px;
  padding: 0 8px;
  color: rgba(36, 51, 47, 0.78);
  background: none;
  border: 0;
  /* 圆角在所有状态里都是这一个值，不随内容变。 */
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--fs-13-5, 13.5px);
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: background var(--ws-hover-motion) ease, color var(--ws-hover-motion) ease;
}

/* ---- 头像 ---- */
.assistant-ws-account__avatar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  color: var(--brand-green);
  background: rgba(18, 83, 72, 0.09);
  border-radius: 50%;
  font-size: var(--fs-12);
  font-weight: 600;
  letter-spacing: 0.01em;
}

.assistant-ws-account__initials,
.assistant-ws-account__icon {
  grid-area: 1 / 1;
}

.assistant-ws-account__icon {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* 有首字母就不画图标；首字母为空（没有姓名）才退到中性图标。 */
.assistant-ws-account__initials:not(:empty) + .assistant-ws-account__icon {
  display: none;
}

/* ---- 姓名 ---- */
.assistant-ws-account__name {
  min-width: 0;
  /* 只靠 CSS 收：不按字符数截断，不缩字号，不换行。 */
  max-width: clamp(96px, 9vw, 128px);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ---- 三种状态 ---- */
/* 未登录：只有「登录」胶囊，没有头像。外沿跟随顶栏 20px padding，
   与左上角 Flusso 空间按钮的外沿严格对称。 */
.assistant-ws-account__button[data-auth-state="anonymous"] {
  padding: 0 14px;
  background: var(--ws-card-bg);
  border: 1px solid var(--ws-hairline);
  border-radius: var(--assistant-radius-pill);
}

.assistant-ws-account__button[data-auth-state="anonymous"] .assistant-ws-account__avatar {
  display: none;
}

.assistant-ws-account__button[data-auth-state="anonymous"] .assistant-ws-account__name {
  max-width: none;
  color: var(--brand-green);
}

/* 检查中只保留与未登录胶囊相同的几何占位，但完全不可见。
   不再先画「头像 + 姓名骨架」再翻成登录，避免强刷时像加载了另一个账户。 */
.assistant-ws-account__button[data-auth-state="pending"] {
  width: 58px;
  padding: 0;
  visibility: hidden;
  pointer-events: none;
}

.assistant-ws-account__button[data-auth-state="pending"] .assistant-ws-account__avatar {
  display: none;
}

.assistant-ws-account__button[data-auth-state="pending"] .assistant-ws-account__icon {
  display: none;
}

.assistant-ws-account__button[data-auth-state="pending"] .assistant-ws-account__name {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-ws-account__button:hover {
    color: rgba(36, 51, 47, 0.96);
    background: rgba(64, 58, 46, 0.05);
  }
}

/* 焦点环：主题色、克制，不改尺寸、不换圆角。
   用 box-shadow 而不是 outline —— assistant.css 里有一条
   `.assistant-page :focus-visible { outline: none !important }`
   把全站的 outline 都关掉了，写 outline 在这里是写不出东西来的。
   内圈用卡片底色垫一层，等价于 outline-offset，且不占布局。 */
.assistant-ws-account__button:focus-visible {
  box-shadow: 0 0 0 2px var(--ws-card-bg), 0 0 0 4px rgba(18, 83, 72, 0.45);
}

/* ---- 顶栏变窄时账户区先收姓名，再藏姓名；头像一直是 26px ----
   断点减去顶栏两侧 20px 内边距：container-type: inline-size 量的是内容盒，
   不是元素的外沿。写 1279 会让 1280px 视口落进窄档，差的正好是这 40px。 */
@container ws-header (max-width: 1239px) {
  .assistant-ws-account__name {
    max-width: clamp(72px, 7vw, 88px);
  }

}

@container ws-header (max-width: 1039px) {
  /* 只剩头像。姓名被隐藏，身份由 tooltip 和 aria-label 补全 ——
     它们放的一直是完整显示名，不是这里省略过的那份。 */
  .assistant-ws-account__button[data-auth-state="authenticated"] .assistant-ws-account__name,
  .assistant-ws-account__button[data-auth-state="pending"] .assistant-ws-account__name {
    display: none;
  }

  .assistant-ws-account {
    min-width: 0;
  }

  .assistant-ws-account__button[data-auth-state="authenticated"] {
    padding: 0 4px;
  }
}

/* ============================================================
   5 · 布局菜单
   ============================================================ */
.assistant-ws-layout-menu {
  position: fixed;
  z-index: 60;
  /* 顶边与卡片齐平：菜单读起来是同一排里的又一张卡。 */
  top: var(--ws-header-h);
  right: var(--ws-pad);
  width: 236px;
  padding: 6px;
  background: var(--flusso-surface, #FCFBF7);
  border: 1px solid rgba(28, 28, 30, 0.1);
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 28px rgba(27, 27, 24, 0.09), 0 2px 8px rgba(27, 27, 24, 0.035);
}

.assistant-ws-layout-menu[hidden] {
  display: none;
}

.assistant-ws-layout-menu__group {
  display: grid;
  gap: 1px;
}

.assistant-ws-layout-menu__group + .assistant-ws-layout-menu__group {
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px solid var(--ws-hairline);
}

.assistant-ws-layout-menu button {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 34px;
  padding: 0 10px;
  color: var(--ink);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--fs-13-5, 13.5px);
  text-align: left;
  cursor: pointer;
}

.assistant-ws-layout-menu button > span:last-child {
  color: rgba(36, 51, 47, 0.4);
  font-size: var(--fs-12);
}

.assistant-ws-layout-menu button[aria-checked="true"] {
  color: var(--brand-green);
}

.assistant-ws-layout-menu button[disabled] {
  color: rgba(36, 51, 47, 0.32);
  cursor: default;
}

/* .assistant-ws-layout-menu__group 自己是 display:grid，会盖掉 [hidden]。 */
.assistant-ws-layout-menu__group[hidden] {
  display: none;
}

/* 自由布局：状态开关件。用真正的 switch 形态，不用勾选项 ——
   勾选项读起来是「选了这一项」，开关读起来是「这个模式现在开着」。 */
.assistant-ws-switch {
  /* 打开时不把整行染绿：状态由右边的轨道表达，标题保持原色更安静。 */
  color: var(--ink) !important;
}

.assistant-ws-switch__label {
  font-size: var(--fs-13-5, 13.5px);
}

.assistant-ws-switch__track {
  position: relative;
  display: block;
  width: 34px;
  height: 20px;
  background: rgba(36, 51, 47, 0.16);
  border-radius: var(--assistant-radius-pill);
  transition: background var(--ws-motion) var(--ws-ease);
}

.assistant-ws-switch__knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: #FFFFFF;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(27, 27, 24, 0.18);
  transition: transform var(--ws-motion) var(--ws-ease);
}

.assistant-ws-switch[aria-checked="true"] .assistant-ws-switch__track {
  background: var(--brand-green);
}

.assistant-ws-switch[aria-checked="true"] .assistant-ws-switch__knob {
  transform: translateX(14px);
}

/* 同上：outline 被全局关掉了，这里也必须走 box-shadow。 */
.assistant-ws-switch:focus-visible .assistant-ws-switch__track {
  box-shadow: 0 0 0 2px var(--ws-card-bg), 0 0 0 4px rgba(18, 83, 72, 0.45);
}

@media (prefers-reduced-motion: reduce) {
  .assistant-ws-switch__track,
  .assistant-ws-switch__knob {
    transition: none;
  }
}

.assistant-ws-layout-menu button[hidden] {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-ws-layout-menu button:not([disabled]):hover {
    background: rgba(64, 58, 46, 0.05);
  }
}

.assistant-ws-layout-menu button:focus-visible {
  background: rgba(18, 83, 72, 0.07);
  outline: none;
}

/* ============================================================
   6 · 对话卡
   ============================================================ */
/* 上下阅读：对话铺满宽度，高度吃 --ws-ratio。 */
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-chat-section,
.assistant-page.assistant-ws[data-ws-orientation="vertical"].assistant-records-open .assistant-chat-section {
  height: var(--ws-conv-h);
}

.assistant-page.assistant-ws .assistant-chat-section,
.assistant-page.assistant-ws.assistant-records-open .assistant-chat-section {
  position: fixed;
  z-index: 20;
  left: var(--ws-conv-left);
  top: var(--ws-header-h);
  width: var(--ws-conv-width);
  height: var(--ws-avail-h);
  min-height: 0;
  margin: 0;
  padding: 0;
  display: block;
  overflow: hidden;
  background: var(--ws-card-bg);
  border: 1px solid var(--ws-card-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--ws-card-shadow);
  /* transform 让内部 fixed 的输入区改为相对卡片定位，
     于是被卡片圆角一起裁掉，底部两个角才是完整的。 */
  transform: translateZ(0);
}

.assistant-page.assistant-ws .assistant-chat-shell {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 18px 0 calc(var(--assistant-dock-h, 156px) + 20px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

.assistant-page.assistant-ws .assistant-chat-shell::-webkit-scrollbar {
  display: none;
}

.assistant-page.assistant-ws.assistant-state-chat .assistant-column--chat {
  width: min(calc(100% - 2 * var(--gutter)), var(--assistant-workbench-w));
  max-width: none;
  margin-inline: auto;
}

.assistant-page.assistant-ws .assistant-conversation-bar {
  min-height: 0;
  margin-bottom: 4px;
  padding: 0;
  background: none;
  border-bottom: 0;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.assistant-page.assistant-ws.assistant-state-chat .assistant-chat-title,
.assistant-page.assistant-ws [data-review-toggle],
.assistant-page.assistant-ws .assistant-conversation-bar [data-new-chat],
.assistant-page.assistant-ws .assistant-conversation-bar > [data-open-records] {
  display: none;
}

.assistant-page.assistant-ws.assistant-state-chat .assistant-conversation-actions {
  position: static;
  top: auto;
  right: auto;
  justify-content: flex-end;
}

.assistant-page.assistant-ws .assistant-composer-dock,
.assistant-page.assistant-ws.assistant-records-open .assistant-composer-dock {
  left: 0;
  right: 0;
  width: auto;
  bottom: 0;
  padding: 30px var(--gutter) 16px;
  background: linear-gradient(180deg, rgba(252, 251, 247, 0) 0%, var(--ws-card-bg) 34%, var(--ws-card-bg) 100%);
}

.assistant-page.assistant-ws.assistant-blank .assistant-composer-dock,
.assistant-page.assistant-ws.assistant-blank.assistant-records-open .assistant-composer-dock {
  top: 0;
  background: transparent;
}

.assistant-page.assistant-ws .assistant-composer--chat {
  border-radius: var(--radius-xl);
}

.assistant-page.assistant-ws .assistant-icon-button--mic,
.assistant-page.assistant-ws .assistant-icon-button--send {
  border-radius: 50%;
}

.assistant-page.assistant-ws .assistant-bubble {
  border-radius: var(--radius-md);
}

.assistant-page.assistant-ws .assistant-memory-toast,
.assistant-page.assistant-ws.assistant-records-open .assistant-memory-toast {
  top: calc(var(--ws-header-h) + 56px);
  left: calc(var(--ws-conv-left) + var(--ws-conv-width) / 2);
}

/* ============================================================
   7 · 右侧卡片
   ------------------------------------------------------------
   四张卡：本次整理（.assistant-review）+ 抽屉里的三个面板。
   面板一个节点都没搬 —— 它们本来就在 DOM 里，这里只是给每张单独定位，
   外壳由 JS 在初始化时注入。
   ============================================================ */

/* 抽屉在工作区里不再是一个盒子，只是这三张卡的容器。 */
.assistant-page.assistant-ws .assistant-records,
.assistant-page.assistant-ws .assistant-records[hidden] {
  display: contents !important;
}

.assistant-page.assistant-ws .assistant-records .assistant-tabs,
.assistant-page.assistant-ws .assistant-records .assistant-drawer-bottom,
.assistant-page.assistant-ws .assistant-records__head,
.assistant-page.assistant-ws .assistant-record-caption,
.assistant-page.assistant-ws .assistant-backdrop,
.assistant-page.assistant-ws .assistant-review-backdrop {
  display: none !important;
}

/* 工作区没生效时（窄窗口、移动端、空间总览…），外壳必须彻底隐身。
   外壳是 init 时一次性建好的，之后一直包着源节点 —— 它的**外形**本来就
   只在 .assistant-ws 下才有样式，但标题栏没有，于是就出现了：
   移动端「本次整理」Sheet 顶上不能多出一条卡片标题栏，还带固定和 ×。
   display: contents 让源节点重新变回原来那一层的直接子元素。 */
.assistant-page:not(.assistant-ws) .assistant-ws-card,
.assistant-page:not(.assistant-ws) .assistant-ws-card__body {
  display: contents;
}

.assistant-page:not(.assistant-ws) .assistant-ws-card__head,
.assistant-page:not(.assistant-ws) .assistant-ws-card__summary {
  display: none;
}

/* ---- 卡片外形 ---- */
.assistant-page.assistant-ws .assistant-ws-card,
.assistant-page.assistant-ws .assistant-ws-card[hidden] {
  position: fixed;
  z-index: 21;
  left: var(--ws-panel-left);
  width: var(--ws-panel-w);
  margin: 0;
  padding: 0;
  overflow: hidden;
  display: flex !important;
  flex-direction: column;
  background: var(--ws-card-bg);
  border: 1px solid var(--ws-card-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--ws-card-shadow);
  /* 收起态：原地上移淡出，不从屏幕外飞进来。 */
  visibility: hidden;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
}

/* 槽位。换槽＝换成另一组 top/height，带过渡就是同一空间里的重排。 */
.assistant-page.assistant-ws .assistant-ws-card[data-ws-slot="0"] { top: var(--ws-c0-a); height: var(--ws-c0-s); }
.assistant-page.assistant-ws .assistant-ws-card[data-ws-slot="1"] { top: var(--ws-c1-a); height: var(--ws-c1-s); }
.assistant-page.assistant-ws .assistant-ws-card[data-ws-slot="2"] { top: var(--ws-c2-a); height: var(--ws-c2-s); }

.assistant-page.assistant-ws .assistant-ws-card[data-ws-slot] {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* 搜索 / 记忆 / 记录原来是抽屉直接子项，assistant.css 会在 ready 之前
   就给它们启动一段从 -6px 开始的旧过渡。工作区先关闭那段过渡，
   否则即使方向判断为右，第一帧仍会短暂向左走。 */
.assistant-page.assistant-ws .assistant-records > .assistant-ws-card[data-ws-slot] {
  transition: none;
}

/* 首屏方向跟随卡片中心相对视口 50% 的位置。位移只承担空间提示，
   不做成从屏幕边缘飞入；跨在中线上的卡片只淡入。 */
.assistant-page.assistant-ws.assistant-ws-entering .assistant-chat-section,
.assistant-page.assistant-ws.assistant-ws-entering .assistant-ws-card[data-ws-slot],
.assistant-page.assistant-state-chat.assistant-ws.assistant-ws-entering .assistant-records > .assistant-ws-card[data-ws-slot] {
  opacity: 0;
}

.assistant-page.assistant-ws.assistant-ws-entering .assistant-chat-section[data-ws-enter-from="left"],
.assistant-page.assistant-ws.assistant-ws-entering .assistant-ws-card[data-ws-slot][data-ws-enter-from="left"],
.assistant-page.assistant-state-chat.assistant-ws.assistant-ws-entering .assistant-records > .assistant-ws-card[data-ws-slot][data-ws-enter-from="left"] {
  transform: translateX(-8px) translateZ(0);
}

.assistant-page.assistant-ws.assistant-ws-entering .assistant-chat-section[data-ws-enter-from="right"],
.assistant-page.assistant-ws.assistant-ws-entering .assistant-ws-card[data-ws-slot][data-ws-enter-from="right"],
.assistant-page.assistant-state-chat.assistant-ws.assistant-ws-entering .assistant-records > .assistant-ws-card[data-ws-slot][data-ws-enter-from="right"] {
  transform: translateX(8px) translateZ(0);
}

.assistant-page.assistant-ws.assistant-ws-entering .assistant-chat-section[data-ws-enter-from="center"],
.assistant-page.assistant-ws.assistant-ws-entering .assistant-ws-card[data-ws-slot][data-ws-enter-from="center"],
.assistant-page.assistant-state-chat.assistant-ws.assistant-ws-entering .assistant-records > .assistant-ws-card[data-ws-slot][data-ws-enter-from="center"] {
  transform: translateZ(0);
}

.assistant-page.assistant-ws.assistant-ws-ready .assistant-chat-section {
  transition:
    opacity var(--ws-reorder-motion) var(--ws-ease),
    transform var(--ws-reorder-motion) var(--ws-ease);
}

.assistant-page.assistant-ws.assistant-ws-ready .assistant-ws-card {
  transition:
    top var(--ws-reorder-motion) var(--ws-ease),
    height var(--ws-reorder-motion) var(--ws-ease),
    opacity var(--ws-reorder-motion) var(--ws-ease),
    transform var(--ws-reorder-motion) var(--ws-ease);
}

.assistant-page.assistant-state-chat.assistant-ws.assistant-ws-ready .assistant-records > .assistant-ws-card[data-ws-slot] {
  transition:
    top var(--ws-reorder-motion) var(--ws-ease),
    height var(--ws-reorder-motion) var(--ws-ease),
    opacity var(--ws-reorder-motion) var(--ws-ease),
    transform var(--ws-reorder-motion) var(--ws-ease);
}

/* 拖动时不要过渡，卡片要跟手。 */
.assistant-page.assistant-ws.assistant-ws-dragging .assistant-ws-card,
.assistant-page.assistant-ws.assistant-ws-dragging .assistant-chat-section {
  transition: none !important;
}

/* ---- 卡片标题栏 ---- */
.assistant-ws-card__head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 30px;
  padding: 14px 16px 0;
}

.assistant-ws-card__title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  margin: 0;
  color: var(--brand-green);
  font-family: var(--font-sans);
  font-size: var(--fs-13);
  font-weight: 600;
  letter-spacing: 0.04em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.assistant-ws-card__actions {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.assistant-ws-card__button {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  color: rgba(36, 51, 47, 0.44);
  background: none;
  border: 0;
  border-radius: var(--assistant-radius-control);
  cursor: pointer;
  transition: color var(--ws-hover-motion) ease, background var(--ws-hover-motion) ease;
}

.assistant-ws-card__button svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-ws-card__button:hover {
    color: var(--brand-green);
    background: rgba(64, 58, 46, 0.05);
  }
}

.assistant-ws-card__button:focus-visible {
  color: var(--brand-green);
  background: rgba(18, 83, 72, 0.08);
  outline: none;
}

/* 固定只属于自由布局。常规布局一共两张、基座本来就不会被挤掉，
   钉住没有任何可观察的效果，露出来就是个空按钮。 */
.assistant-ws-card__button[data-ws-card-pin] {
  display: none;
}

.assistant-page.assistant-ws.assistant-ws-free .assistant-ws-card__button[data-ws-card-pin] {
  display: inline-grid;
}

.assistant-page.assistant-ws.assistant-ws-free .assistant-ws-card.is-pinned .assistant-ws-card__button[data-ws-card-pin] {
  color: var(--brand-green);
}

/* ---- 完整态 / 摘要态 ---- */
.assistant-ws-card__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 16px 14px;
  scrollbar-width: none;
}

.assistant-ws-card__body::-webkit-scrollbar {
  display: none;
}

/* 摘要态占满剩下的高度并垂直居中：卡片高度由 50/30/20 决定，
   内容只有一两行，顶着标题排会在下面留一大片空白。 */
.assistant-ws-card__summary {
  flex: 1 1 auto;
  min-height: 0;
  display: none;
  align-content: center;
  gap: 3px;
  padding: 4px 16px 14px;
}

.assistant-ws-card__summary p {
  margin: 0;
  color: rgba(36, 51, 47, 0.72);
  font-size: var(--fs-13);
  line-height: 1.6;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.assistant-ws-card__summary p + p {
  color: rgba(36, 51, 47, 0.44);
  font-size: var(--fs-12);
}

/* 非主卡收起完整内容、只留摘要 —— 但**只在三卡时**。
   三卡是自由布局才给的，下面两张各自只剩 30%/20%，不压缩就互相挤。
   常规两卡（基座「本次整理」+ 一张辅助）都是完整态：各占约一半，
   放得下真正的内容，压成一行摘要只会把整理的空状态弄丢。 */
.assistant-page.assistant-ws[data-ws-count="3"] .assistant-ws-card:not([data-ws-slot="0"]) .assistant-ws-card__body {
  display: none;
}

.assistant-page.assistant-ws[data-ws-count="3"] .assistant-ws-card:not([data-ws-slot="0"]) .assistant-ws-card__summary {
  display: grid;
}

.assistant-page.assistant-ws[data-ws-count="3"] .assistant-ws-card:not([data-ws-slot="0"]) {
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-page.assistant-ws[data-ws-count="3"] .assistant-ws-card:not([data-ws-slot="0"]):hover {
    border-color: rgba(28, 28, 30, 0.12);
  }
}

/* 局部更新：一次短暂的「已更新」，不整张卡闪、不重新加载。 */
.assistant-ws-card__flash {
  color: var(--brand-green);
  font-size: var(--fs-12);
  font-weight: 400;
  letter-spacing: 0;
  opacity: 0;
  transition: opacity 200ms var(--ws-ease);
}

.assistant-ws-card.is-updated .assistant-ws-card__flash {
  opacity: 1;
}

/* assistant.css 把抽屉每个直接子元素钉死在 `--assistant-drawer-w - 36px`
   （204px，左侧抽屉时代的宽度）。卡片外壳正是它的直接子元素，所以这里必须
   赢过那条规则 —— 靠的是选择器多一个类，不是再写一条 width:auto
   （写了反而会把上面卡片规则里的 --ws-panel-w 一起覆盖掉，实测三张记录卡
   会缩成 204px，而 .assistant-review 因为不在抽屉里所以是对的，两边不一样宽）。 */
.assistant-page.assistant-ws .assistant-records > .assistant-ws-card {
  width: var(--ws-panel-w);
  min-width: 0;
  max-width: none;
}

.assistant-page.assistant-ws .assistant-record-panel {
  width: 100%;
  min-width: 0;
  padding: 0;
  overflow: visible;
}

/* 卡片里那一层源节点本来就带 hidden：
   · .assistant-review 初始就是 hidden（按需出现的旁栏时代留下的）
   · selectRecordTab 会给非当前面板加 hidden
   在卡片工作区里，显示权归卡片自己 —— 外壳有没有槽位才是唯一的开关。 */
.assistant-page.assistant-ws .assistant-ws-card__body > [hidden] {
  display: block !important;
}

/* 源节点进了卡片就只是内容，不再是一块自带外壳的浮层。
   .assistant-review 原本是 position:fixed / 340×400 / 自带底色和投影的右侧旁栏；
   卡片上有 translateZ(0)，于是它把卡片当成了包含块，浮在标题栏上面 ——
   看起来就是「卡片内容空了」。这里统一把外壳属性交还给卡片。 */
.assistant-page.assistant-ws .assistant-ws-card__body > * {
  /* assistant.css:7155 的 .assistant-state-chat .assistant-review[hidden] 是
     旧版右侧面板的滑出态：visibility:hidden + opacity:0 + pointer-events:none
     （窄屏那一档还加 translateX）。整理为空时 hidden 一直挂着，
     卡片是可见的、几何也对，里面却整片透明 —— 就是「非登录态一片空白」。
     在卡片工作区里，出现与否归卡片管，不归源节点自己，四条一起收回来。 */
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  position: static;
  inset: auto;
  transform: none;
  width: 100%;
  min-width: 0;
  max-width: none;
  height: auto;
  /* 撑满卡身。源节点如果是「按内容高」，它里面那些 min-height:100% 的
     未登录/空状态就只在**内容**里居中 —— 表现就是提示贴在卡片最上面，
     下面空一大片。这里给它一个确定的高度参照，居中才是相对整张卡。
     内容超出时不裁：卡身自己有 overflow-y: auto。 */
  min-height: 100%;
  max-height: none;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  overflow: visible;
}

.assistant-page.assistant-ws .assistant-history-list,
.assistant-page.assistant-ws .assistant-history-item,
.assistant-page.assistant-ws .assistant-history-item__open,
.assistant-page.assistant-ws .assistant-search-field,
.assistant-page.assistant-ws .assistant-memory-card,
.assistant-page.assistant-ws .assistant-memory-item {
  width: 100%;
  min-width: 0;
  max-width: none;
  box-sizing: border-box;
}

/* 空状态 / 未登录提示在卡片里居中，不贴左上角。
   某张卡未登录只影响它自己，不阻塞别的卡。 */
.assistant-page.assistant-ws .assistant-record-panel .assistant-panel-empty {
  place-content: center;
  justify-items: center;
  min-height: 100%;
  padding: 20px 12px;
  text-align: center;
}

.assistant-page.assistant-ws .assistant-record-panel .assistant-panel-empty p {
  max-width: 34ch;
}

.assistant-page.assistant-ws .assistant-memory-drawer {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  align-content: start;
  gap: 10px;
}

/* 只剩空状态 / 未登录提示时，上面那条 align-content: start 会把它压在卡片最顶上，
   下面空一大片。有便签时顶部对齐是对的，没有时应当居中。 */
.assistant-page.assistant-ws .assistant-memory-drawer:has(> .assistant-panel-empty) {
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
}

/* 搜索面板：输入框固定在上，剩下的高度整块交给结果区，
   未登录提示于是在「输入框以下」这块里居中，而不是紧贴输入框。 */
.assistant-page.assistant-ws .assistant-search-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.assistant-page.assistant-ws .assistant-search-panel > .assistant-search-body {
  flex: 1 1 auto;
  min-height: 0;
}

.assistant-page.assistant-ws .assistant-search-body:has(> .assistant-panel-empty),
.assistant-page.assistant-ws .assistant-history-panel:has(> .assistant-panel-empty) {
  display: grid;
  align-content: center;
}

/* ---- 记忆便签在工作区里只是右侧的一张卡 ----
   assistant.css 把它做成「全区模式」：body.assistant-memory-mode 会把对话区
   整个 display:none，内容改画到 .assistant-memory-workspace。那是左侧抽屉
   时代的形态。卡片工作区里对话必须留着，内容用抽屉那份
   （renderMemoryData 本来就同时写抽屉面板和全区，两边是同一份数据）。 */
.assistant-page.assistant-ws.assistant-memory-mode .assistant-chat-section {
  display: block !important;
}

.assistant-page.assistant-ws.assistant-memory-mode .assistant-memory-workspace {
  display: none !important;
}

.assistant-page.assistant-ws.assistant-memory-mode .assistant-main {
  display: block;
}

/* 本次整理：卡片外壳接管标题与滚动，内部只留分组。 */
.assistant-page.assistant-ws .assistant-review__head,
.assistant-page.assistant-ws .assistant-review__note {
  display: none;
}

.assistant-page.assistant-ws .assistant-review__body {
  display: grid;
  align-content: start;
  gap: 22px;
  overflow: visible;
}

/* ============================================================
   8 · 分隔条
   ------------------------------------------------------------
   静止：看不见。靠近：出现一枚很短的中性胶囊。
   拖动：胶囊加深，并出现一条极细的定位线。松开：定位线消失。
   ============================================================ */
.assistant-ws-splitter,
.assistant-ws-card-splitter {
  display: none;
}

.assistant-page.assistant-ws .assistant-ws-splitter {
  position: fixed;
  z-index: 30;
  left: var(--ws-split-left);
  top: var(--ws-header-h);
  width: var(--ws-gap);
  height: var(--ws-avail-h);
  display: block;
  padding: 0;
  background: none;
  border: 0;
  cursor: col-resize;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

.assistant-page.assistant-ws.assistant-ws-panel-empty .assistant-ws-splitter {
  display: none;
}

/* 卡片之间的横向分隔条：视觉宽度就是那道缝，命中区 16px。 */
.assistant-page.assistant-ws .assistant-ws-card-splitter[data-ws-slot] {
  position: fixed;
  z-index: 30;
  left: var(--ws-panel-left);
  width: var(--ws-panel-w);
  height: 16px;
  display: block;
  padding: 0;
  margin: 0;
  background: none;
  border: 0;
  cursor: row-resize;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

.assistant-page.assistant-ws .assistant-ws-card-splitter[data-ws-slot="0"] {
  top: calc(var(--ws-c0-a) + var(--ws-c0-s) + (var(--ws-card-gap) - 16px) / 2);
}

.assistant-page.assistant-ws .assistant-ws-card-splitter[data-ws-slot="1"] {
  top: calc(var(--ws-c1-a) + var(--ws-c1-s) + (var(--ws-card-gap) - 16px) / 2);
}

/* ============================================================
   上下阅读（orientation: vertical）
   ------------------------------------------------------------
   对话在上、卡片带在下；卡片在带子里左右并排。
   JS 只算一套「沿堆叠轴的起点 -a / 尺寸 -s」，这里把它接到 left/width 上。
   ============================================================ */
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card,
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card[hidden],
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-records > .assistant-ws-card {
  left: auto;
  width: auto;
  top: var(--ws-panel-top);
  height: var(--ws-panel-h);
  /* 收起态在这根轴上是左移淡出。 */
  transform: translateX(-6px);
}

.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card[data-ws-slot="0"] { left: var(--ws-c0-a); width: var(--ws-c0-s); top: var(--ws-panel-top); height: var(--ws-panel-h); }
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card[data-ws-slot="1"] { left: var(--ws-c1-a); width: var(--ws-c1-s); top: var(--ws-panel-top); height: var(--ws-panel-h); }
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card[data-ws-slot="2"] { left: var(--ws-c2-a); width: var(--ws-c2-s); top: var(--ws-panel-top); height: var(--ws-panel-h); }

.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card[data-ws-slot] {
  transform: none;
}

.assistant-page.assistant-ws[data-ws-orientation="vertical"].assistant-ws-ready .assistant-ws-card {
  transition:
    left var(--ws-reorder-motion) var(--ws-ease),
    width var(--ws-reorder-motion) var(--ws-ease),
    opacity var(--ws-reorder-motion) var(--ws-ease),
    transform var(--ws-reorder-motion) var(--ws-ease);
}

/* 主分隔条转成横的：在对话和卡片带之间。 */
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-splitter {
  left: var(--ws-pad);
  top: var(--ws-split-top);
  width: var(--ws-avail-w);
  height: var(--ws-gap);
  cursor: row-resize;
}

/* 卡片之间的分隔条转成竖的。 */
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card-splitter[data-ws-slot] {
  left: auto;
  top: var(--ws-panel-top);
  width: 16px;
  height: var(--ws-panel-h);
  cursor: col-resize;
}

.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card-splitter[data-ws-slot="0"] {
  top: var(--ws-panel-top);
  left: calc(var(--ws-c0-a) + var(--ws-c0-s) + (var(--ws-card-gap) - 16px) / 2);
}

.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card-splitter[data-ws-slot="1"] {
  top: var(--ws-panel-top);
  left: calc(var(--ws-c1-a) + var(--ws-c1-s) + (var(--ws-card-gap) - 16px) / 2);
}

/* 卡片带很矮，摘要态在这里没有意义：并排的卡各自还有整幅高度。 */
.assistant-page.assistant-ws[data-ws-orientation="vertical"][data-ws-count="3"] .assistant-ws-card:not([data-ws-slot="0"]) .assistant-ws-card__body {
  display: block;
}

.assistant-page.assistant-ws[data-ws-orientation="vertical"][data-ws-count="3"] .assistant-ws-card:not([data-ws-slot="0"]) .assistant-ws-card__summary {
  display: none;
}

/* 把手：一颗短胶囊，静止完全透明，靠近才出现，拖动时留在原地稍微加深。
   除了它以外，拖动过程中不再画任何东西 —— 之前那条贯穿整栏的 1px 定位线
   已经删掉：它比胶囊本身重得多，看起来像把页面切开了。 */
.assistant-ws-splitter::before,
.assistant-ws-card-splitter::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: var(--assistant-radius-pill);
  background: rgba(36, 51, 47, 0);
  transform: translate(-50%, -50%);
  transition: background var(--ws-hover-motion) ease;
}

/* 胶囊永远垂直于它能拖的方向。方向一换，两条分隔条的走向就对调，
   所以尺寸也得跟着换，否则会出现一颗横胶囊配一条竖着拖的边。 */
.assistant-ws-splitter::before,
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-card-splitter::before {
  width: 3px;
  height: 32px;
}

.assistant-ws-card-splitter::before,
.assistant-page.assistant-ws[data-ws-orientation="vertical"] .assistant-ws-splitter::before {
  width: 32px;
  height: 3px;
}

/* 中性灰，不用主题绿 —— 绿会读成「被选中」。 */
@media (hover: hover) and (pointer: fine) {
  .assistant-page.assistant-ws .assistant-ws-splitter:hover::before,
  .assistant-page.assistant-ws .assistant-ws-card-splitter:hover::before {
    background: rgba(36, 51, 47, 0.26);
  }
}

/* 拖动中：胶囊是唯一的反馈，所以必须一直在，并且略微加深。
   不到 0.5 —— 那一档在暖白底上是一道黑杠。 */
.assistant-page.assistant-ws.assistant-ws-dragging .assistant-ws-splitter::before,
.assistant-page.assistant-ws.assistant-ws-dragging .assistant-ws-card-splitter::before {
  background: rgba(36, 51, 47, 0.34);
}

.assistant-page.assistant-ws .assistant-ws-splitter:focus-visible::before,
.assistant-page.assistant-ws .assistant-ws-card-splitter:focus-visible::before {
  background: rgba(36, 51, 47, 0.42);
}

.assistant-page.assistant-ws .assistant-ws-splitter:focus-visible,
.assistant-page.assistant-ws .assistant-ws-card-splitter:focus-visible {
  outline: none;
}

/* 自由布局不再让胶囊常驻：它是「可以拖」的模式，不是「到处都是把手」的模式。 */

.assistant-page.assistant-ws.assistant-ws-dragging,
.assistant-page.assistant-ws.assistant-ws-dragging * {
  -webkit-user-select: none;
  user-select: none;
}

.assistant-page.assistant-ws.assistant-ws-dragging {
  cursor: col-resize;
}

.assistant-page.assistant-ws.assistant-ws-dragging.is-row-drag {
  cursor: row-resize;
}

/* ============================================================
   9 · 本次整理的空状态
   ============================================================ */
.assistant-ws-empty {
  display: none;
}

.assistant-page.assistant-ws .assistant-ws-card.is-empty .assistant-ws-empty {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-height: 100%;
}

.assistant-ws-summary-empty {
  flex: 0 0 auto;
  display: grid;
  justify-items: center;
  gap: 6px;
  padding: 26px 20px 24px;
  background: #FDFCFA;
  border: 1px solid rgba(28, 28, 30, 0.05);
  border-radius: var(--radius-md);
  text-align: center;
}

.assistant-ws-summary-empty__mark {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 8px;
  color: rgba(36, 51, 47, 0.34);
  background: rgba(64, 58, 46, 0.045);
  border-radius: var(--assistant-radius-pill);
}

.assistant-ws-summary-empty__mark svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.assistant-ws-summary-empty p {
  margin: 0;
  color: rgba(36, 51, 47, 0.78);
  font-size: var(--fs-14);
  line-height: 1.7;
}

.assistant-ws-summary-empty p + p {
  color: rgba(36, 51, 47, 0.46);
  font-size: var(--fs-13);
  line-height: 1.75;
}

.assistant-ws-starters {
  display: none;
}

.assistant-page.assistant-ws .assistant-ws-card.is-empty .assistant-ws-starters:not([hidden]) {
  flex: 0 0 auto;
  display: grid;
  gap: 8px;
}

.assistant-ws-starters__label {
  margin: 0;
  color: rgba(36, 51, 47, 0.42);
  font-size: var(--fs-12);
}

.assistant-ws-starters__card {
  overflow: hidden;
  background: transparent;
  border: 1px solid var(--ws-card-border);
  border-radius: var(--radius-md);
}

.assistant-ws-starter {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) 12px;
  align-items: center;
  column-gap: 12px;
  width: 100%;
  min-height: 58px;
  padding: 10px 14px;
  color: inherit;
  background: none;
  border: 0;
  border-radius: 0;
  font-family: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--ws-hover-motion) ease;
}

.assistant-ws-starter + .assistant-ws-starter {
  position: relative;
}

.assistant-ws-starter + .assistant-ws-starter::before {
  content: "";
  position: absolute;
  top: 0;
  left: 46px;
  right: 0;
  height: 1px;
  background: var(--ws-hairline);
}

.assistant-ws-starter__icon {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  color: rgba(36, 51, 47, 0.42);
}

.assistant-ws-starter__icon svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.assistant-ws-starter__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.assistant-ws-starter__title {
  color: var(--ink);
  font-size: var(--fs-13-5, 13.5px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.assistant-ws-starter__note {
  color: rgba(36, 51, 47, 0.44);
  font-size: var(--fs-12);
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.assistant-ws-starter__arrow {
  color: rgba(36, 51, 47, 0.3);
}

.assistant-ws-starter__arrow svg {
  display: block;
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-ws-starter:hover {
    background: rgba(64, 58, 46, 0.045);
  }
}

.assistant-ws-starter:focus-visible {
  background: rgba(18, 83, 72, 0.075);
  outline: none;
}

.assistant-ws-starters__hint {
  margin: 0;
  color: rgba(36, 51, 47, 0.4);
  font-size: var(--fs-12);
  line-height: 1.6;
}

.assistant-ws-starters__hint button,
.assistant-home__empty-hint button {
  padding: 0;
  color: var(--brand-green);
  background: none;
  border: 0;
  border-radius: 0;
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
}

/* Space 是任务工作区，不使用「网页链接」式下划线来表达可点。
   所有入口继续保留颜色、图标、行容器与焦点环，避免把可达性降成纯文本。 */
.assistant-page :is(a, button),
.assistant-page :is(a, button):hover,
.assistant-page :is(a, button):active,
.assistant-page :is(a, button):focus,
.assistant-page :is(a, button):focus-visible,
.assistant-page :is(a, button) * {
  text-decoration: none !important;
  text-decoration-line: none !important;
}

.assistant-ws-empty__privacy {
  display: none;
}

.assistant-page.assistant-ws .assistant-ws-card.is-empty .assistant-ws-empty__privacy {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  align-items: start;
  column-gap: 8px;
  margin: auto 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--ws-hairline);
  color: rgba(36, 51, 47, 0.4);
  font-size: var(--fs-12);
  line-height: 1.6;
}

.assistant-ws-empty__privacy svg {
  width: 13px;
  height: 13px;
  margin-top: 2px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ============================================================
   10 · 输入框上方的动态行动卡片
   ============================================================ */
.assistant-ws-actions {
  display: none;
}

.assistant-page.assistant-ws .assistant-ws-actions:not([hidden]) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  width: min(calc(100% - 2 * var(--gutter)), var(--assistant-workbench-w, 720px));
  margin: 0 auto 10px;
}

.assistant-ws-actions__primary {
  min-height: 32px;
  padding: 0 12px;
  color: var(--paper-on-dark, #FFFFFF);
  background: var(--brand-green);
  border: 1px solid var(--brand-green);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--fs-13);
  cursor: pointer;
}

/* ============================================================
   11 · 新对话确认 / 总览返回
   ============================================================ */
.assistant-ws-confirm {
  display: none;
}

.assistant-page.assistant-ws .assistant-ws-confirm:not([hidden]) {
  position: fixed;
  z-index: 62;
  top: var(--ws-header-h);
  right: calc(var(--ws-pad) + 120px);
  display: grid;
  gap: 10px;
  width: 268px;
  padding: 14px;
  background: var(--ws-card-bg);
  border: 1px solid rgba(28, 28, 30, 0.1);
  border-radius: var(--assistant-radius-card);
  box-shadow: 0 12px 28px rgba(27, 27, 24, 0.09), 0 2px 8px rgba(27, 27, 24, 0.035);
}

.assistant-ws-confirm p {
  margin: 0;
  color: var(--ink);
  font-size: var(--fs-13-5, 13.5px);
  line-height: 1.6;
}

.assistant-ws-confirm__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.assistant-ws-confirm__actions button {
  min-height: 30px;
  padding: 0 12px;
  border-radius: var(--assistant-radius-control);
  font-family: inherit;
  font-size: var(--fs-13);
  cursor: pointer;
}

.assistant-ws-confirm__actions button[data-ws-confirm-cancel] {
  color: rgba(36, 51, 47, 0.72);
  background: none;
  border: 1px solid var(--ws-card-border);
}

.assistant-ws-confirm__actions button[data-ws-confirm-ok] {
  color: var(--paper-on-dark, #FFFFFF);
  background: var(--brand-green);
  border: 1px solid var(--brand-green);
}

.assistant-ws-resume {
  display: none;
}

.assistant-page.assistant-home-mode .assistant-ws-resume {
  position: fixed;
  z-index: 41;
  top: 9px;
  right: var(--ws-pad, 20px);
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  color: rgba(36, 51, 47, 0.56);
  background: none;
  border: 0;
  border-radius: var(--assistant-radius-control, 10px);
  cursor: pointer;
  transition: color 140ms ease, background 140ms ease;
}

.assistant-ws-resume svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.assistant-ws-resume__dot {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 5px;
  height: 5px;
  border-radius: var(--assistant-radius-pill, 999px);
  background: var(--brand-green);
}

.assistant-ws-resume__dot[hidden] {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .assistant-page.assistant-home-mode .assistant-ws-resume:hover {
    color: var(--brand-green);
    background: rgba(64, 58, 46, 0.05);
  }
}

.assistant-page.assistant-home-mode .assistant-ws-resume:focus-visible {
  color: var(--brand-green);
  background: rgba(18, 83, 72, 0.08);
  outline: none;
}

/* ============================================================
   12 · 你的整理空间
   ============================================================ */
@media (min-width: 721px) {
  .assistant-page.assistant-home-mode .assistant-home {
    position: fixed;
    z-index: 20;
    left: var(--ws-pad);
    top: var(--ws-header-h);
    width: calc(100vw - 2 * var(--ws-pad));
    height: calc(100dvh - var(--ws-header-h) - var(--ws-pad));
    min-height: 0;
    overflow-y: auto;
    background: var(--ws-card-bg);
    border: 1px solid var(--ws-card-border);
    border-radius: var(--assistant-radius-card);
    box-shadow: var(--ws-card-shadow);
    scrollbar-width: none;
  }

  .assistant-page.assistant-home-mode .assistant-home::-webkit-scrollbar {
    display: none;
  }
}

.assistant-page.assistant-home-mode .assistant-home__input {
  border-radius: var(--assistant-radius-input);
  border-color: var(--ws-card-border);
  padding: 14px 16px 14px 20px;
}

.assistant-page.assistant-home-mode .assistant-home__card,
.assistant-page.assistant-home-mode .assistant-home__cand {
  border-radius: var(--radius-md, 14px);
}

/* 发送键：空输入时也保持正常外观。压透明度会让它读起来像「功能失效」，
   而它其实只是在等一句话 —— 真正拦住空提交的是 disabled 属性本身。 */
.assistant-page.assistant-home-mode .assistant-home__send[disabled] {
  opacity: 1;
  background: var(--brand-green);
}

.assistant-page.assistant-home-mode .assistant-home__send[disabled] svg {
  stroke: #FFFFFF;
}

.assistant-home__empty {
  display: none;
}

.assistant-page.assistant-home-mode .assistant-home__inner:has([data-home-recent][hidden]):has([data-home-pending][hidden]) .assistant-home__empty {
  display: grid;
  gap: 8px;
  padding: 26px 22px 28px;
  background: rgba(64, 58, 46, 0.028);
  border: 0;
  border-radius: var(--radius-md, 14px);
}

.assistant-home__empty p {
  margin: 0;
  color: rgba(36, 51, 47, 0.78);
  font-size: 14px;
  line-height: 1.7;
}

.assistant-home__empty p + p {
  color: rgba(36, 51, 47, 0.48);
  font-size: 13px;
  line-height: 1.75;
}

.assistant-home__empty-hint[hidden] {
  display: none;
}

/* ============================================================
   13 · 减少动态效果
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .assistant-page.assistant-ws {
    transition: none;
  }

  .assistant-page.assistant-ws.assistant-ws-ready {
    transition: none;
  }

  .assistant-page.assistant-ws .assistant-chat-section,
  .assistant-page.assistant-ws .assistant-composer-dock {
    transition: none;
  }

  /* 卡片重排只留一段极短的淡入，位移取消。 */
  .assistant-page.assistant-ws.assistant-ws-ready .assistant-ws-card {
    transition: opacity 90ms linear;
  }

  .assistant-page.assistant-ws .assistant-ws-card,
  .assistant-page.assistant-ws .assistant-ws-card[data-ws-slot] {
    transform: none;
  }

  .assistant-page.assistant-ws.assistant-ws-entering .assistant-chat-section {
    opacity: 1;
    transform: translateZ(0);
  }

  .assistant-page.assistant-ws.assistant-ws-entering .assistant-ws-card[data-ws-slot][data-ws-enter-from],
  .assistant-page.assistant-state-chat.assistant-ws.assistant-ws-entering .assistant-records > .assistant-ws-card[data-ws-slot] {
    opacity: 1;
    transform: none;
  }
}
