/* assets/css/pdf-workbench.css — PDF Workspace 执行器的组合层（Phase 10A2）
 *
 * 与 image-workbench.css 同一角色：只写这一块工作区**特有**的布局与状态。
 * 组件视觉（按钮 / 下拉 / 菜单 / accordion / completion / trust）全部来自
 * assets/css/workspace-ui.css —— 这里不再复制一套（10A2 §7）。
 * 颜色/圆角一律引用 tokens.css，不硬编码色值。
 *
 * ⚠️ 这一份没有第二条 "legacy / quick" 路径：Founder 批准的层级**就是**
 *    公开默认形态，所以不存在两套 CSS 需要长期维护（§3/§96）。
 */
/* 大区块节奏由 .yqw-surface 的 --yqw-section-gap 一处提供（§12）——
   以前 PDF 是 12px、Image 是另一套，这正是两条线不像一家的另一半原因。 */
.pw { display: block; }
.pw * { box-sizing: border-box; }
.pw [hidden] { display: none !important; }   /* 作者样式会盖过 UA 的 [hidden] */

/* ⚠️ 空态的可见视觉已收敛到 workspace-ui.css 的 .yqw-dropzone（10A2-B §13/§14）：
   Image 与 PDF 必须是**同一个组件**，只允许文案、格式串与 accept 不同。
   这里以前那一份 .pw-dropzone 是第二套视觉，已合法退役。 */

/* ── Office 暂存（import-time，不是 Source）──────────────── */
.pw-staged-title { font-size: 13px; font-weight: 500; color: var(--yq-text-2); margin: 0 0 8px; }
.pw-staged { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px;
              /* 暂存文件多时**这一列自己滚**（10B1 §7）：外壳已经锁高，
                 不能让一堆 staged 行把 Continue / Cancel 顶出视口。
                 滚动条视觉来自共享层的 .yqw-scroll，这里只给上限。 */
              max-height: 232px; overflow-y: auto; }
.pw-staged li { display: grid; grid-template-columns: 76px minmax(0, 1fr) auto; gap: 10px;
                align-items: center; background: var(--yq-bg-page);
                border: 1px solid var(--yq-border); border-radius: var(--yq-r-ctl);
                padding: 10px 14px; }

/* ── Sources（住在 Header count 旁边那个 popover 里）──────────
   ⚠️ 整张表**统一一个字号**（--yqw-t4，也就是第一列 doc-tag 那一档）：
   以前标签 12px、文件名与页数继承 14px，一行里三种字号，读起来是散的。 */
.pw-sources { list-style: none; margin: 0; padding: 0; font-size: var(--yqw-t4-size); }
.pw-sources li { display: grid;
                 grid-template-columns: 16px 26px 64px minmax(0, 1fr) auto auto; gap: 10px;
                 align-items: center; padding: 7px 0; border-top: 1px solid var(--yq-border); }
/* 方形预览：PDF 的第一页 / 图片本身。**小而已，不抢视觉** —— 它只是让用户
   在一长串同名文件里认出哪一份是哪一份。走的是页网格那条**同一个**懒渲染
   管线与缓存，不另起一套。 */
.pw-sources .doc-thumb { width: 26px; height: 26px; border-radius: 4px; overflow: hidden;
                         background: var(--yq-bg-canvas); border: 1px solid var(--yq-border);
                         display: flex; align-items: center; justify-content: center; }
/* ⚠️ `cover` 默认取**垂直居中**那一块 —— 竖版页面的标题正好被裁掉。
   封面要看顶部，所以 object-position 定在 top。 */
.pw-sources .doc-thumb img { width: 100%; height: 100%; display: block;
                             object-fit: cover; object-position: top center; }
.pw-sources li:first-child { border-top: 0; }
.pw-sources .doc-tag { font-weight: 600; }
.pw-sources .doc-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pw-sources .doc-meta { color: var(--yq-text-3); white-space: nowrap; }
.pw-staged .fmt { font-size: var(--yqw-t4-size); }
/* 拖动手柄：拖它 = 把这份来源的所有页当成一组移到新位置。
   ⚠️ 只改页序，不改 sourceOrder —— 标签与 primary 的身份保持不变。 */
