.studio { height: 100vh; display: flex; flex-direction: column; overflow: hidden; }

/* ---------- 顶栏 ----------
   元素不少（返回/项目/名称/协作/模型/引擎/运行/分享/发布/用户），窄屏必须
   能压缩而不是把后面的挤出屏幕。策略：项目名可收缩，按钮不收缩也不换行。 */
.top {
  display: flex; align-items: center; gap: 12px;
  height: 54px; padding: 0 16px; flex: none;
  border-bottom: 1px solid var(--line); background: var(--bg-1);
  min-width: 0; overflow: hidden;
}
.top > * { flex: none; }
.sep { width: 1px; height: 20px; background: var(--line); }
.name {
  /* 唯一允许被压缩的元素：优先牺牲项目名的宽度 */
  flex: 0 1 200px; min-width: 86px;
  height: 30px; padding: 0 10px; border-radius: 8px;
  background: var(--bg-2); border: 1px solid transparent; outline: none; font-size: 13px;
}
.name:focus { border-color: var(--ac); }
.name[aria-invalid="true"] { border-color: var(--warn); }
#proj-name-status { max-width: 96px; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#proj-name-status:empty { display: none; }
.top-right {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
  flex: none; min-width: 0;
}
.pick { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--tx-2); }
.pick .field { height: 30px; max-width: 132px; }

/* 窄屏逐级收起次要内容，保证「运行/发布/用户菜单」永远可见可点 */
@media (max-width: 1500px) {
  .top { gap: 9px; }
  .pick .field { max-width: 104px; }
}
@media (max-width: 1320px) {
  .pick { font-size: 0; gap: 0; }         /* 只留下拉框，隐去「模型」「引擎」字样 */
  .pick .field { font-size: 12px; max-width: 92px; }
  .home b + * { display: none; }
}
@media (max-width: 1180px) {
  .top .home { font-size: 0; padding: 0 9px; }
  .top .home b { font-size: 13px; }       /* 只剩箭头 */
  #collab, #reqs { display: none; }       /* 协作入口在项目弹窗里还能进 */
}
@media (max-width: 1000px) {
  /* 模型/引擎切换频率低，收进「项目」弹窗之外的场景很少，先让位 */
  .top .pick { display: none; }
  .top #share { display: none; }
  .top .sep { display: none; }
}
@media (max-width: 880px) {
  .top { gap: 7px; padding: 0 10px; }
  .name { flex-basis: 110px; min-width: 64px; }
  .top #projs { font-size: 0; padding: 0 9px; }
  .top #projs::before { content: "☰"; font-size: 13px; }
}

/* ---------- 三栏 ----------
   `min-width: 0` 是关键，不能省：grid/flex 子项默认 min-width:auto，意思是
   「不得小于内容固有宽度」。中间栏装的是 iframe 与代码框，只要游戏里有个
   宽 canvas 或长文本，就会把 1fr 顶宽 → 整个 board 超出视口 → 左右两栏被
   挤出屏幕。加上它以后，1fr 才真正等于「剩余空间」。 */
.board {
  flex: 1; min-height: 0; min-width: 0; overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr) minmax(0, 272px);
}
.panel {
  display: flex; flex-direction: column;
  min-height: 0; min-width: 0; overflow: hidden;
  border-right: 1px solid var(--line);
}
.insp { border-right: 0; }
.p-head {
  display: flex; align-items: center; gap: 10px; flex: none;
  height: 40px; padding: 0 14px; font-size: 12.5px;
  border-bottom: 1px solid var(--line); background: var(--bg-1);
  min-width: 0; overflow: hidden; white-space: nowrap;
}
.p-head > :first-child { flex: none; }
.p-head #badge {
  overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.p-head-r { margin-left: auto; display: flex; gap: 6px; flex: none; }
.p-body { flex: 1; overflow: auto; padding: 14px; min-width: 0; }

/* 窄屏收起两侧，把空间留给预览。
   限定 :not(.asset-board) —— 资产库共用 .board，但它有自己的一套栏宽。 */
@media (max-width: 1240px) {
  .board:not(.asset-board) {
    grid-template-columns: minmax(0, 270px) minmax(0, 1fr) minmax(0, 234px);
  }
}
@media (max-width: 1040px) {
  .board:not(.asset-board) {
    grid-template-columns: minmax(0, 248px) minmax(0, 1fr);
  }
  /* Agent 每一步在对话区也能看到，窄屏先让位给预览 */
  .board:not(.asset-board) .insp { display: none; }
}

