/* ai-chat-studio-stage.css - the workbench: brand framing, the two panes, the working ring, the drag handle, mobile layout.
   One of the Studio stylesheet's 7 parts (part 3). They are contiguous slices of what used to be one
   file, and ai-chat-styles.liquid loads them in this order - the cascade depends on it, so a new part goes at the
   end of its own section, never between two others (gate: scripts/ui/studio-css-parts.test.mjs). */

/* ── Brand 层镶框(契约 §2C):有品牌 → view-page 底色 + 两窗口边框 = 品牌色(细缝天然镶色);无品牌走中性 ── */
/* 品牌色不再勾窗口大轮廓(饱和色×大周长=扎眼,再细也压不住,且暗色品牌又会看不见)→ 窗口全中性。
   品牌色只集中到 header 品牌名那个真色小胶囊(.studio-org-brand-name.is-clickable = 有品牌态,见下),
   小面积+真色:亮黄不扎眼、藏蓝看得见、颜色还保真。 */
/* 品牌卡拖到操作区的蒙层 = 去色中性(.brand-drop-hover::after 用 --studio-drop-tint,在 ai-chat-base.css) */
.studio-brand-card.dragging { opacity: var(--dim); }
/* collection 的品牌色圆点:★移到名字【前面】(替代原文件夹图标位)。尺寸/圆度复用图片页 .images-filter-item-dot(9px)单一基准。
   无品牌 → .is-empty 透明占位,保留同样的位置与间距 → 有品牌/无品牌的 collection 名左缘对齐一致。 */
.studio-collection-brand-dot { margin-right: 9px; }
.studio-collection-brand-dot.is-empty { background: transparent; }
/* collection 行拖动排序拖起态:行本身 live 跟随插入点(无拖影),淡出表示"被抓着"(同 brand/agent 卡基准) */
.studio-collection-item.dragging { opacity: var(--dim); }
/* 架构区 header:常驻 + 预留固定高度(不随品牌有无显隐,防抖动;以后放别的东西) */
/* 高度 = sidebar header(--duo-header-h)减去 studio 缝隙(窗口比 sidebar 往下缩进 --duo-window-gap)→ 分割线与 sidebar 齐平 */
.studio-org-header { flex-shrink: 0; display: flex; align-items: center; height: calc(var(--duo-header-h) - var(--duo-window-gap)); box-sizing: border-box; padding: 6px 24px; border-bottom: 1px solid var(--color-border); }
/* 本机连接状态:靠右,与品牌名同一行。★这一栏的 agent 圆圈【有意】不显示上下线(见下方注释),
   所以这里不引入那套语言 —— 单色点,不发明 success/warn 配色(代码库里没有这两个色标)。
   实心=那台机器开着(三分钟内报过平安)· 淡=连着但没开机 · 无点=还没连过 */
/* 右边距要跟上边距一样。上边距是算出来的:header 高 60-4=56,上下 padding 各 6 → 内容 44,
   36px 的按钮居中 → (44-36)/2=4,所以离顶 6+4=10px。而 header 横向 padding 是 24px。
   竖向没法加到 24(header 就 56 高),所以让按钮反向溢出 24-10=14px,四边才看着一致。
   ★品牌名仍然靠那 24px 站着,不动 header 的 padding —— 动它会把名字也一起挪了。 */
.studio-bench-btn { margin-left: auto; margin-right: -14px; position: relative; flex-shrink: 0; }
/* 24px 而不是 header 按钮默认的 18px:链条那个字形只占 viewBox 中间三分之一的高度,
   按 18px 画出来的墨迹比同尺寸的三点/分享小一大截。改的是【看上去多大】,不是声明值。
   同特异性靠加载顺序压过 ai-chat-base.css(studio.css 在它之后),不用 !important。 */
.studio-bench-btn svg { width: var(--icon-size); height: var(--icon-size); }
/* ★状态画在【图标本身】,不再外挂一个小点:一个 6-9px 的点贴在图标角上,在深色 header 上
   读起来像屏幕上的灰尘,而且用两个元素说一件事。
   只给"开着"上色 —— 机器没开是正常状态(你合上笔记本而已),不是故障,给它常驻一个
   警示色等于天天报警、看久了就没人看了。没开/没连过一律普通次级灰。 */
/* ★这里【不许】挂 html:not([data-input="touch"]):那道门是给 :hover 用的,而"在线"是状态。
   挂上去的后果是手机(html[data-input=touch])上这条整条失效 —— 图标压根不变绿,只剩那层
   淡光晕,于是同一个"已连上"在两端看起来完全不是一回事(owner 2026-08-09 实拍)。
   ★两条都要写:暗色的 hover 是 `.dark-mode .chat-header-btn:hover`(0,3,0),只写一条
   (0,2,0) 会被它压过去 —— 表现成"鼠标一放绿就变白"。同层级说清即可,不用 !important。
   hover 的反馈仍然由背景给:背景管交互反馈,颜色管状态,两件事不许互相抢。 */
.studio-bench-btn.is-online,
.dark-mode .studio-bench-btn.is-online{ color: var(--color-live); }
/* 开着 = 一盏亮着的灯。光用 drop-shadow:它按【图标自身的形状】渲染,所以是沿着线条散出来的
   边缘光,而不是在图标背后糊一个圆 —— 形状仍然是那个链条。两层是为了近处实、远处虚。
   ★呼吸幅度必须极小(1 → 1.05):真灯不会跳,它只是"活着"。看得出在动就过头了。 */
.studio-bench-btn.is-online svg {
  animation: studio-bench-breathe 3.6s ease-in-out infinite;
  transform-origin: 50% 50%;
}
@keyframes studio-bench-breathe {
  0%, 100% { transform: scale(1);    filter: drop-shadow(0 0 1px var(--color-live)) drop-shadow(0 0 2.5px var(--color-live)); }
  50%      { transform: scale(1.04); filter: drop-shadow(0 0 1px var(--color-live)) drop-shadow(0 0 4px var(--color-live)); }
}
/* 关掉动效偏好的人,灯照样亮着 —— 光才是"开着"这个意思的载体,呼吸只是让它像真的。
   两件事分开:去掉会动的那半,不去掉意思。 */
@media (prefers-reduced-motion: reduce) {
  .studio-bench-btn.is-online svg {
    animation: none;
    filter: var(--live-glow);   /* 静止态的光走真源(唯一写法在 base.css) */
  }
}
.studio-org-brand-name { font-size: 14px; font-weight: 500; color: var(--color-text); }
.studio-org-brand-name.is-hint { font-weight: 400; color: var(--color-text-secondary); }   /* 无品牌引导提示:淡色 */
/* 品牌名的定位容器 = 下拉触发器:承载 .version-dropdown(绝对定位需定位父级)与 .open 展开态 */
.studio-org-brand-wrap { position: relative; display: inline-flex; align-items: center; gap: 2px; }
.studio-org-brand-wrap:has(.is-clickable) { cursor: pointer; }
/* 有品牌 → 品牌名做成真色小胶囊(底=真品牌色 --studio-brand-color,字=按亮度自动黑/白 --studio-brand-fg,均由 JS applyBrandFrame 写在 page 上) */
.studio-org-brand-name.is-clickable {
  background: var(--studio-brand-color);
  color: var(--studio-brand-fg);
  border-radius: 999px;
  corner-shape: round;
  padding: 3px 10px;
  transition: filter 0.15s, background-image 0.15s;
}
/* ★没有品牌可穿的对象(agent)= 中性皮:同样的胶囊,底色中性。
   必须【明写背景】而不是只把内联的 --studio-brand-color 删掉 —— 删掉之后 var() 会继续往上
   继承 page 上那份(applyBrandFrame 写的当前 collection 品牌色),于是 agent 穿着别人家的品牌色
   (owner 2026-09-04 实拍:agent 页名字是 Paspaley 的黄)。这个类以前只加在元素上、没有任何规则。 */