.pw-sources .doc-grip { display: inline-flex; align-items: center; justify-content: center;
                        color: var(--yq-text-3); cursor: grab; }
.pw-sources li.is-dragging { opacity: .45; }
@media (prefers-reduced-motion: reduce) {
  .pw-sources li { transition: none !important; }
}
.pw-sources li.drop-before { box-shadow: inset 0 2px 0 0 var(--yq-primary); }
.pw-sources li.drop-after  { box-shadow: inset 0 -2px 0 0 var(--yq-primary); }
/* 来源多时这一列自己滚（上限由 JS 按外壳高度算），滚动条走共享层。
   ⚠️ 默认滚动条会落在**内容区**的右缘 —— 那是浮层内边距(16px)之内，
   于是它紧贴着 Remove 按钮（Founder：都挨上了）。把这一层向右撑出内边距，
   让轨道落到距浮层右边 6px 的位置；行内容再用 padding 推回来，
   所以 Remove 与滚动条之间有真实的空隙。 */
.pw-sources-scroll { overflow-y: auto;
                     --pw-sb-inset: 4px;
                     margin-right: calc((var(--yqw-pop-pad-x) - var(--pw-sb-inset)) * -1);
                     padding-right: calc(var(--yqw-pop-pad-x) - var(--pw-sb-inset)); }

/* ══ Page Object Region（10B1 §8/§9/§51）══════════════════════════════════
   对象区是一个**看得见的容器**：与 Completion 用同一套边框 / 圆角 / 底色，
   左右边缘也一致 —— 两块因此读起来是"编辑对象区 + 完成区"同一组东西，
   而不是"一堆页卡散在白 surface 上"。
   ⚠️ 外壳锁高（见 pdf-workbench.js 的 attachSurfaceFit）之后，剩余高度全部
   落在这里：`flex: 1 1 auto` + `min-height: 0`。少了 min-height，flex 子项的
   默认最小尺寸是内容高度，页一多就会把外壳顶破而不是自己滚。 */
.pw-region { display: flex; flex-direction: column; min-height: 0;
             /* ⚠️ 圆角与 Completion **逐值相同**（--yq-r-ctl）：两块要读起来是
                同一组东西，差一档就散了（§8/§51）。 */
             border: 1px solid var(--yq-border); border-radius: var(--yq-r-ctl);
             background: var(--yqw-sunken); padding: var(--pw-region-pad); gap: 10px;
             /* 这两个数被 .pw-scroller 与拖放指示条一起消费，所以只声明一次。 */
             --pw-region-pad: 12px; --pw-grid-gap: 12px; }
.pw .yqw-surface { display: flex; flex-direction: column; }
.pw .pw-region { flex: 1 1 auto; }
/* 空态里剩余高度归拖放区（与 Image 同一条关系）。 */
.pw[data-yq-state="empty"] .yqw-dropzone { flex: 1 1 auto; }

/* 对象区自己的 contextual toolbar：History 与选页入口。
   这里**没有** Export —— 全页唯一的主 CTA 在 Completion 里。 */
.pw-region-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
                 min-height: 28px; }
.pw-region-bar .yqw-grow { flex: 1 1 auto; }

/* ── Pages 区高度偏好 1× / 2× / 4×（Phase 17B3）─────────────────────────
   ⚠️ **不另造颜色体系**：这就是既有的 `.yqw-btn--mini` 一档，只多两件事 ——
      三个按钮连成一组（中间不重边框），以及一个选中态。
   ⚠️ 选中态是**一条 1px accent 边框 + 轻底**，不叠 inset ring：
      V0.0.1228 冻结过"选中 = 一层就够"，叠起来会变成 2px。
   ⚠️ 数字是语言中立的（1× / 2× / 4×），所以按钮上没有 data-i18n；
      能读出来的名字走 aria-label（见模板），文字与无障碍名字在这里刻意分工。 */