/* ---------- 对话 ---------- */
.msgs { flex: 1; overflow: auto; padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.msg { font-size: 13.5px; }
.msg .who { font-size: 11px; color: var(--tx-2); font-family: var(--mono); margin-bottom: 4px; }
.msg .bub { padding: 10px 12px; border-radius: 11px; background: var(--bg-1); border: 1px solid var(--line); }
.msg.me .bub { background: #1a1630; border-color: #35306a; }
.msg .diff { font-family: var(--mono); font-size: 11.5px; color: var(--ac-2); margin-top: 7px; }
.quick { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 14px 10px; }
.quick button {
  padding: 5px 9px; border-radius: 20px; cursor: pointer; font-size: 12px;
  background: transparent; border: 1px solid var(--line); color: var(--tx-2);
}
.quick button:hover { color: var(--tx); border-color: #3a3a46; }
.composer { flex: none; padding: 12px; border-top: 1px solid var(--line); }
.composer textarea {
  width: 100%; resize: none; padding: 9px 11px; border-radius: 10px;
  background: var(--bg-2); border: 1px solid var(--line); outline: none; font-size: 13.5px;
}
.composer textarea:focus { border-color: var(--ac); }
.composer-act { display: flex; gap: 8px; margin-top: 8px; }
.composer-act .btn { flex: 1; }
.composer-act #skills { flex: none; padding: 0 10px; }
.composer-act #skill-n { color: var(--tx-2); font-size: 11px; }
.plist { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; }

/* ---------- 预览 + 编辑器 ----------
   预览区的两个硬要求：
   1. **不被游戏内容撑开** —— iframe 里是任意 HTML，可能有超宽 canvas。
      靠 .view 的 overflow:hidden + 上面 .panel 的 min-width:0 一起挡住。
   2. **不形变** —— iframe 固定 16:9，用 aspect-ratio 让它在可用空间里等比
      缩放居中，而不是被拉成任意长宽比。 */
.stage { background: var(--bg); min-width: 0; }
.view {
  /* 用 grid 而不是 flex：flex 的 align-items 会参与子项尺寸协商，
     对带 aspect-ratio 的子项容易算出非等比结果；
     grid + place-items:center 只做定位，尺寸完全由子项自己的约束决定。
     独占剩余竖向空间（代码区是固定 basis 不伸展的）。 */
  flex: 1 1 auto;
  min-height: 160px; min-width: 0;
  display: grid; place-items: center;
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  background: radial-gradient(circle at 50% 0%, #17172a, var(--bg) 62%);
  padding: 10px;
  overflow: hidden;            /* 游戏内容再宽也不外溢 */
}
@media (max-width: 1300px) {
  .view { padding: 6px; }
}

/* 精确 16:9 的关键：把等比交给一层包裹（.screen），iframe 在里面 100% 填充。
   直接给 iframe 写 aspect-ratio + max-width/max-height 是不够的 —— 容器比
   16:9 更「高」时，height:100% 先撑满高度、宽度再被 max-width 截断，
   aspect-ratio 就让位了（实测比例掉到 1.53~1.69）。
   包裹层同时用 height:100% 与 max-width:100%，浏览器会自行取能同时满足
   两者的最大等比尺寸，等效于 object-fit: contain。 */
.screen {
  /* 尺寸由 JS 按 contain 规则精确算好写进这两个变量（见 studio.js fitScreen）。
     纯 CSS 方案（aspect-ratio + 双向 max）在容器比目标更高/更扁时，
     浏览器的尺寸协商顺序会让 aspect-ratio 让位，实测比例会漂到
     1.5~2.5，所以这里用变量兜底，CSS 只负责默认值。 */
  width: var(--sw, 100%);
  height: var(--sh, auto);
  aspect-ratio: var(--ar, 16 / 9);
  max-width: 100%; max-height: 100%;
  position: relative;
  border-radius: 8px; overflow: hidden; background: #000;
  box-shadow: 0 6px 28px rgba(0, 0, 0, .45);
}
#frame {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; display: block; background: #000;
}
/* 手机竖屏预览：9:16 的固定机身 */
.view.mobile .screen {
  aspect-ratio: 9 / 16;
  border-radius: 20px; border: 8px solid #1a1a22;
}
/* 原生全屏（#full 按钮走 requestFullscreen）时铺满整块屏幕，
   此时没有别的面板要让位，不必再守 16:9 */
#frame:fullscreen {
  width: 100%; height: 100%; max-width: none; max-height: none;
  aspect-ratio: auto; border-radius: 0; border: 0;
}

.tabs { display: flex; gap: 4px; min-width: 0; overflow-x: auto; }
.tabs button {
  padding: 4px 10px; border-radius: 7px; cursor: pointer; font-size: 12px;
  background: transparent; border: 1px solid transparent; color: var(--tx-2);
  font-family: var(--mono); white-space: nowrap; flex: none;
}
.tabs button.on { background: var(--bg-2); border-color: var(--line); color: var(--tx); }
.editor {
  /* 不参与伸展：竖向空间优先给预览（它要按 16:9 等比，越大越好用）。
     代码区固定占 32%，够看十几行；要细读代码可以点文件名在弹窗里看。
     max-height 防它在高屏上无意义地变高，min-height 保证矮屏仍可用。 */
  flex: 0 0 32%;
  min-height: 116px; max-height: 42%;
  width: 100%; resize: none;
  padding: 14px; border: 0; outline: none; background: #0b0b0f;
  font-size: 12.5px; line-height: 1.7; tab-size: 2;
  overflow: auto; white-space: pre;
}
/* 矮屏（笔记本 13 寸横屏、浏览器带调试栏）优先保预览 */
@media (max-height: 760px) {
  .editor { flex-basis: 26%; min-height: 96px; }
}

/* ---------- Agent 流程时间线 ---------- */
.flow { list-style: none; margin: 0; padding: 0 0 0 4px; }
.flow-empty { font-size: 12.5px; line-height: 1.7; }
.fs {
  position: relative; display: flex; gap: 9px;
  padding: 0 0 14px 0;
}
.fs::before {
  content: ""; position: absolute; left: 9px; top: 20px; bottom: 0;
  width: 1px; background: var(--line);
}
.fs:last-child::before { display: none; }
.fs-ico {
  flex: none; width: 19px; height: 19px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2); border: 1px solid var(--line);
  font-size: 10px; font-family: var(--mono); color: var(--tx-2);
}
.fs-main { min-width: 0; flex: 1; }
.fs-main b { display: block; font-size: 12.5px; font-weight: 550; }
.fs-main pre {
  margin: 5px 0 0; padding: 7px 9px; border-radius: 7px;
  background: var(--bg-1); border: 1px solid var(--line);
  font-family: var(--mono); font-size: 11px; line-height: 1.6;
  color: var(--tx-2); white-space: pre-wrap; word-break: break-all;
  max-height: 150px; overflow: auto;
}
/* 按类型着色 */
.fs.cmd   .fs-ico { color: #9ad1ff; border-color: #2b4055; }
.fs.file  .fs-ico { color: var(--ac-2); border-color: #1f4b3d; }
.fs.reply .fs-ico { color: #fff; background: var(--ac); border-color: transparent; }
.fs.plan  .fs-ico { color: #ffcb6b; border-color: #4d3f1e; }
.fs.error .fs-ico { color: var(--warn); border-color: #55202e; }
.fs.run  .fs-ico { animation: pulse 1.1s infinite; }
.fs.run  .fs-main b::after { content: " …"; color: var(--tx-2); }
.fs.fail .fs-main b { color: var(--warn); }
@keyframes pulse { 50% { opacity: .35; } }

/* ---------- 检查器 ---------- */
.insp h4 { margin: 20px 0 10px; font-size: 12px; color: var(--tx-2); letter-spacing: .06em; text-transform: uppercase; }
.row label { display: block; font-size: 12.5px; margin-bottom: 12px; }
.row span { float: right; color: var(--tx-2); font-family: var(--mono); }
.row input[type=range] { width: 100%; margin-top: 6px; accent-color: var(--ac); }
.levels { display: flex; flex-direction: column; gap: 6px; }
.lv {
  display: flex; justify-content: space-between; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 9px; font-size: 12.5px; cursor: pointer;
}
.lv:hover { border-color: #3a3a46; }
.lv.on { border-color: var(--ac); }
/* 中断/失败那一轮留下的半成品版本，给个不刺眼但能注意到的提示 */
.lv.warn { border-color: rgba(255, 176, 90, .42); }
.lv.warn:hover { border-color: rgba(255, 176, 90, .75); }
.lv .wm {
  display: inline-flex; align-items: center; justify-content: center;
  width: 13px; height: 13px; margin-right: 5px; vertical-align: -1px;
  border-radius: 50%; font-style: normal; font-size: 9.5px; font-weight: 700;
  background: rgba(255, 176, 90, .2); color: #ffb05a;
}

/* 项目行 + 删除键。删除平时几乎看不见，悬停整行才浮出来，避免误点 */
.lv-wrap { position: relative; display: flex; align-items: stretch; gap: 6px; }
.lv-wrap .lv { flex: 1; min-width: 0; }
.lv-wrap .lv > span:first-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lv-del {
  flex: none; width: 30px; border: 1px solid transparent; border-radius: 9px;
  background: none; color: var(--tx-2); font-size: 13px; cursor: pointer;
  opacity: 0; transition: opacity .14s, color .14s, border-color .14s;
}
.lv-wrap:hover .lv-del { opacity: .55; }
.lv-del:hover {
  opacity: 1; color: var(--warn, #ff6b6b); border-color: var(--warn, #ff6b6b);
}
.lv-del:disabled { opacity: .3; cursor: default; }
/* 回收站里的「还原」—— 这是正向操作，常态就该看得见 */
.lv-act {
  flex: none; padding: 0 10px; border-radius: 9px; cursor: pointer;
  background: transparent; border: 1px solid var(--line);
  color: var(--tx-2); font-size: 12px;
  transition: color .14s, border-color .14s;
}
.lv-act:hover { color: var(--ac-2, #33e6b0); border-color: var(--ac-2, #33e6b0); }
.lv-act:disabled { opacity: .4; cursor: default; }
.assets { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.asset {
  position: relative; height: 54px; border-radius: 9px; overflow: hidden;
  display: flex; align-items: flex-end; padding: 6px 8px;
  background: var(--bg-2); border: 1px solid var(--line);
  font-size: 11px; font-family: var(--mono);
}
.asset img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .55; }
.asset span {
  position: relative; width: 100%; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.asset.add { background: none; border: 1px dashed var(--line); align-items: center; justify-content: center; color: var(--tx-2); cursor: pointer; }
.chk { display: block; font-size: 12.5px; margin-bottom: 8px; color: var(--tx-2); }

/* ---------- 对话框附件（多模态输入） ----------
   .attach / .at 的通用样式在 base.css，这里只放对话框特有的布局 */
.composer .attach { margin: 0; padding: 7px 8px 0; }
.composer-act .grow { flex: 1; }
.btn.ico { padding: 0 9px; font-size: 14px; }

/* ---------- API 未连接：黄色警告 ----------
   用既有的琥珀色（同版本历史里的「未完成」标记），红色留给真正的危险操作 */
.api-warn {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 12px 8px; padding: 9px 11px; border-radius: 9px;
  border: 1px solid rgba(255, 176, 90, .45); background: rgba(255, 176, 90, .10);
}
.api-warn[hidden] { display: none; }   /* 类选择器会盖掉 hidden 属性，必须显式关掉 */
.api-warn .aw-txt { flex: 1 1 100%; min-width: 0; font-size: 11.5px; line-height: 1.6; }
.api-warn .aw-txt b { display: block; color: #ffb05a; font-size: 12px; }
.api-warn .aw-txt span {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; color: var(--tx-2);
}
.api-warn .aw-act { display: flex; gap: 6px; flex: none; margin-left: auto; }
.btn.warn {
  border-color: rgba(255, 176, 90, .6); background: rgba(255, 176, 90, .16);
  color: #ffc47d;
}
.btn.warn:hover { background: rgba(255, 176, 90, .26); border-color: #ffb05a; }

/* 技能勾选行：复用 .lv 的外框，只补 checkbox 的排布 */
.chk-lv {
  display: flex; align-items: flex-start; justify-content: flex-start;
  gap: 9px; cursor: pointer; text-align: left;
}
.chk-lv > span { flex: 1; min-width: 0; }
.chk-lv input { margin-top: 3px; flex: none; accent-color: var(--ac); }
.chk-lv em { display: block; font-style: normal; font-size: 11px; margin-top: 3px; }
/* 拖拽悬停时整块对话区高亮 */
.chat.drop { outline: 2px dashed var(--ac); outline-offset: -6px; }

/* ---------- 自动续作 ---------- */
.ap { font-size: 12.5px; }
.ap .sw { color: var(--tx); line-height: 1.5; }
.ap-cfg { display: flex; gap: 8px; margin: 4px 0 10px; }
.ap-cfg label {
  flex: 1; display: flex; flex-direction: column; gap: 4px;
  font-size: 11px; color: var(--tx-2);
}
.field.sm { height: 26px; font-size: 12px; padding: 0 7px; }
.ap-queue { margin-bottom: 10px; }
.ap-queue .field { width: 100%; margin-bottom: 6px; }
.ap-task { display: flex; justify-content: space-between; gap: 8px; cursor: default; }
.ap-task .x { color: var(--tx-2); cursor: pointer; }
.ap-task .x:hover { color: var(--warn); }
.ap-round {
  padding: 7px 9px; margin-bottom: 5px; border-radius: 8px;
  background: var(--bg-1); border: 1px solid var(--line);
}
.ap-round b { display: block; font-size: 11.5px; font-weight: 550; }
.ap-round span { font-family: var(--mono); font-size: 10.5px; color: var(--tx-2); }
.ap-round.running { border-color: #4d3f1e; }
.ap-round.failed { border-color: #55202e; }
.ap-away {
  padding: 8px 10px; border-radius: 9px; margin-bottom: 9px;
  background: #16132a; border: 1px solid #35306a; font-size: 12px;
}

@media (max-width: 1080px) {
  .board { grid-template-columns: 1fr; overflow: auto; }
  .studio { height: auto; overflow: visible; }
  .view { height: 340px; }
}