.studio-org-brand-name.is-clickable.tc-obj-neutral {
  background: var(--color-bg-card);
  color: var(--color-text);
}
/* hover (pointer only) darkens with filter; PRESS darkens with a translucent overlay and NO filter: on iOS a filter
   applied at tap time promotes a new compositing layer, which paints white for a frame (owner 2026-09-06 phone capture: the capsule
   flashed white). The overlay keeps the true brand colour underneath and needs no layer. */
html:not([data-input="touch"]) .studio-org-brand-wrap:hover .studio-org-brand-name.is-clickable{ filter: brightness(var(--press-hover)); }

.studio-org-brand-wrap:active .studio-org-brand-name.is-clickable { filter: none; background-image: linear-gradient(var(--press-overlay), var(--press-overlay)); }
.studio-org-brand-name .brand-hint-short { display: none; }   /* 桌面显完整引导句;手机切成只"No brand"(见 max-width:768px) */

/* ── 栏2+3：主区 ── */
.studio-main { flex: 1; min-width: 0; display: flex; position: relative; }
/* 两栏各自是独立的层叠上下文:栏内控件的 z-index(如 composer 加号的 20)只在栏内比大小,
   不再外泄到 .studio-main 里去压过欢迎覆盖层(z-index 3) —— 否则无 collection 时加号会从覆盖层底下透出来 */
.studio-org-chart, .studio-meeting { isolation: isolate; }

/* 栏2：组织架构图 */
.studio-org-chart { flex: 0 0 60%; min-width: 0; display: flex; flex-direction: column; }
/* ★竖向必须 auto 不能 hidden:5 行是"平分高度"(.studio-org-row flex:1),可 flex 项压不到自身内容
   高度以下 —— 容器矮于 5×内容(手机横屏实测 332 < 551)时就一定溢出,hidden 会把第 3~5 行钉死裁掉、
   人还滚不到。横向仍 hidden(连线 SVG 与光靠它裁,行内横滑由 .studio-org-agents 自己管)。 */
.studio-org-scroll { flex: 1; overflow-y: auto; padding: 0 24px; position: relative; min-height: 0; display: flex; flex-direction: column; -webkit-overflow-scrolling: touch; }

/* top/left:0(不用 inset:0)→ 尺寸由 JS 设的 width/height 属性(=scrollWidth/Height)决定,横滑时随内容一起滚、覆盖满整棵树 */
.studio-org-links { position: absolute; top: 0; left: 0; pointer-events: none; z-index: 0; opacity: 0.9; }   /* 全连后线多了,整体压 10%(owner 2026-08-23);颜色仍是 --color-border 单一源 */
.studio-org-row {
  flex: 1;   /* header 以下高度 5 等分,每行占 1/5,内容(align-items:center)在各自 band 竖直居中 */
  display: flex; align-items: center; justify-content: center; gap: 16px;   /* 圆圈组水平居中 */
  position: relative; z-index: 1;
}
/* 岗位名钉在左边(绝对定位,不参与居中)→ 各行标签左对齐成一列;圆圈组在整行水平居中 */
.studio-org-row-label { position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 96px; font-size: 12px; color: var(--color-text-secondary); }
.studio-org-agents { display: flex; justify-content: center; gap: 22px; flex-wrap: wrap; }
/* 拖拽 = 指针事件自绘拖影(ui-chat-pointer-drag.js),不用 HTML5 draggable。
   ★别改回 draggable:iOS WebKit 的长按 lift 预览把元素矩形包围盒合成到不透明黑底板上(透明像素全变黑、
   不读 border-radius),圆形元素必然带黑方块 —— 2026-07-22 iPhone 真机 A/B/C 对照坐实,无 CSS 解。 */
.studio-org-agent {
  display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer;
}
/* 头像圆圈 = 单一真源 --avatar-bg/--avatar-fg（复用全站头像规范色） */
.studio-org-agent-circle {
  width: 80px; height: 80px; border-radius: 50%;
  corner-shape: round;
  background: var(--avatar-bg); color: var(--avatar-fg);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 500; letter-spacing: 0.5px;
  /* ★这条 2px 边框保留(owner 2026-08-09 定:带边框、圈 r=30 的那一版才是真正的同心圆)。
     我曾为了消掉图与圈之间那条暗缝去拆它 —— 那是拆错了对象:缝要靠【把圈收小】消,
     不是靠改变头像本身的尺寸。 */
  border: 2px solid transparent; box-sizing: border-box;
}
/* 圆圈不再显示上/下线(旧 .online 描边已去)。参与与否=行级 .row-inactive */
/* ── 干活中:一条发绿光的线顺时针把圆画满,画满即从头再画(owner 参照 EVE 的模块激活圈)──
   ★这【不是】上传进度环:那一个是按真百分比擦扇形的(ai-chat-base.css 的 [data-uploading]),
   它的断言明确禁止"不知道百分比就转圈"的变体。这里表达的是【在干、不知道还要多久】,
   两件事、两个画法,别互相搬。
   ★必须【矢量描边】,不许用"锥形渐变 + 环形遮罩挖一条线":后者两条边都靠抗锯齿摊出来,
   1x 光栅下实测只剩 ~1px 实心 + 两侧灰边 = 又细又发灰、弧头带台阶(owner:"不利落")。
   描边由浏览器按路径画,粗细恒定、端点干净。
   ★线画在【盘外】:画在圆圈那条边框带上会读成"这个黑盘缩小了一圈"(实测坐实)。
   几何取自实测余量:邻居横向 22px、到名字竖向 6px → inset -4px + 3px 线,
   外扩 5.5px 不碰名字、离盘 2.5px。
   颜色/光走 --color-live + --live-glow(真源在 base.css,与本地手在线灯同一口井);
   线带透明度 = 让它像发光的痕迹,不像一根实心塑料环。
   pathLength=100 把周长归一化 → dash 用 0-100,换半径/换到别的尺寸头像都不用重算圆周长。
   SVG 的 0° 在 3 点,所以整体转 -90° 从 12 点起笔、顺时针。 */
.studio-org-agent-circle { position: relative; }
/* ★光【不在线上】:绿光是圆盘自己在呼吸(owner 2026-08-08 指着 EVE 那张图定的 ——
   盘外那圈线是白/灰的,绿的是整个图标周围那团弥散的光)。所以这里不挂 filter。 */
/* ★半径比盘沿只大 2px:描边(3.4)跨在这个半径上 → 内侧压在头像图层【上面】、外侧露在盘外,
   两者之间不留缝。原先 -4px 会在盘与线之间露一条底色的黑缝(owner 2026-08-08 实拍点名)。
   svg 挂在图/缩写【之后】,所以天然盖在头像那一层上。 */
/* 下面这些数值都留了旋钮变量(默认值写在 var 的第二参),控制台 window.DuoRing 可现调,
   调完 DuoRing.dump() 吐出要粘回这里的那几行 —— 同珍珠那套 DuoPearl 的做法。 */