.pw-hscale { display: inline-flex; align-items: center; }
.pw-hscale .yqw-btn--mini { padding: 0 9px; font-variant-numeric: tabular-nums; }
.pw-hscale .yqw-btn--mini + .yqw-btn--mini { margin-left: -1px; }
.pw-hscale .yqw-btn--mini:not(:first-child):not(:last-child) { border-radius: 0; }
.pw-hscale .yqw-btn--mini:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.pw-hscale .yqw-btn--mini:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.pw-hscale .yqw-btn--mini[aria-pressed="true"] {
  /* 与页卡选中态同源：`.pw-grid .pc[aria-selected]` 用的就是 --yq-primary。
     ⚠️ 别引用不存在的令牌 —— 第一版我写了 `--yq-accent`，tokens.css 里根本没有，
        CSS 会静默退化成继承值，看起来"选中态没生效"。 */
  border-color: var(--yq-primary); color: var(--yq-primary);
  background: var(--yq-primary-weak);
  /* 选中的那一段要压在相邻边框之上，否则左边那条会被后一个按钮盖掉 */
  position: relative; z-index: 1; }
.pw-icon-btn { width: 28px; height: 28px; display: inline-flex; align-items: center;
               justify-content: center; border: 1px solid var(--yq-border);
               border-radius: var(--yq-r-ctl); background: #fff; color: var(--yq-text-2);
               cursor: pointer; padding: 0; }
.pw-icon-btn svg { width: 16px; height: 16px; }
.pw-icon-btn:hover:not(:disabled) { border-color: var(--yq-border-strong); color: var(--yq-text-1); }
.pw-histtools { display: flex; gap: 6px; align-items: center; }

/* Selection 是 compact 的**对象区内部状态**（§32）：不再是一整块大横条，
   所以 Completion 不用让位搬家、Export 的位置也不会跳。 */
.pw-seltools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: 1 1 auto; }
.pw-seltools-count { font-size: var(--yqw-t4-size); color: var(--yq-text-2); }
/* ⚠️ 数字变宽会把整条工具条往右推（15 → 3 就跳一下）。给**数字**留出
   三位数的固定槽 + 等宽数字，所以 1 / 15 / 999 之间按钮一个像素都不动。
   留的是数字的宽度而不是整段文字的宽度 —— 后者在别的语言下必然不准。 */
.pw-count-slot { display: inline-block; min-width: 3ch; text-align: right;
                 font-variant-numeric: tabular-nums; }
.pw-seltools-sep { width: 1px; height: 16px; background: var(--yq-border); }
.pw-seltools .yqw-grow { flex: 1 1 auto; }

/* 滚动的那一层。视觉滚动条只来自共享层的 `.yqw-scroll`（§10）——
   这一份 CSS 里**没有第二套 ::-webkit-scrollbar 皮肤**。
   ⚠️ 也**不要**写 `overscroll-behavior: contain`：那条的字面意思就是
   "滚到头也不许把滚动交给外层"，实测就是滚轮停在页网格里、整页不动。 */
/* ⚠️ `min-height: 0` 让它能被压缩（flex 子项的默认最小尺寸是内容高度，
   不写这条页一多就把外壳顶破）；`--pw-region-floor` 则是**下限**：
   矮视口（800×600、笔记本半屏、Lab 页上下还有别的卡）上，"剩余高度"可能
   收成 0，对象区就成了一条缝 —— 一张页卡都看不见，懒渲染也因此一张都不触发。
   到了那一步宁可让外层页面自然滚动（10B1 §7：绝不 clip 关键信息），
   也不要一个 0 高的对象区。⚠️ 这是**下限**不是写死高度（§112）。 */
/* ⚠️ 滚动条与右边缘的距离（V0.0.1245，Founder：减到 4px）：
   `overflow` 的滚动条永远画在**这个盒子自己的**右边缘上，所以要让它更靠外，
   就得让盒子探出去 —— 负 margin 把它拉到距离对象区内边 --pw-sb-inset 处，
   等量的 padding 再把内容推回原位，页卡一个像素都不动。
   与 Sources 弹窗用的是**同一条**做法与同一个值（.pw-sources-scroll）。
   ⚠️ 左边也探出**半个 gap + 1px**：拖放指示条画在两张卡中间的空档里，
   第一列那根落在卡片左外侧 —— 不留这段，`overflow` 会把它整条裁掉，
   而"拖到最前面"恰恰是个真实动作。 */
.pw-scroller { flex: 1 1 auto; min-height: 0; overflow-y: auto;
               --pw-sb-inset: 4px;
               margin-left: calc(var(--pw-grid-gap) / -2 - 1px);
               padding-left: calc(var(--pw-grid-gap) / 2 + 1px);
               margin-right: calc((var(--pw-region-pad) - var(--pw-sb-inset)) * -1);
               padding-right: calc(var(--pw-region-pad) - var(--pw-sb-inset)); }
.pw-region { --pw-region-floor: 160px; }
/* 页卡里的预览区高度（V0.0.1244）：A4 竖版卡片因此从 186px 降到 161px。
   改这一个数就够，卡片宽度与网格列数一个字不用动。 */
.pw-grid { --pw-card-preview-h: 104px; }
.pw-region .pw-scroller { min-height: var(--pw-region-floor); }

/* ── Page grid：对象本身是这一屏的主体 ───────────────────────────────────
   ⚠️ 关键关系（§12）：**宽屏变化的是每行几张，卡片宽度只在一个紧凑区间内变**。
   `auto-fill + minmax(106px, 1fr)` 让列数按 106px 下限决定，余量摊进列宽把
   右边抹平，所以卡片始终落在约 106–150 这一档，绝不会变成一行几张巨大的页卡。 */
.pw-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(106px, 1fr));
           /* 锁高之后网格常常比内容高，而 grid 默认会把多余高度摊给各行 ——
              只有一页时那张卡会被拉成半屏高。行高必须按内容走。 */
           align-content: start;
           gap: var(--pw-grid-gap); margin: 0; padding: 0; list-style: none; }
.pw-grid .pc { border: 1px solid var(--yq-border); border-radius: var(--yq-r-ctl);
               background: #fff; padding: 8px; cursor: pointer;
               user-select: none; position: relative; }
.pw-grid .pc:hover { border-color: var(--yq-border-strong); }
/* 选中态**只有一层 1px accent**（10B1 §15/§34，见 docs/ui/quiet-ui-v2.md §3.1）。
   ⚠️ 以前这里是 border + inset ring = 视觉 2px，几十页同时选中时一屏粗蓝框。 */
.pw-grid .pc[aria-selected="true"] { border-color: var(--yq-primary); box-shadow: none; }
/* 拖放指示（V0.0.1245，Founder 明确否掉了旧做法）：
   ⚠️ 旧版是给目标卡片加一条 3px 的 inset 描边 —— 页卡本身选中时又是蓝框，
   于是读起来像"前后两张卡的边都变粗了"，而不是"要插到这里"。
   现在是**一条**独立的 2px 竖条，画在两张卡之间那 12px 空档的正中间：
   它不属于任何一张卡，语义就是插入位置本身。 */
.pw-grid .pc.drop-before::after,
.pw-grid .pc.drop-after::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 2px;
  border-radius: 1px; background: var(--yq-primary); pointer-events: none; }
.pw-grid .pc.drop-before::after { left: calc(var(--pw-grid-gap) / -2 - 1px); }
.pw-grid .pc.drop-after::after  { right: calc(var(--pw-grid-gap) / -2 - 1px); }
.pw-grid .pc.dragging { opacity: .45; }
/* 预览区**高度固定**（V0.0.1244，Founder：卡片矮 25px、宽度不变）。
   ⚠️ 页框比例没有被丢掉 —— 它搬进了里面的 .thumbPage：
   预览区是一个固定的格子，页按自己的比例**contain 在格子里**。
   以前是"框 = 页"，所以横版页的卡片比竖版矮一大截，整片网格行高参差；
   现在每张卡等高，页的形状仍然看得见（横版就是一条更扁的页）。
   宽度用 `min(100%, 预览高 × 页宽高比)`：宽度定死之后高度由 aspect-ratio 推出，
   必然 ≤ 预览高 —— 不会出现"两个方向都被夹取、比例被压掉"的那种写法。 */
.pw-grid .thumbBox { width: 100%; height: var(--pw-card-preview-h);
               display: flex; align-items: center; justify-content: center;
               /* 点它是"看清楚这一页"（V0.0.1247）——与 Image 卡片同一个动作、
                  同一个查看器，所以也用同一个光标语汇。 */
               cursor: zoom-in; }