/* ★尺寸必须【显式写宽高】,不能用 inset 四边偏移去撑:<svg> 是替换元素,WebKit 按规范
   不拉伸它 —— 用 inset 时 iOS 上盒子仍是包含块的 56(而不是 58),于是半径小 2px、
   圆心左上偏 1px、起点跟着偏左(owner 2026-08-09 真机 ringdiag:svgBox 56x56 / r 28 /
   c 29,29,而 Chrome 同样代码是 58 / 29 / 30,30 —— 我只在 Chrome 量,所以一直没看见)。
   ★inset 用【百分比】不用 px:描边宽度随盒子缩放,所以"贴着盘沿"只有按比例写才在任何
   头像尺寸(手机 60 / 桌面 80 / 折叠 48)上都成立,写死 px 只能对一个尺寸。
   ★-1% 还带一点【咬进去】:精确相切(内沿 = 盘半径)在 3 倍屏上落到半个设备像素上,
   抗锯齿会把切点摊成一条发丝缝(owner 2026-08-09 实拍)。实测内沿 29.37(咬进 0.63px,
   看不出盖住)、外沿 31.81、圆心 (30,30) —— 任何取整都不留缝。 */
.studio-org-work {
  position: absolute; pointer-events: none;
  top: var(--work-inset, -2px); left: var(--work-inset, -2px);
  width: calc(100% - 2 * var(--work-inset, -2px));
  height: calc(100% - 2 * var(--work-inset, -2px));
  display: none; overflow: visible;

}
/* 呼吸的绿光:一块与盘同形的色斑垫在【盘底下】(z-index:-1 → 只有糊出盘外的那圈看得见),
   靠 opacity 一呼一吸。颜色走 --color-live(全站"活着"唯一绿);
   ★幅度 0.3→1:上一版 0.5→0.85 被 owner 判"呼吸感不明显"—— 看不出在动的呼吸等于没做。
   ★半径不抄本地手那盏灯的 px 值 —— 那是给 20px 图标定的(≈图标的 15%),
   照搬到 80px 头像上等于没有。这里取同一个【比例】:盘径的 ~12%。
   幅度必须小(0.5→0.85):真灯不会跳,它只是"活着"(同 studio-bench-breathe 那条的分寸)。 */
/* ★光在头像【上面】一层(owner 2026-08-09)。原先垫在底下(z-index:-1),亮的部分被头像挡住,
   只有外溢的尾巴看得见 —— 那就是"边缘看着暗"的原因。
   ★压在上面必须用滤色混合:直接盖一块半透明绿是【一层膜】,会把头像压灰;screen 只加不减,
   读起来才是"光打在它身上"。inset 归 0,让亮部正好落在盘沿而不是缩在里面。 */
/* ★两层各做一件事,不许合成一层:mix-blend-mode 与 filter:blur 落在【同一个元素】上时,
   Chrome 会把透明区合成成黑的(实测截图:整张脸中心发黑)。所以
   ::before = 压在头像【上面】的贴边光(滤色混合,靠渐变自己柔和,不带 blur);
   ::after  = 垫在头像【下面】的外溢晕(带 blur,只有溢出盘外的那圈看得见)。 */
.studio-org-agent-circle.is-working::before {
  content: ""; position: absolute; border-radius: 50%; corner-shape: round; z-index: 1; pointer-events: none;
  mix-blend-mode: screen;
  inset: var(--glow-inset, 0px);
  /* 中心透明:压在上面的是边缘光,不是色盘 —— 实心色盘 + screen 会把整张脸吃成绿饼(实测) */
  background: radial-gradient(closest-side, transparent var(--glow-core, 70%), var(--glow-color, var(--color-live)) 100%);
  animation: duoLiveBreathe var(--glow-cycle, 1.2s) ease-in-out infinite;
}
.studio-org-agent-circle.is-working::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; corner-shape: round; z-index: -1; pointer-events: none;
  background: var(--glow-color, var(--color-live));
  filter: blur(var(--glow-min, 3px));
  animation: duoLiveBreathe var(--glow-cycle, 1.2s) ease-in-out infinite;
}
/* 外圈也跟着呼吸(owner 2026-08-08:10↔12px),不只是明暗 —— 光在"胀",不是在闪 */
/* 正在停:光从"活着"的绿换成"要你动手"的红,圈继续把这一圈画完(JS 在 animationiteration
   那一刻才熄)。只换颜色不换画法 —— 两个状态共用同一套光,颜色各自喝自己的真源。 */
.studio-org-agent-circle.is-stopping { --glow-color: var(--color-danger); }
@keyframes duoLiveBreathe {
  0%, 100% { opacity: var(--glow-op-min, 0.7); filter: blur(var(--glow-min, 3px)); }
  50%      { opacity: var(--glow-op-max, 1);   filter: blur(var(--glow-max, 6px)); }
}
.studio-org-agent-circle.is-working .studio-org-work { display: block; }
.studio-org-work path {
  fill: none;
  /* ★线是【白】的,绿只在光里(owner 2026-08-08 点名)。用 --color-text 这个随主题反色的 token:
     暗色下就是白线;亮色下自动变深 —— 纯白压在白页上等于没有。 */
  stroke: var(--work-line-color, var(--color-text)); stroke-opacity: var(--work-line-op, 0.7);
  /* ★别加 vector-effect: non-scaling-stroke —— 它把虚线也拉回设备空间算,pathLength 的
     归一化当场失效(实测:周长≈276px 而 dash=100px,绕 2.7 圈 → 永远看着是满圈)。
     所以粗细用【用户单位】:盒子 88px / 100 单位 → 3.4 ≈ 3px;换到小一号的头像自动细一档,
     这正是想要的(80px 圆和 48px 圆不该配同样粗的线)。 */
  /* 平头端点(owner 2026-08-08):圆头让起止看着像两颗药丸,直边才是"画到这儿了" */
  stroke-linecap: butt;   /* 线宽由 syncWorkRings 按 --work-line-px 现算(见那里的注释) */
}

.studio-org-work .arc {
  stroke-dasharray: 100;
  animation: duoWorkDraw var(--work-cycle, 10s) linear infinite;   /* 一圈 10s(owner 2026-08-08) */
}
@keyframes duoWorkDraw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
/* 手机端按 owner 2026-08-09 给的数:直径比头像小 1.6px → 半径 29.2px = 48.667 个 viewBox 单位
   (盒子 60 → 1 单位 = 0.6px)。盒子与描边【不跟着变】(半径已与盒子解耦,见 buildWorkRing),
   所以内沿 = 29.2 - 1.2 = 28.00,正好落在头像图的边上、缝归零;起点同步下移 0.8。
   桌面维持 50(圈在元素边缘):那边的缝只有 0.4px,不能共用手机这个数。 */
/* 桌面(头像 80,1 单位 = 0.8px):49.5 → 半径 39.6、内沿 38.00 正好落在图沿(图半径 38)、
   起点下移 0.4、描边仍 3.2、圆心 (40,40)。盒子不动。 */
:root { --work-r-px: 39.6; --work-line-px: 3.2; }   /* 桌面 80:半径 39.6、线 3.2 → 内沿 38.0 = 图沿 */
@media (max-width: 768px), (max-height: 500px) { :root { --work-r-px: 29.2; --work-line-px: 2.4; --glow-min: 2px; --glow-max: 4px; } }   /* 手机 60:内沿 28.0 = 图沿;晕收小到溢出约 8px,配下面那 10px 余量 */
/* 折叠成 60px 竖条时头像是 48(1 单位 = 0.48px):47.4167 → 半径 22.76(直径比原来小 2)、
   起点下移 1、描边仍 1.92、圆心 (24,24)。盒子不动。 */
.studio-org-chart.studio-org-folded { --work-r-px: 23; --work-line-px: 2; }   /* 折叠 48:线 2px(owner) */
@media (prefers-reduced-motion: reduce) {
  /* 不放弃这个状态,只是不动:满圈静止 + 光常亮(同 studio-bench-breathe 那条的处理:
     去掉会动的那半,不去掉意思) */
  .studio-org-work .arc { animation: none; stroke-dashoffset: 0; }
  .studio-org-agent-circle.is-working::before,
  .studio-org-agent-circle.is-working::after { animation: none; opacity: 0.7; }
}
/* 岗位名可点击:点它切换整排"参与/不参与";不参与=整排头像变暗(照 sidebar 未在岗那套 opacity:0.4) */
.studio-org-row-label-text { cursor: pointer; transition: opacity 0.15s; }
 html:not([data-input="touch"]) .studio-org-row-label-text:hover{ opacity: 0.6; } 