.pw-grid .thumbPage { width: min(100%, calc(var(--pw-card-preview-h) * var(--pw-ar, 1)));
               background: var(--yq-bg-canvas); border-radius: 6px; overflow: hidden;
               display: flex; align-items: center; justify-content: center; }
.pw-grid .thumb { max-width: 100%; max-height: 100%; display: block; object-fit: contain; }
.pw-grid .pc.is-image .thumbPage { background: #FAFBFC; }
.pw-grid .pos { font-size: 13px; font-weight: 550; color: var(--yq-text-1); margin-top: 6px;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pw-grid .src { color: var(--yq-text-3); font-size: 12px; margin-top: 2px; overflow: hidden;
               text-overflow: ellipsis; white-space: nowrap; }
/* geometry / 旋转角这类 Engine 语汇**只在 Lab**（data-pw-debug）出现（§14/§55）。 */
.pw-grid .geo { color: var(--yq-text-3); font-size: 11px; }
/* selection mode 才有的 checkbox —— 平时它根本不在 DOM 里。
   ⚠️ 视觉尺寸不变，但点击热区四边各 +10px（10B1 §33，Image 已验证）：
   热区是包在外面的 label 的 padding，所以 checkbox 的位置与大小一点没动。 */
.pw-grid .pc-check-hit { position: absolute; top: -2px; left: -2px; padding: 10px;
               display: inline-flex; cursor: pointer; z-index: 2; }
.pw-grid .pc-check { width: 17px; height: 17px; margin: 0; accent-color: var(--yq-primary); }

/* ══ 进件骨架屏（V0.0.1249）══════════════════════════════════════════════
   Founder：大 PDF 从选中文件到卡片出现有半秒空白（530 页实测 529ms），
   那段时间用户还盯着拖放区。骨架不加速任何事，它只是**把状态先摆出来**。
   ⚠️ 用 `@keyframes` 的微光而不是转圈：转圈是"正在等一件不知道多久的事"，
   微光是"这里马上会有内容"，后者才是这里的实情。
   ⚠️ `prefers-reduced-motion` 下不动 —— 静止的灰块同样说明了"待填"。 */
.pw-grid .pc-skeleton { cursor: default; pointer-events: none; }
.pw-grid .thumbPage.is-skeleton,
.pw-grid .pc-skeleton .skeleton-line { position: relative; overflow: hidden;
               background: var(--yq-bg-canvas); }
.pw-grid .pc-skeleton .skeleton-line { border-radius: 4px; color: transparent; }
.pw-grid .pc-skeleton .pos { height: 13px; margin-top: 8px; }
.pw-grid .pc-skeleton .src { height: 11px; margin-top: 4px; width: 70%; }
.pw-grid .thumbPage.is-skeleton::after,
.pw-grid .pc-skeleton .skeleton-line::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .75), transparent);
  transform: translateX(-100%);
  animation: pw-skeleton 1.25s ease-in-out infinite;
}
@keyframes pw-skeleton { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .pw-grid .thumbPage.is-skeleton::after,
  .pw-grid .pc-skeleton .skeleton-line::after { animation: none; }
}

/* 缩略图还没到的那些**真**卡片同样给微光（V0.0.1249）：
   以前是一个空灰框，读起来像"这页坏了"，其实只是还没渲到。
   ⚠️ 判据是 `.thumb:not([src])` —— 懒渲染给 src 的那一刻它自动消失，
   不需要任何一行 JS 去摘状态。 */
.pw-grid .thumb:not([src]) { visibility: hidden; }
.pw-grid .thumbPage:has(.thumb:not([src]))::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .75), transparent);
  transform: translateX(-100%);
  animation: pw-skeleton 1.25s ease-in-out infinite;
}
.pw-grid .thumbPage { position: relative; }
@media (prefers-reduced-motion: reduce) {
  .pw-grid .thumbPage:has(.thumb:not([src]))::after { animation: none; }
}

/* 网格末尾的「+」占位卡（§20/§49）：第二个添加入口，和 Header 的 Add files
   走**同一个 fileInput、同一条 intake**。
   ⚠️ 刻意**不带 .pc**：它不是一页，不进 Page Plan、不参与选择、不可旋转、
   不可拖拽、不进导出。 */
.pw-add-tile { border: 1px dashed var(--yq-border-strong); border-radius: var(--yq-r-ctl);
               background: transparent; color: var(--yq-text-3); cursor: pointer;
               display: flex; align-items: center; justify-content: center;
               min-height: 92px; padding: 8px; }
.pw-add-tile:hover:not(:disabled) { border-color: var(--yqw-primary); color: var(--yqw-primary);
               background: var(--yq-primary-weak); }
.pw-add-tile svg { width: 22px; height: 22px; }
.pw-add-tile:disabled { opacity: .5; cursor: not-allowed; }

/* ══ Context notices（§42/§43）════════════════════════════════════════════
   DjVu / TIFF / 签名 / 输出提示归成一组，位置固定在**对象区与 Completion 之间**。
   提示出现时缩小的是对象区（它是 flex:1），Completion 与 Trust 一动不动。 */
.pw-context-notices { display: flex; flex-direction: column; gap: 8px; }
.pw-context-notices:not(:has(> :not([hidden]):not(:empty))) { display: none; }

/* Completion 里"当前输出/版式真正有的可调项"。它**不是 Advanced**：
   没有折叠、没有分类、没有二级导航（§27）。 */
.pw-controls { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: flex-end;
               border-top: 1px solid var(--yq-border); padding-top: 12px; }

/* ══ Completion → Trust 是同一组（10B1 §41）════════════════════════════
   与 Image 逐条相同：不再画那条分割线，改用一个 wrapper 承载更紧的内部间距
   （约 15px），并用同样的上内边距把盒高补回来 —— 所以两条产品线在同一视口下
   trust 的位置一致。**不给 trust 写负 margin**：负 margin 会随父级 gap 变化失准。 */
/* ⚠️ gap 从 15px 收成 0（V0.0.1245，Founder："export as 这个容器下移 15px，
   空出来的空间给 pages card 容器高度增加"）。
   外壳是**锁高**的、对象区是 `flex: 1`，所以"对象区多 15px"这件事必须有人
   让出 15px —— 不可能凭空多出来。这里让出的是 Completion 与 Trust 之间那条
   纯空白：Trust 自己还带 12px 的 padding-top，所以两者仍然分得开，
   而 Trust 与 surface 底边一个像素都没动。 */
.pw .pw-close { display: flex; flex-direction: column; gap: 0; }
.pw[data-yq-state="empty"] .pw-close { margin-top: 12px; }
.pw .yqw-trust { border-top: 0; padding-top: 13px; margin-top: 0; }

/* Header 里那个很轻的 Sources 入口（§57）：它是 metadata 旁边的一个链接式
   affordance，不是又一个按钮。 */
.pw-quiet-link { background: none; border: 0; padding: 0 0 0 8px; font: inherit;
                 font-size: var(--yqw-t4-size); color: var(--yqw-primary);
                 cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.pw-quiet-link:hover { color: var(--yq-primary-strong); }

/* popover 里的 body：range 与 sources 两组被**原地搬进来**，关掉搬回去。 */
.pw-pop-body { display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
               font-size: var(--yqw-t4-size); }
.pw-pop-body .yqw-full { flex: 1 1 100%; }
.pw-pop-body .yqw-grow { flex: 1 1 auto; }
/* 浮层标题：与 Completion 的 EXPORT AS 同一档（section label），不是正文。 */
.pw-pop-title { flex: 1 1 100%; margin: 0 0 2px; font-size: var(--yqw-t5-size);
                font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
                color: var(--yq-text-3); }
/* range：输入框 + Select **一行搞定、同高**（Founder）。
   ⚠️ 高度用 **mini 档 28px**，不是自己发明的数字：Select 原来是
   `--yqw-h-primary`(46px)，那是**主 CTA** 的档 —— 浮层里的行内动作不该占那一档。
   46 × 60% ≈ 28，正好落在设计系统已有的 `.yqw-btn--mini` 上。
   ⚠️ 输入框必须**显式写全**设计系统的那几项：它已经不在 `.yqw-field` 里了，
   不写就退回浏览器默认（实测高 19px、UA 的 2px inset 边框、圆角 0、无内边距）
   —— 那正是 Founder 看到的"样式不对、像两层边框"的来源。 */
.pw-range-row { display: flex; align-items: center; gap: 8px; width: 100%; }
.pw-range-row #rangeInput {
  flex: 1 1 auto; min-width: 0; width: auto;
  font: inherit; font-size: var(--yqw-t4-size);
  height: var(--yqw-h-mini); padding: 0 10px;
  border: 1px solid var(--yq-border-strong); border-radius: var(--yq-r-ctl);
  background: #fff; color: var(--yq-text-1); }
.pw-range-row .yqw-btn { flex: 0 0 auto; }
.pw-pop-body .yqw-btn { font-size: var(--yqw-t4-size); }
/* ⚠️ **只有一层环**（Founder）：焦点环用 `outline-offset: -2px` 画在边框位置上，
   与边框重合 —— 看起来仍是一条边，只是变粗变色，而且不会有布局位移。
   共享层默认的 `outline-offset` 会让它落在边框**外面**，那就是两道圈。 */
.pw-range-row #rangeInput:focus,
.pw-range-row #rangeInput:focus-visible {
  outline: 2px solid var(--yqw-primary); outline-offset: -2px;
  border-color: var(--yqw-primary); }