.studio-org-row-label-text:active { opacity: 0.6; }
.studio-org-row.row-inactive .studio-org-agent { opacity: var(--dim); }
.studio-org-row.row-inactive .studio-org-row-label-text { opacity: var(--dim); }   /* 岗位名也淡一档,示意整排歇工 */
/* 绑定到本行(角色)的模板 = 岗位名下方一排文件类型彩色小图标(缩小版模板卡图标)。拖模板到某行 → 立刻在该行出现。点图标=打开编辑器(改名/解绑/删)。 */
.studio-org-row-templates { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.studio-org-tpl-chip {
  /* ★27px 是解出来的,不是拍的:要让旁边那个"+"三项占比都与主聊天基准一致(笔画 4.2% / 外沿 36.6% /
     图标占按钮 55.6%),且图标奇数、两侧留白整数、渲染笔画≥1px —— 21~33 之间唯一解就是 27。
     chip 与"+"同宽高才能同排居中。圆角 8px = 站内标准 14/48(29.2%)按 27 换算。 */
  width: 20px; height: 20px; border-radius: calc(6px * var(--corner-k));
  display: flex; align-items: center; justify-content: center;
  background: var(--color-bg-card); color: var(--color-text);
  border: 1px solid var(--color-border); box-sizing: border-box; overflow: hidden; cursor: pointer;
}
.studio-org-tpl-chip.has-filetype { border: none; color: #fff; }   /* 文件类型彩色底 + 白图标(同侧栏模板卡 has-filetype) */
.studio-org-tpl-chip svg { width: var(--icon-size-sm); height: var(--icon-size-sm); }
 /* ★这里【不】显示模板就绪状态(2026-08-01 撤掉,别再加回来)。
   20px 的 chip 承载不了一个一眼读懂的状态:颜色会被文件类型底色干掉(图标底色由类型定,
   PDF 红/表格绿,任何状态色都会跟某个类型撞),形状又跟满幅图标糊在一起。
   外环/内描边/伪元素边框/加隔离环四种都试过,没有一种读得清。
   而这个信息在【模板卡】上已经很清楚(右上角红黄绿点 + hover 说明)—— 在这儿再放一个
   更弱的版本是加噪音,不是加理解。 */
 html:not([data-input="touch"]) .studio-org-tpl-chip:hover{ opacity: 0.8; } 
.studio-org-tpl-chip:active { opacity: 0.8; }
/* 从桌面拖文件进侧栏:整段亮起 = "松手会落在这一段"。分段本身就是答案(拖到 Templates 就是模板,
   拖到 Portfolio 就是作品),所以高亮必须是【整段】,不是某一张卡。
   蒙层复用 --studio-drop-tint(拖品牌卡/拖 agent 同一个),不为这里另造一种绿。
   不收时(未登录 / 没开系列)只给虚线轮廓、不给蒙层 —— 一眼看出"这里不接收",而不是看着能放、松手却没反应。 */
/* 作品卡拖到【别的类别文件夹】= 改产出类型。整个文件夹亮起(意图是"归到这一类"),
   区别于拖到同类卡片上的 merge-target(意图是"和它叠在一起")。蒙层同源不另造颜色。 */
.studio-pf-folder.kind-target { position: relative; }
.studio-pf-folder.kind-target::after {
  content: ''; position: absolute; inset: 0; border-radius: calc(12px * var(--corner-k));
  background: var(--studio-drop-tint); pointer-events: none; z-index: 5;
}
.sidebar-section.is-file-drop::after {
  content: ''; position: absolute; inset: 0; border-radius: calc(12px * var(--corner-k));
  background: var(--studio-drop-tint); pointer-events: none; z-index: 5;
}
.sidebar-section.is-file-drop-blocked::after {
  content: ''; position: absolute; inset: 0; border-radius: calc(12px * var(--corner-k));
  border: 1px dashed var(--color-border); pointer-events: none; z-index: 5;
}
.sidebar-section.is-file-drop, .sidebar-section.is-file-drop-blocked { position: relative; }
/* agent 拖到某行(5等分 band)→ 去色中性蒙层(--studio-drop-tint,不带金色品牌属性;随白天/夜间) */
/* 左右延伸 -24px 抵消 org-scroll 的 0 24px padding → 覆盖整列满宽(scroll overflow:hidden 裁到列边),不留左右间隙 */
.studio-org-row.agent-drop-hover::after { content: ''; position: absolute; top: 0; bottom: 0; left: -24px; right: -24px; background: var(--studio-drop-tint); pointer-events: none; z-index: 5; }
/* 手机长按 agent 会误触发文字选择(iOS 还弹 Copy/Find Selection/Look Up,选中高亮盖在圆上像个黑框)
   → 架构区整体禁用文字选择与长按菜单(指针拖拽长按 350ms 进入,期间不能冒系统 UI)。 */
.studio-org-scroll,
.studio-org-scroll * {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  /* iOS 长按时 WebKit 会在被触元素周围画一块深色 tap 高亮矩形,长按拖拽期间不能出现 → 关掉 */
  -webkit-tap-highlight-color: transparent;
}
/* 左右拖动时的落点竖线:位置由 showDropLine 按与 dropIndexInRow 相同的规则算 → 线在哪就落在哪 */
.studio-org-agents { position: relative; }
/* 落点竖线已废弃 → 改用"两侧让位开口"效果(showOrgGap),不再需要竖线 */
.studio-org-agent.org-dragging { opacity: var(--dim); }   /* 拖起的圆圈变淡(同 grid);其余圆圈两侧让位开口 */
/* 点击式加成员"+"= 岗位名列里的小圆按钮(不占头像位)。★仅手机显示(桌面直接拖);默认 display:none,手机 media 里开 */
.studio-org-add {
  display: none;
  /* ★圆环画在 svg 里(见 icon-plus-circle.liquid):按钮自己不再有 border/border-radius ——
     CSS 边框会被吸附到整设备像素而 SVG 内容不会,两者分开画必然错开(实测 iPhone dpr=3)。 */
  width: 20px; height: 20px; padding: 0; border: none; background: transparent;
  color: var(--color-text); opacity: 0.55; box-sizing: border-box;
  position: relative;
  align-items: center; justify-content: center;
  cursor: pointer; flex: 0 0 auto;
}
/* ★圆环与十字【都用 CSS 盒画,不用 icon-plus-circle 那个 svg】——理由只有一个:
   紧挨着它的模板 chip 的墨迹是 CSS 盒画的,而五个岗位行是把容器高度平分的
   (实测 694/5 = 138.8),所以每行起点落在不同的亚像素相位(.0/.8/.6/.4/.2)。
   iOS 上【CSS 盒】与【SVG 视口】在同一个小数位置会被吸附到不同的设备像素 →
   加号比方块高约 1 个设备像素(owner 截图量出 0.06" vs 0.10",WebKit 自报的
   circle bbox 上1.5/下2.0 与之吻合;Chrome 六相位全 0 差,所以电脑上永远量不到)。
   两者同为 CSS 盒后,同一个 top 只会有一种吸附,任何相位都同心。
   几何照抄原 svg:环外沿 18px、描边 1px;十字 7.5px 长 1px 粗(= 原 line 8.11~15.89
   单位加 square 端帽后的 7.48px)。Chrome 六相位逐行逐列比对 = 完全一致。
   (snippet 本身不动:3D 查看器还在用,那里没有相邻 CSS 盒要对齐。) */
/* ★墨迹挂在这个 span 上、【不挂 button 自己的伪元素】:实测 iPhone 上那一版整颗加号不显示
   (CSS 三条规则线上都在、JS 照常建按钮、Chrome 画得出)——WebKit 对原生控件的生成内容有
   自己的脾气,不赌它。span 是本站已在这台设备上验证过的构造(头像绿光就是 div::before/::after)。
   环外沿 18px 由按钮的 flex 居中放进 20px 里(各让 1px,整数);十字 7.5×1 画在 span::before,
   inset 4.25 = (16 - 7.5)/2,16 是 span 去掉 1px 边框后的内容盒。 */
.studio-org-add-mark {
  width: 18px; height: 18px; box-sizing: border-box; flex: 0 0 auto; position: relative;
  border: 1px solid currentColor; border-radius: 50%;
  corner-shape: round;
}
.studio-org-add-mark::before {
  content: ''; position: absolute; inset: 4px;   /* cross 8x8 in the 16 content box; bars are 2px because 16 is EVEN - a 1px bar can only straddle the half pixel there (painted blurred and off-centre, measured) */
  background: linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat,
              linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat;
}
/* ★复用主聊天加号的【视觉重量】,不只是同一个 svg 文件:
   主聊天 = 36px 按钮 + 20px 图标 → 渲染出的笔画 1.8 × 20/24 = 1.5px。
   这里按钮只有 21px,若图标同样用 1.8 的笔画,渲染出来只有 1.8 × 13/24 ≈ 0.98px ——
   细到亚像素,十字交叉处被抗锯齿冲淡,看着像"中间是透明的"(用户 2026-07-26)。
   所以按同一渲染粗细反推:1.5 × 24/13 ≈ 2.8。图标 13px(奇数)落在 21px(奇数)按钮里,
   两侧各 4px 整数偏移 → 加号正落圆心。 */
/* ★27px 按钮 + 15px 图标 → 笔画/外沿/图标占比三项全部等于主聊天基准,
   而且反推出的 stroke-width 正好是图标原始的 1.8 ——【不需要任何覆盖】,
   这才是真正"直接从主聊天输入框那个加号拿来的"。
   上一版在 21px 上只对上了外沿占比,笔画占比却是基准的 1.68 倍 → 又粗又挤(用户 2026-07-26)。
   21px 装不下这个字形:按比例笔画只有 0.88px,亚像素会发虚 —— 所以必须改尺寸,不是调数值。 */
/* ★十字中心定在【上下左右各 10px 的那一点】、描边正好 1px(用户 2026-07-27 定):
   按钮 21px + border 1px → 内容盒 19px 起于 x=1;svg 11px 居中 → 左缘 5px;
   图标 viewBox 中线 x=12 映射到 5 + 12/24×11 = 10.5px —— 正是中心像素的中线,左右各 10.5。
   stroke-width 24/11 = 2.182 → 渲染笔画 = 2.182×11/24 = 1.00px,压在半像素中线上正好铺满一个像素、不糊。
   (别改 svg 尺寸就以为能保持:换成 13px 要配 1.846 才仍是 1px —— 两个数是绑死的 24/S。) */
/* ★overflow:visible 是 r=11.4 的前提:圆环外缘正好压在 viewBox 边界上,SVG 默认按视口裁切,
   亚像素一舍描边外半边就没了(icon-plus-circle 注释里记着的实测:"圆形缺左上两边")。
   放开裁切后整条描边都画得出,而墨迹恰好 20px = 按钮盒,不会溢出到别处。 */
 html:not([data-input="touch"]) .studio-org-add:hover{ opacity: 1; } 
.studio-org-add:active { opacity: 1; }
/* 入口A 选 agent sheet:一行 = 头像 + 名字(复用全站头像色/圆角规范) */
.studio-picker-list { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.studio-picker-item {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 8px 10px; border-radius: calc(12px * var(--corner-k)); border: none; background: transparent;
  color: var(--color-text); cursor: pointer; text-align: left; font-family: inherit;
}
 html:not([data-input="touch"]) .studio-picker-item:hover{ background: var(--color-bg-hover); } 
.studio-picker-item:active { background: var(--color-bg-hover); }
.studio-picker-icon {
  width: 40px; height: 40px; border-radius: 50%; corner-shape: round; flex: 0 0 auto; overflow: hidden;
  background: var(--avatar-bg); color: var(--avatar-fg);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 500; letter-spacing: 0.5px;
}
.studio-picker-icon img { width: 100%; height: 100%; object-fit: cover; display: block; }
.studio-picker-name { font-size: 14px; }
.studio-picker-empty { font-size: 13px; color: var(--color-text-secondary); padding: 16px 6px; text-align: center; }
/* 入口B 岗位选择器(agent 编辑器内):胶囊 chip,选中=反色实底 */

/* 可拖间隙（无可见分割条；hover 露淡线提示可拖） */
.studio-splitter { flex: 0 0 var(--duo-window-gap); cursor: col-resize; background: transparent; position: relative; }
.studio-splitter::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 2px; height: 36px; transform: translate(-50%, -50%);
  border-radius: 1px; background: transparent; transition: background 0.15s;
}
html:not([data-input="touch"]) .studio-splitter:hover::after,
html:not([data-input="touch"]) .studio-splitter:active::after{ background: var(--color-border); }


/* 栏3：会议室（样式=主聊天） */
.studio-meeting { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.studio-meeting-header {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 10px 14px; flex-shrink: 0; border-bottom: 1px solid var(--color-border);
  height: calc(var(--duo-header-h) - var(--duo-window-gap)); box-sizing: border-box;   /* = sidebar header 减去缝隙 → 分割线齐平 */
}
/* 右上角排布 = 共享项目页 header:头像组 + Share + "…"(复用 .project-collaborators/.project-avatar-group/.project-header-share-btn) */
.studio-meeting-header .project-collaborators { display: flex; align-items: center; gap: 8px; }
.studio-meeting-header-actions { display: flex; align-items: center; gap: 4px; }
/* 展开态:横向 ⋯ 右移 3px → 与折叠态居中位置(cx)对齐,切换不跳位(实测展开 cx1609 vs 折叠 1612;折叠态 ⋯ 靠 align-items:center 已居中,不加此偏移) */
.studio-meeting:not(.studio-meeting-folded) .studio-meeting-header-actions { margin-right: -3px; }
.studio-meeting-close-mobile { display: none; }   /* 桌面无关闭(去掉开关按钮);仅手机 sheet 用 */
/* 会议室消息区 = 复用主聊天 .chat-messages(气泡样式);此处只补会议室内的填充布局 */
.studio-meeting .chat-messages { flex: 1; min-height: 0; overflow-y: auto; }
/* composer 背景交给会议室窗口(下方 .dark-mode .studio-meeting 统一到主聊天色),自身透明继承 → 无接缝 */
.studio-meeting-composer.composer-bar { flex-shrink: 0; }

/* ── 拖动最小宽:两栏永远 ≥最小宽(内容不被挤压变形)或折叠,没有畸形中间态 ── */
.studio-org-chart { min-width: 420px; }
.studio-meeting { min-width: 340px; }

/* 方案A 连续收合:折叠态宽度由 JS 的 flexBasis 连续驱动(不固定 60px、不用 flex:1 抢占;分隔线永远贴光标) */

/* 会议室折叠态 = 头像竖排(宽度跟手,松手吸附 60);min-width 放到 60 让它能连续收窄、藏聊天泡泡/输入框 */
.studio-meeting.studio-meeting-folded { min-width: 60px; }
.studio-meeting.studio-meeting-folded .chat-messages,
.studio-meeting.studio-meeting-folded .studio-meeting-composer { display: none; }
.studio-meeting.studio-meeting-folded .studio-meeting-header {
  flex-direction: column; align-items: center; justify-content: flex-start;
  gap: 10px; padding: 10px 6px 14px; border-bottom: none;   /* padding-top 14→10:折叠 ⋯ 顶距对齐展开态(展开 ⋯ 居中56px header≈顶距9.5) */
}
.studio-meeting.studio-meeting-folded .project-collaborators { flex-direction: column; align-items: center; gap: 6px; }
/* 折叠头像组水平居中:实测整个内容列比 60px 轨道中心偏左 2px(轨道 border/亚像素,结构消不掉)→ 精确右移 2px 校正 */
.studio-meeting.studio-meeting-folded .project-avatar-group { flex-direction: column; align-items: center; transform: translateX(2px); }
/* 折叠竖条:头像居中 + 垂直盖(把展开时的横向 -6px 重叠换成竖向,一个盖一个) */
.studio-meeting.studio-meeting-folded .project-avatar-group .project-avatar { margin-left: 0; margin-top: -6px; }
.studio-meeting.studio-meeting-folded .project-avatar-group .project-avatar:first-child { margin-top: 0; }
/* 会议室成员头像带图:铺满圆内、盖边(仅会议成员组,不动其它 .project-avatar) */
/* has-avatar 的图片同心规则已升进 .project-avatar 基准(ai-chat-share-modal.css),这里不再各修一份 */
/* "+N" 溢出圆:不透明头像标准底(半透明会透出下层头像=盖不住,见叠放机制);字号小一档 */
#studioMeetingMembers .studio-meeting-overflow { background: var(--avatar-bg); color: var(--avatar-fg); font-size: 10px; }
/* 会议室成员/邀请面板(复用共享弹窗):成员头像带图 + 禁用的"即将上线"邀请输入 */
.studio-meeting-share-modal .share-member-avatar.has-avatar { overflow: hidden; }
.studio-meeting-share-modal .share-member-avatar.has-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.studio-meeting-share-modal .share-email-input:disabled { opacity: 0.55; cursor: default; }
.studio-meeting.studio-meeting-folded .studio-meeting-share { display: none; }
.studio-meeting.studio-meeting-folded .studio-meeting-header-actions { flex-direction: column; align-items: center; order: -1; }  /* 折叠时三点排到头像上方 */

/* 架构图折叠态 = 60px 竖条:岗位圆圈竖排(复用同一批 .studio-org-agent-circle),点一下展开 */
.studio-org-chart.studio-org-folded { min-width: 60px; cursor: pointer; }
.studio-org-chart.studio-org-folded .studio-org-scroll { padding: 14px 6px; overflow: hidden; }
.studio-org-chart.studio-org-folded .studio-org-links,
.studio-org-chart.studio-org-folded .studio-org-row-label { display: none; }
.studio-org-chart.studio-org-folded .studio-org-row {
  flex: 0 0 auto;   /* 折叠竖条:行按内容自然高,不被 5 等分拉伸 */
  flex-direction: column; align-items: center; gap: 10px; margin-bottom: 10px;
}
.studio-org-chart.studio-org-folded .studio-org-agents { flex-direction: column; gap: 10px; }
/* 折叠态头像【要能点】:它是在干活的开关(owner 2026-08-09)。原先这里 pointer-events:none
   把点击直接漏给整条去展开 —— 那才是点头像会展开的产生源,不是脚本没拦住。 */
/* 折叠竖条:头像直径 48px(同 sidebar .studio-agent-icon),干净落进 60px 竖条不被裁 */
.studio-org-chart.studio-org-folded .studio-org-agent-circle { width: 48px; height: 48px; font-size: 13px; }
/* 折叠竖条:品牌胶囊 → 居中正圆(直径=胶囊高即圆弧直径),只留品牌色不显名 */
.studio-org-chart.studio-org-folded .studio-org-header { justify-content: center; padding: 6px; }
/* 折叠竖条:连接状态那盏灯挪到竖条【最下面】。窄条里顶部要留给品牌圆点,而这盏灯是
   "这台机器还在不在"的常驻信号,放底部既不跟品牌抢那一格,也不会被竖排的头像挤走。
   ★用绝对定位而不是改 DOM:它在展开态属于表头(与品牌名同一行),换个位置不该换个爹。 */
.studio-org-chart.studio-org-folded { position: relative; }
.studio-org-chart.studio-org-folded .studio-bench-btn {
  position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%);
  margin: 0;                     /* 展开态那 -14px 右外边距是给表头右缘对齐用的,这里必须清掉 */
  /* ★z-index 不是保险丝,是这里必须声明的层序:它所在的 header 是 static,而下面的滚动区是
     relative —— 后者天然压在它上面。实测(elementFromPoint)按钮中心收到的是 #studioOrgScroll,
     所以 hover 不亮、点击也进不去。抬一层它才是自己那块地的主人。 */
  z-index: 1;
}
/* 头像竖排不许跑到那盏灯底下 —— 折叠条 overflow:hidden,不留位置就是直接压上去 */
.studio-org-chart.studio-org-folded .studio-org-scroll { padding-bottom: 44px; }
.studio-org-chart.studio-org-folded .studio-org-brand-name.is-clickable {
  width: 24px; height: 24px; padding: 0; border-radius: 50%;
  corner-shape: round;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0; overflow: hidden; flex: 0 0 auto;
}

/* ── 手机 sheet 的钉死标题栏(S.sheet 在手机上组装):内容盒自己滚,真源那条 absolute 会跟着滚走 → 这里 sticky。
   负边距 = 内容盒 24px 内距,条才贴壳顶满宽;底色 inherit = 和内容盒同一个值(亮/暗各自的),不再写第二份色。── */
@media (max-width: 768px), (max-height: 500px) {
  /* 钉死/遮罩全在真源 .duo-sheet-head;这里只补:内容盒 24px 内距的负边距(项目设置手机态内距是 0 所以不需要)+ 关闭钮坐标 */
  /* sticky 头出不了父级 content box → 内容盒 padding 0,内距给 body(同项目设置手机态);body 顶距 20 = 项目设置给头下第一行留的那个值(让开 20px 渐变) */
  .project-settings-modal-content.has-sheet-head { padding: 0; }
  .studio-sheet-body { padding: 20px 24px 24px; }
  /* 卡片 sheet(project-settings-cards):卡片/标签自带 16/20 的横向边距(项目设置真源),body 不再加横向内距 */
  .project-settings-cards .studio-sheet-body { padding: 0 0 24px; }
  /* The markup dialog rides the cards sheet but its content is not cards (image stage + note rows carry
     no own side margins) - so this one body keeps side padding (owner 2026-08-27: content was glued to the edges) */
  .studio-markup-modal .studio-sheet-body { padding: 20px 16px 24px; }   /* top 20 = clear the sheet-head gradient, same as the base body */
  /* The cards-mode actions padding assumes a zero-padding body; this body pads 16, so only the vertical
     part survives (the grid spans the same rail as the picture and the cards). */
  .studio-markup-modal .project-modal-actions { padding: 12px 0 32px; }
  /* ...and the picture itself bleeds to the sheet edges - the image gets the full width, the text keeps its inset */
  /* The phone sheet drops the how-to line: it taxed the small screen and the picture wants the room
     (owner 2026-08-27). Keyed off the sheet body = the real mobile form, not a viewport guess. */
  /* The picture runs exactly as wide as the grey cards (same 16px inset, width-first: a tall image grows
     down and the sheet scrolls). The cards-mode side margin would double the addrow inset and zero its top
     gap - the row sits at the body inset with its own 12px gap (owner 2026-08-27). */
  .studio-markup-modal .studio-sheet-body .studio-markup-figure { width: 100%; }
  .studio-markup-modal .studio-sheet-body .studio-markup-img { width: 100%; max-height: none; }
  /* 头下第一样东西让开 20px 渐变(项目设置真源:mobile-header + label = 20);子 sheet 第一样是行卡,没有这条就被遮罩压住一截 */
  .project-settings-cards .studio-sheet-body > :first-child { margin-top: 20px; }
}
/* 桌面壳形契约(S.sheet 在桌面组装,手机那条是 has-sheet-head):壳封顶 90vh 但自己不滚,标题 / body / 按钮行
   是三个 flex 子项,只有 body 滚 —— 和分享弹窗(header + body + footer)同一个形。滚动条轨道因此起于标题下、
   止于按钮上,两头都在圆角之外;壳自己滚的话轨道从角到角(手机 sheet 由真源定 92dvh,不受这些影响)。
   内距从壳搬到三段:标题 24/52(28 + 壳的 24)/0/24,body 横向 24,按钮行 24。body 恒占 8px 滚动条位、
   右内距对应减 8 → 内容右缘无论滚不滚都停在 24,和按钮行、标题一条竖线。 */
.project-settings-modal-content.has-modal-body { max-height: 90vh; display: flex; flex-direction: column; padding: 0 0 24px; }
.project-settings-modal-content.has-modal-body > .project-settings-title { padding: 24px 52px 0 24px; }
.project-settings-modal-content.has-modal-body > .studio-modal-body { flex: 1; min-height: 0; overflow-y: auto; scrollbar-gutter: stable; padding: 0 16px 0 24px; }
.project-settings-modal-content.has-modal-body > .project-modal-actions { padding: 0 24px; }
@media (max-width: 768px), (max-height: 500px) {
  /* 标题带着桌面弹窗的 padding-right:28 / margin-bottom:20 进条 → 居中点左偏、文字顶在关闭钮上方;条里归零,关闭钮是流内 flex 子项(真源三段式),不再 absolute */
  .studio-sheet-bar .project-settings-title { margin: 0; padding: 0; }
  .studio-sheet-bar .project-modal-close { position: static; flex-shrink: 0; }
  /* 左格坐进切换器后比右格的 36px 关闭钮宽,标题(flex:1 吃剩余)就偏右 —— 换成三栏网格,两侧等宽、标题落正中 */
  .duo-sheet-head:has(> .studio-training-nav) { display: grid; grid-template-columns: 1fr auto 1fr; }
  .duo-sheet-head:has(> .studio-training-nav) > .duo-sheet-close { justify-self: end; }
}

/* ── 无 collection 欢迎页 ── */
.studio-welcome {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-bg-page); z-index: 3;
}
.studio-welcome[hidden] { display: none; }
.studio-welcome-inner { text-align: center; max-width: 480px; padding: 24px; }   /* 标题改用 .h1(Fraunces 500,字号大)→ 放宽避免换行 */
/* 主标题已改用主聊天欢迎页同款 .prose > .h1(Fraunces 500,全局 h1/.h1 规则供给);原 .studio-welcome-title 已无使用者,删 */
/* 标题颜色必须显式接管:.prose 的色来自 theme.css 的 --text-color(Prestige 自己那套 token),
   而 DuoHand 夜间模式改的是 --color-text —— 两套不通,不接管则暗色下标题不跟着变。
   用 --color-text 后亮/暗自动适配,无需再写 .dark-mode 覆盖。欢迎页与 Coming soon 共用 .studio-welcome,一条管两处。 */
/* 结构与主聊天欢迎页同形(.prose > .h1 + div > p),标题/副标题间距照 #initial-message 的 6px */
.studio-welcome .prose { margin: 0 0 18px; color: var(--color-text); }
.studio-welcome .prose .h1 { color: var(--color-text); }
.studio-welcome .prose > .h1 + div { margin-top: 6px; }

/* ── 移动端会议室 peek 提示条（桌面隐藏） ── */
.studio-meeting-peek { display: none; }

/* ── 移动端：架构图铺满 + 会议室底部上拉 sheet（复用 5.2 规范） ── */
@media (max-width: 768px), (max-height: 500px) {
  /* 汉堡默认 top:10(中心30,为主聊天 60px header 居中);studio header 中心=窗口顶 gap(4)+header(60-4=56)/2=32
     → studio 页汉堡下移 2px(top:12)与之居中。只在 studio-active 时改,主聊天不受影响。 */
  .chat-sidebar.studio-active ~ .chat-main .mobile-menu-trigger { top: 12px; }
  /* 手机端不再写死 padding:原来写 6px 绕过了 --duo-window-gap,而 header 高度仍按 token 推导 → 分割线对不齐。
     现在统一走 token(桌面已收到 4px,比原手机值还紧),需要手机单独调时改成覆盖 --duo-window-gap 而不是 padding。 */
  /* 手机端:左右上留缝,【下边不留】→ 窗口直抵屏幕底;窗口只保留上圆角、去掉下边框(与无痕模式同一处理) */
  .studio-view-page { padding: var(--duo-window-gap) var(--duo-window-gap) 0; }
  .studio-org-chart { border-radius: var(--studio-window-radius) var(--studio-window-radius) 0 0; border-bottom: none; }
  /* 会议室手机端是上拉 sheet:整条边线去掉(border:none)。品牌色已不上窗口边框(改 header 胶囊),这里纯为 sheet 无边观感 */
  /* ★ ai-chat-studio.css 比 ai-chat-sheet.css 后加载,而两条选择器特异性相同(0,1,0)
     → .studio-meeting 的 18px 会盖掉 .duo-sheet 的"上圆角+下直角",下面两角就还是圆的。
     这里显式让位:引用 sheet 的圆角 token(不复制数字,仍是同一个真源)。 */
  .studio-meeting {
    border: none;
    border-radius: var(--duo-sheet-radius) var(--duo-sheet-radius) 0 0;
  }
  .studio-org-agent-circle { width: 60px; height: 60px; font-size: 14px; }   /* 手机端架构圆圈直径 60 */
  .studio-org-add { display: inline-flex; }   /* "+" 仅手机显示(桌面隐藏),跟在岗位名后面的小圆按钮 */
  /* ── 手机端组织架构:每行【上=岗位名(居中小标题)+下=头像(满宽居中)】,整棵树左右对称、总监落页面正中 ──
     竖向仍固定5行band、行内容竖直居中;某岗位人多就本行头像区横滑(不换行→不打架,见 CLAUDE 第0号铁律)。 */
  /* 竖向 5px 与行内那 5px 同理:它也是裁切盒,最后一行的光会顶在它的下边上(实测 bottom=0) */
  .studio-org-scroll { padding: 10px 12px; }   /* 溢出行为继承基础规则的 x:hidden / y:auto —— 横屏装不下 5 行时靠它滚 */
  .studio-org-row {
    flex-direction: column; align-items: center; justify-content: center; gap: 6px;   /* 名字在上、头像在下,整体页面居中 */
    /* ★行高不许被容器压扁:flex:1 在矮容器里会掉到内容高(实测 110),整棵树看着被压扁一档。
       钉住竖屏那档(实测 138.8),装不下就交给 .studio-org-scroll 竖滚 —— 横竖屏的节奏一致。 */
    min-height: 138px;
  }
  .studio-org-row-label {
    position: static; transform: none; align-self: auto;
    width: auto; flex: none; padding: 0;
    display: flex; flex-direction: row; align-items: center; gap: 6px;   /* 岗位名 + 跟随的小"+",作为居中小标题 */
  }
  .studio-org-row-label-text { font-size: 11px; line-height: 1.2; }
  /* 手机端:模板图标不再另起一行(桌面是名字下方),而是排进"岗位名 · 模板 · +"这条居中横行、与"+"同排竖直居中 */
  .studio-org-row-templates { margin-top: 0; }
  .studio-org-agents {
    width: 100%; align-self: stretch; min-width: 0; flex-wrap: nowrap;
    overflow-x: auto; overflow-y: hidden; justify-content: safe center;
    /* ★竖向 padding 不是留白,是【不让圈和光被裁】:横滑要 overflow-x:auto,另一轴只能是
       hidden/auto —— 于是这个盒子四边都裁,而它的上下边【正好压在头像圆的上下边上】
       (实测 clip.top/bottom === circle.top/bottom)→ 绿光被切成两条横线、圆环上下变细
       看着像"圆偏了"(owner 2026-08-08 手机实拍)。负 margin 抵掉,行高不变。 */
    gap: 16px; padding: 10px 4px; margin: -10px 0; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;                              /* 横滑无滚动条(Firefox) */
  }
  .studio-org-agents::-webkit-scrollbar { display: none; }   /* 横滑无滚动条(iOS/Chrome) */
  .studio-org-row.agent-drop-hover::after { left: 0; right: 0; }
  /* 无品牌提示:手机只显"No brand"(隐藏完整引导句)+ 左移让开固定汉堡菜单(left:12 宽40 → 右缘52,+缝隙) */
  .studio-org-brand-name .brand-hint-full { display: none; }
  .studio-org-brand-name .brand-hint-short { display: inline; }
  .studio-org-header { padding-left: 58px; }
  .studio-meeting-share { display: none; }              /* 手机去掉 Share(分享走手机版共享) */
  .studio-meeting-close-mobile { display: inline-flex; } /* 手机 sheet:最右关闭 X */
  /* 移动端 sidebar = 复用现有 chat-sidebar 抽屉(汉堡菜单 #mobileOpenSidebarBtn 打开,在 header 外不受隐藏影响),此处不自建 */
  .studio-main { flex-direction: column; }
  /* 那两条 min-width 是【给桌面分割条用的】(两栏拖动时不许被挤变形),而手机上分割条 display:none、
     根本没有拖动这回事 —— 约束必须跟着一起走。留着的话 420px 宽过绝大多数 iPhone(SE 375 / 标准 390),
     工作台就比屏幕宽。 */
  .studio-org-chart { flex: 1; min-width: 0; }
  .studio-meeting { min-width: 0; }
  .studio-splitter { display: none; }

  /* 移动端会议室 sheet 由 .duo-sheet 单一真源接管（见 ai-chat-sheet.css），此处不再自建 */

  /* 会议室入口 = 右下角正圆按钮(聊天泡泡图标,无文字) */
  .studio-meeting-peek {
    display: flex; align-items: center; justify-content: center;
    position: absolute; left: auto; right: 12px; bottom: 12px;
    width: 48px; height: 48px; z-index: 4;
    border: 1px solid var(--color-border); border-radius: 50%;
    corner-shape: round;
    background: var(--color-bg-page); color: var(--color-text);
    cursor: pointer; padding: 0;
  }
  /* the bubble keeps its own 24px drawing (owner 2026-09-16: the room's open button back to its original size) */
  .studio-meeting-peek svg { width: 24px; height: 24px; display: block; }
  .studio-meeting.duo-sheet-open ~ .studio-meeting-peek,
  .studio-meeting.duo-sheet-closing ~ .studio-meeting-peek { display: none; }   /* 下滑动画放完再让泡泡按钮回来 */
  /* No room, no bubble: while the welcome layer is up (no collection chosen, not training) there is nothing behind the
     sheet to open, so the button follows the same fact the welcome layer shows (owner 2026-09-16 phone). */
  .studio-view-page:has(> .studio-welcome:not([hidden])) .studio-meeting-peek { display: none; }
  /* The bubble floats over the bottom-right corner of every training page (12 from the bottom, 48 tall). Whatever scrolls
     under it keeps that zone clear, hub and object page alike: the hub's last row ends in a chevron on the right, the market
     page ends in Import on the right, and both sat under the bubble (owner 2026-09-16 phone; measured chevron 753-773 vs
     bubble 748-796). 16px was enough only while the last thing on a page was the left-hand Delete. One number, once. */
  .studio-view-page { --studio-peek-clear: calc(12px + 48px + 12px); }
  .studio-view-page.is-training .tp-left { padding-bottom: var(--studio-peek-clear); }
  .studio-view-page.is-training-object .tp-left { padding-bottom: var(--studio-peek-clear); }
  /* 上下对齐不在这里改:桌面那条 align-items: center 手机照用。曾经写 flex-start,一行的句子配一颗
     更高的按钮就被吊在按钮中线上方 7.5px(owner 2026-09-04 手机实拍"已是最新")。 */
  .studio-view-page.is-training .studio-ability-foot { margin: 20px 0 0; }
  /* 手机上页脚是设置页那张行卡:行恢复成行(卡/细线/内距全来自 settings-memory-toggle-group) */
  .tp-dna-actions { display: block; }
  /* ★卡的宽度真源 = 这一列的内容宽(.studio-org-scroll 的横向内距),对比卡就是这么摆的。
     设置 sheet 那条 .project-settings-cards .settings-memory-toggle-group { margin: 0 16px } 是给
     【直接放在 sheet 里、自己没有内距】的卡用的,在这一列里会再缩一层 —— 卡比对比卡窄一圈。 */
  .tp-obj-group { display: block; }
  /* ★必须带上 .project-settings-cards:要清掉的那 16px 来自
     .project-settings-cards .settings-memory-toggle-group(0,2,0),裸 .tp-obj-group(0,1,0)清不动
     —— 写了,卡还是比对比卡窄一圈(owner 2026-09-04 实拍)。同特异性靠本表后加载取胜。 */
  .project-settings-cards .tp-obj-group { margin: 0; }
  .tp-obj-row { display: flex; }
  .tp-obj-row .settings-row-label-group { display: flex; }
  /* 删除不在卡里(owner 2026-09-04):卡是一组东西,删除就一颗按钮 —— 没有灰底、没有说明,
     左下角,尺寸是页脚那一档大的。★这几条必须排在上面两条【之后】:同特异性(0,2,0),
     写在前面会被 .tp-obj-row 那两条盖掉(实拍:说明还在、按钮还在右边)。 */
  .tp-obj-bare { display: block; margin: 16px 0 0; }
  .tp-obj-bare .settings-row { padding: 0; border-bottom: none; }
  /* 卡里的按钮照设置行的真源 = 基准胶囊(Manage / Log out 那几行就是它)。页脚那一档大尺寸
     只属于【窗口底部动作行】—— 桌面上它确实是,手机上它是页中的一张卡。 */
  .tp-obj-row .project-modal-btn,
  .studio-ability-foot .project-modal-btn { padding: var(--btn-pill-pad-y) var(--btn-pill-pad-x); font-size: var(--btn-pill-font); }
  /* 删除是自己站着的那颗,拿页脚那一档(同上:排在胶囊那条之后才盖得住) */
  .tp-obj-bare .project-modal-btn { padding: var(--btn-block-pad-y) 14px; font-size: var(--btn-block-font); }
  /* 卡与上面那张对齐(列自己已有 24px 内距,别再往里缩一层);删除钮不再自己往左推 —— 行来放它 */
  .studio-view-page.is-training .tp-dna-actions { margin: 16px 0 0; }
  .tp-obj-row .studio-brand-del-btn { margin-right: 0; }
}