/* 输入不合法：同一条边变红，不在页卡容器上方另立警告条。
   红框说的是"这次输入不能执行"，不是 Workspace 级别的故障。 */
.pw-range-row #rangeInput.is-invalid { border-color: var(--yq-danger); }
.pw-range-row #rangeInput.is-invalid:focus,
.pw-range-row #rangeInput.is-invalid:focus-visible {
  outline-color: var(--yq-danger); border-color: var(--yq-danger); }

/* Office 转换中的四层：file list → progress → notice → Cancel。
   任何两层都不许贴在一起（§21/§37）。 */
.pw .office-progress { margin: 14px 0 0; font-size: 13px; line-height: 1.4;
                       color: var(--yq-text-2); }
.pw .office-progress + .yqw-notice-warn { margin-top: 18px; }
.pw .yqw-notice-warn + .yqw-secondary { padding-top: 16px; }

.pw-error { border: 1px solid #FDE68A; background: #FFFBEB; border-radius: var(--yq-r-ctl);
            padding: 8px 12px; margin: 0; font-size: 13px; color: #92400E;
            display: flex; align-items: flex-start; gap: 10px; }
.pw-error > span { flex: 1 1 auto; }
/* 关闭键与文字同色系、不抢戏；热区比图标大一圈。 */
.pw-error-x { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
              width: 22px; height: 22px; margin: -2px -4px 0 0; padding: 0; cursor: pointer;
              border: 0; border-radius: 6px; background: transparent; color: inherit; opacity: .7; }
.pw-error-x:hover { opacity: 1; background: #FEF3C7; }

@media (max-width: 640px) {
  .pw-sources li { grid-template-columns: 16px 26px minmax(0, 1fr) auto; }
  .pw-sources li .doc-tag { grid-column: 3; }
  .pw-sources li .doc-name { grid-column: 3; }
  .pw-sources li .doc-meta { grid-column: 3 / -1; }
  .pw-staged li { grid-template-columns: 60px minmax(0, 1fr); }
  .pw-staged li .doc-meta { grid-column: 2 / -1; }
  /* 390px 上仍要能放两列且预览看得清（§66）：宽度关系优先于"强制两列"。 */
  .pw-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .pw-region { padding: 10px; }
  .pw-region-bar { row-gap: 6px; }
}

/* ══ 空节点不占位（V0.0.1230 / 10B1 §R）════════════════════════════════
   `#pwAdvHost` 平时是**空的**（0 高），但它仍然是可见的 flex 子项 —— 于是
   surface 的 24px section gap 照样为它让出一份，空态凭空高出几十像素。
   空的容器不该占位。⚠️ 用 :has 判据而不是让 JS 去 toggle hidden：
   这是纯粹的"有没有内容"，不是产品状态，不该再多一处状态同步。
   ⚠️ Advanced host 里**装着**那个折叠面板（只有内部 Lab 才有），
   所以判据不是 :empty 也不是"有没有孩子"，而是"有没有**看得见的**孩子"。 */
#pwAdvHost:not(:has(> :not([hidden]))) { display: none; }
