/* ============================================================
   Image Workbench 组合层（Phase 3B / Quiet UI V2）

   **只负责组合与布局**，以及 viewer 这类领域组件。
   按钮 / 边框 / badge / dropzone / file row / progress / toolbar
   的视觉一律来自 assets/css/quiet-ui-v2.css —— 这里绝不重画一遍，
   否则设计系统就名存实亡了（tests/check.sh 第 [29] 组有门禁）。

   作用域：工具页只有 .yq2 那一块 Workbench 进入 V2，
   SEO 正文与 landing 外壳继续用 tool-landing.css，排版不被污染。
   ============================================================ */

/* ---------- 组合布局 ---------- */
/* ⚠️ Phase 10A2-B：Workspace 的**外壳 / Task header / dropzone / trust**
   已经全部收敛到 assets/css/workspace-ui.css 的 .yqw-* 权威（§4/§34）。
   这里以前的 .iw-head / .iw-h1 是 Quiet UI V2 时代的视觉 override，
   它们会把 shared title 的字号与 margin 顶掉，正是 Image 与 PDF
   "看起来是两个产品"的一半原因 —— 在 workspace path 上**合法退役**。
   SEO identity 是那段文字本身，不是这几行旧 CSS 的字号（§19）。 */

/* 面板整体的纵向体量（V0.0.1178 调整）。
   在这之前空态面板只有约 350px 高，配 720px 的宽度显得又扁又空——
   容器比例不对，不是字号问题，所以这里只动布局尺寸，**不碰任何排版令牌**
   （字号仍由 g11 的 computed-style 断言把守）。
   放大的是"呼吸"而不是"密度"：行高、字号、控件档位全部不变。 */
/* ⚠️ 这里**不要**加 min-height。试过：为了让"空态→放文件"不跳而给 body 一个
   高度下限，结果选中状态的信任行下面多出约 180px 死白——比高度变化难看得多
   （flex column 的剩余空间只会堆在末尾）。
   面板放文件后变矮是合理的：文件列表本来就比空拖放区紧凑。 */
/* Image 的大区块都装在 .iw-body 里（PDF 的直接挂在 surface 上），
   所以这里的 gap 必须等于 shared 的 --yqw-section-gap，否则两条线的
   纵向节奏还是两套（§12）。 */
.iw-body { display: flex; flex-direction: column; gap: var(--yqw-section-gap); }
/* 外壳被锁成"一个视口高"（见 image-workbench.js 的 fitGridToViewport）之后，
   多出来的空间要**落在对象区**上：空态给 dropzone，有图时给卡片网格。
   这样三个状态（空 / 一行 / 多行）外壳一样高，Export 那一排永远不动。
   ⚠️ `min-height: 0` 不能少 —— flex 子项的默认最小尺寸是内容高度，
   不写这一条，卡片多的时候网格会把外壳顶破而不是自己滚。 */
.iw--workspace .iw-body { flex: 1 1 auto; min-height: 0; }
/* ⚠️ 这里必须是 `min-height: 0`（Phase 16A2 定稿，两次反复之后的结论）。
   16A 曾给它加过下限，想消掉一条"溢出只有 2px 却出现 12px 宽滚动条"的幻影。
   16A2 把账算清楚了：
     · 幻影的触发条件极窄 —— 1280 宽下视口高 600→920 共 161 档里只有 **2 档**
       （h=838 / 840，约 4px 宽的一条带）。
     · 而那条下限用的是 `--iw-card-h`，它是 Workbench 渲染后**实测**写入的，
       卡片数一变列宽就变、卡高跟着变 —— 于是下限本身随状态浮动：
       1 张卡时 206px，9 张卡时 173–180px。实测 1366×768 / 1280×720 / 1024×600
       上 Export 与 Trust 因此漂移 **26–33px**。
   Founder 冻结的优先级是 **EXPORT_POSITION_STABILITY > CARD_ROW_PEEK_AESTHETIC**，
   所以两条下限（1.2 行的 peek 门限、以及这条 +2px）一起撤回，回到基线写法。
   ⚠️ `min-height: 0` 本身是必需的：flex 子项的默认最小尺寸是内容高度，
      不写这一条，卡片多的时候网格会把外壳顶破而不是自己滚。 */
.iw--workspace .iw-grid { flex: 1 1 auto; min-height: 0; }
.iw--workspace[data-yq-state="empty"] .yqw-dropzone { flex: 1 1 auto; }
/* ⚠️ 外层 inset 由 .yqw-surface 一处提供；这里再加一层就是 double inset（§7）。
   只对 workspace path 归零，legacy 消费者一个像素不动。 */
.iw--workspace .yq2-panel-body { padding: 0; }
/* 空态等高（见 workspace-ui.css 的 --yqw-empty-min）：Image 的 dropzone 隔着
   一层 .iw-body，所以这一层也要能被撑开，多出来的高度才落到 dropzone 上。 */


/* ⚠️ 空态体量与 dropzone 视觉也已收敛到 workspace-ui.css 的 .yqw-dropzone（§13–§16）。
   以前这里的 --iw-dropzone-min 会打败 shared contract，让同一个视口下
   Image 的空态明显比 PDF 矮 —— 那正是 Founder 说的"太扁"。
   `.iw--has-controls` 这一档同样退役：Profile Controls 现在住在 Advanced 里，
   空态根本没有它们，按"有没有 controls"分档已经没有对象。 */
.iw-progress { margin: calc(var(--yq2-sp-2) * -1) 0; }

/* 文件列表在窄高度下自己滚动，工具条与信任行始终可见 */
.iw .yq2-file-list { max-height: 340px; overflow-y: auto; scrollbar-gutter: stable; }

/* 缩略图是可点开查看器的按钮：继承 V2 的 file-thumb 外形，只补按钮语义 */
.iw-thumb { padding: 0; cursor: zoom-in; }
.iw-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.iw-thumb:focus-visible { outline: none; box-shadow: var(--yq2-focus-ring); }

@media (max-width: 640px) {
  .iw .yq2-file-list { max-height: 300px; }
}

/* ⚠️ Image Viewer 的样式已在 **V0.0.1247 搬进 assets/css/workspace-ui.css**：
   Founder 要求 PDF 的页卡预览"用同一个图片查看器"，于是它成了共享组件 ——
   组件样式就该住在共享组件表里，两条线各留一份才是真的会漂移。
   class 名一个字没改（`.viewer-*`），所以 Image 这边的外观逐值不变。 */

/* Profile Controls（Phase 4）——只做布局组合。
   input / select / label / hint 的视觉全部来自 Quiet UI V2，这里一律不重画。
   controls 为空的 Profile（WebP→PNG）整块 hidden，
   由 .yq2 [hidden]{display:none!important} 兜住，不会留下 gap。 */
/* ⚠️ Phase 19A1.2：这里原来还有一条 `.iw-controls { display: grid; … }`。
   本轮在文件末尾加的 flex 声明会**整条盖死**它（同选择器、后来者胜），
   留着只会让人以为字段行是 grid —— 我自己写 g81 时就照着它写了判据，
   结果 mutation 注在真正生效的那一条上，静态门禁没红。
   同选择器的第二份声明是**测试与人一起会读错**的东西，所以删掉，
   `.iw-controls` 从此在本文件里只声明一次（见文件末尾）。 */
/* ⚠️ Phase 19A1.1：profile controls 已从 Quiet UI V2（.yq2-*）收敛到
   Workspace 共享层（.yqw-field）。高度 / 边框 / 圆角全部来自
   workspace-ui.css 的 --yqw-h-select —— 这里**只管宽度**，不写第二份几何。 */
/* ⚠️ Phase 19A1.2：这里原来是 `.iw-controls .yqw-field { width: auto }`。
   那是 19A1.1 为了"别让字段满宽各占一行"加的，但它同时把字段交还给了
   **内容撑开** —— helper 文案因此成了宽度权威（en/vi 下 Background 比 zh 宽 90px）。
   现在宽度由共享层的 --yqw-field-w 统一给（一个确定值，既不满宽也不由文案决定），
   所以这条 override 必须**删掉**，否则它会盖住新的 authority。
   本文件从此不声明任何字段宽度。 */

/* 控件下面那行说明。PDF 那条线没有 hint，所以它是 Image 专属的组合层样式，
   不往共享组件表里加一个只有一个消费者的组件。 */
.iw-hint { font-size: var(--yqw-t4-size); line-height: 1.45; color: var(--yqw-text-faint); margin: 0; }
.iw-hint--error { color: var(--yq2-danger); }
/* 错误态由 aria-invalid 驱动（同一个事实同时管无障碍与视觉，不维护第二份状态）。 */
.iw-controls input[aria-invalid="true"] { border-color: var(--yq2-danger-border); }

/* ⚠️ Phase 19A1.2：原来这里有 `@media (max-width:560px) { .iw-controls {
   grid-template-columns: 1fr } }`，随上面那条 grid 一起失效。窄屏换单列现在是
   **派生结果**而不是第二条断点规则：workspace-ui.css 在 ≤560 把 .yqw-field 放成
   width:100%，flex 行自然每行一个。断点因此只写在一处。 */

/* ════════════════════════════════════════════════════════════════════
   Universal Image Workspace（Phase 7R-B1）

   ⚠️ 全部规则都挂在 `.iw--workspace` 下。legacy 的三个 public intent 页
   **不带这个 modifier**，所以 row 高度 / dropzone / toolbar / 排版
   一个像素都不会变（g22 有逐像素回归）。

   视觉纪律沿用 Quiet UI：compact、precise、quiet、desktop-grade。
   不做大卡片套大卡片、不给每行做巨大缩略图、不做彩色格式图标、
   不把每个输出格式做成卡片选择器。
   ════════════════════════════════════════════════════════════════════ */

/* ══ Phase 17C1：Images 区高度档 1× / 2× / 4× ═══════════════════════════
   Founder 要的是"一屏看到更多行"，所以改的是**容器高度**，
   卡片宽度 / 宽高比 / 列数 / 缩略图尺寸 / 行距一个字都不动。

   ⚠️ 为什么不直接复用 PDF 的 `.pw-hscale`：那条规则住在 pdf-workbench.css，
      Image 页根本不加载它。把它提到共享层是"为了 DRY 大改 visual system"，
      而且会让 g73 守的 PDF 视觉契约跟着动 —— 执行令 §9 明确允许
      "保持 Image 自己 selector，只复用 token/尺寸"。所以这里是同一套
      `.yqw-btn--mini` + `aria-pressed` + 同一组令牌，只是选择器归 Image。
   ⚠️ 数字是语言中立的（1× / 2× / 4×），按钮上没有 data-i18n；
      能读出来的名字走 aria-label（见模板），文字与无障碍名字刻意分工。 */
.iw-hscale { display: inline-flex; align-items: center; }
.iw-hscale .yqw-btn--mini { padding: 0 9px; font-variant-numeric: tabular-nums; }
.iw-hscale .yqw-btn--mini + .yqw-btn--mini { margin-left: -1px; }
.iw-hscale .yqw-btn--mini:not(:first-child):not(:last-child) { border-radius: 0; }
.iw-hscale .yqw-btn--mini:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.iw-hscale .yqw-btn--mini:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; }
/* 选中态与卡片同源（`.iw-card[aria-selected]` 用的就是 --yq-primary）；
   `position/z-index` 让选中的那一段压在相邻边框之上，否则左边那条会被后一个按钮盖掉。
   ⚠️ 别引用不存在的令牌 —— PDF 那轮写过 `--yq-accent`，tokens.css 里没有，
      CSS 会静默退化成继承值，看起来"选中态没生效"。
   ⚠️ 写成**单行**是有意的：g52 的零回归判据是逐行比对，
      "每一行新增都必须带 `.iw-hscale`"是它最强的形式；
      拆成多行会让续行认不出归属，只能把断言放宽 —— 那是更差的交换。 */
.iw-hscale .yqw-btn--mini[aria-pressed="true"] { border-color: var(--yq-primary); color: var(--yq-primary); background: var(--yq-primary-weak); position: relative; z-index: 1; }

/* ══ Phase 10A3：对象区从"横条列表"改成**固定尺寸的卡片网格** ══════════
   Founder 的判断：横条像日志，卡片像"我有这几张图"。而且卡片自己就是
   选择界面 —— 上传完即默认全选，没有"进入选择态"这一步。

   ⚠️ 关键约束（§2.4/§6.1）：**卡片尺寸基本稳定，变化的是每行几个**。
   所以列宽用 minmax(下限, 上限) 而不是 1fr —— 1fr 会让卡片随容器一起
   被拉宽拉窄，那正是 Founder 不要的。剩余空间留白，不摊到卡片上。 */
.iw-grid {
  display: grid;
  /* 卡片比上一版窄一档，并且**铺满容器宽度**：对象区现在是一个看得见的框，
     右边再留一条几十上百像素的空档就散了（格式塔：对象区与下面的 completion
     同宽、同边框、同圆角，看起来才是同一组东西）。
     ⚠️ `1fr` 在这里**不等于**"把卡片拉通"——列数仍由 auto-fill 按 148px 下限决定，
     所以卡片始终落在 ~155–170 这一档紧凑区间里，只是把那点余量摊进列宽把右边抹平。
     10A3 §6.1 要防的是"一行一张被拉满"，那条仍然成立。 */
  grid-template-columns: repeat(auto-fill, minmax(106px, 1fr));
  justify-content: start;
  /* ⚠️ 外壳锁高之后网格常常比内容高，而 grid 的 align-content 默认会把多余高度
     **摊给各行**——只放一张图时那张卡会被拉成半屏高（实测 582px）。
     行高必须按内容走，剩余空间留空。 */
  align-content: start;
  --iw-grid-gap: 12px;
  --iw-grid-pad: 12px;
  gap: var(--iw-grid-gap);
  margin: 0;
  /* 对象区是一个**看得见的容器**：与 completion 用同一套边框/圆角/底色，
     两块因此读起来是同一组东西，而不是"一堆卡片散在白底上"。 */
  border: 1px solid var(--yq-border);
  border-radius: var(--yq-r-card);
  background: var(--yqw-sunken);
  padding: var(--iw-grid-pad);
  /* 高度 = **2.2 行**：第三行露出一小截，用户一眼看得出"下面还有"，
     而整块工作区也因此能塞进 iframe 视口 —— 目标是**尽量不让 iframe 自己滚**
     （Founder：两层滚动很烦）。卡片同步缩到约 80%（列宽下限 132 → 106），
     一行能放更多张，滚动次数进一步减少。
     ⚠️ 行高不写死：--iw-card-h 由 Workbench 在渲染后**实测**第一张卡片写进来，
     这里只负责"2.2 个行距 − 尾部那个间距 + 上下内边距"的算式；
     量不到时回落到 160px。 */
  --iw-row-pitch: calc(var(--iw-card-h, 160px) + var(--iw-grid-gap));
  max-height: calc(2.2 * var(--iw-row-pitch) - var(--iw-grid-gap)
                   + 2 * var(--iw-grid-pad));
  overflow-y: auto;
  /* ⚠️ **不要**写 `overscroll-behavior: contain`：那条的字面意思就是
     "滚到头也不许把滚动传给外层"，实测就是滚轮停在卡片区里、整页不动 ——
     用户体感是卡住。默认的 auto 才有滚动链：卡片区到顶/到底之后，
     同一串滚轮继续滚外层页面。 */
  /* 滚动条的长相归共享组件层（.yqw-scroll，见 workspace-ui.css）：
     宽度、两侧间距、两端空档都在那里定义一次，这里只管"能滚"与"多高封顶"。 */
}

.iw-card {
  position: relative;
  display: flex; flex-direction: column;
  border: 1px solid var(--yq-border); border-radius: var(--yq-r-ctl);
  background: var(--yq-bg-page);
  padding: 8px;
  cursor: pointer;
  user-select: none;
}
.iw-card:hover { border-color: var(--yq-border-strong); }
/* 选中是**默认状态**（上传即全选），所以它必须安静：**一条 1px 蓝边**，
   不叠 inset ring。⚠️ 边框 + 内阴影会让选中态实际有 2px 粗，一屏几十张全选时
   整块界面被蓝框割裂 —— 默认状态不该这么吵（V0.0.1228 Founder 实测）。 */
.iw-card.is-selected { border-color: var(--yq-primary); box-shadow: none; }
.iw-card.is-failed { border-color: #FDE68A; background: #FFFBEB; }

/* 预览区固定比例，网格才不会被高矮不一的图撑歪 */
.iw-card-thumb { width: 100%; aspect-ratio: 4 / 3; background: var(--yq-bg-canvas);
                 border-radius: 6px; overflow: hidden;
                 display: flex; align-items: center; justify-content: center;
                 border: 0; padding: 0; cursor: zoom-in; }
.iw-card-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.iw-card-thumb:focus-visible { outline: 2px solid var(--yq-primary); outline-offset: 2px; }

.iw-card-name { font-size: 13px; line-height: 18px; font-weight: 550; color: var(--yq-text-1); margin-top: 8px;
                overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* metadata 明显弱于文件名（§6.2） */
.iw-card-meta { font-size: 12px; line-height: 16px; color: var(--yq-text-3); margin-top: 2px;
                overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 卡片状态（10A3-B PART D）：**三个稳定态各自看得出来**，
   未转换=中性弱、已转换=success、失败=danger。
   ⚠️ 这里只是 presentation mapping —— 底层仍是既有的
   ready / queued / processing / done / failed 那一套 meta.status，
   没有第二套状态机，也没有改 common.st_*（那是全站通用词表）。 */
.iw-card-badge { font-size: 12px; line-height: 16px; color: var(--yq-text-3); margin-top: 2px;
                 font-weight: 500; }
.iw-card-badge.is-converted { color: var(--yq-success); }
.iw-card-badge.is-failed    { color: var(--yq-danger); }
/* 失败由状态那一行的 danger 色表达；metadata 从此永远是来源信息（10A3-C §1），
   不再变色也不再让位给错误原因。 */

/* checkbox 是**默认可见**的：卡片自己就是选择界面（§2.5）。
   ⚠️ 热区四边各多 10px（10A3-C 先做了 5px，Founder 实测仍然偏小，
   V0.0.1225 加到 10px），靠外面这层 padding 实现 —— **不放大 checkbox 本体**。
   wrapper 的 top/left 相应各减同样的量，所以视觉方块仍然落在原来的
   10px/10px 上，卡片几何一个像素不变。 */
.iw-card-check-hit { position: absolute; top: 0; left: 0; padding: 10px; z-index: 2;
                     display: inline-flex; line-height: 0; cursor: pointer; }
.iw-card-check { position: static; width: 17px; height: 17px; margin: 0; display: block;
                 accent-color: var(--yq-primary); cursor: pointer; }

/* 末尾的「+」占位卡：与真实卡片**同尺寸**（网格由它自己决定列宽，所以只要
   同在网格里就天然一样宽），高度跟着行走。虚线边框表明它是入口不是内容。 */
.iw-add-tile { display: flex; align-items: center; justify-content: center; cursor: pointer;
               border: 1px dashed var(--yq-border-strong); border-radius: var(--yq-r-ctl);
               background: var(--yq-bg-sidebar); color: var(--yq-text-3);
               min-height: var(--iw-card-h, 180px); padding: 8px;
               transition: color var(--yq-dur) var(--yq-ease),
                           border-color var(--yq-dur) var(--yq-ease),
                           background var(--yq-dur) var(--yq-ease); }
.iw-add-tile:hover:not(:disabled) { color: var(--yq-primary);
                                    border-color: var(--yq-primary);
                                    background: var(--yq-primary-weak); }
.iw-add-tile:focus-visible { outline: 2px solid var(--yq-primary); outline-offset: 2px; }
.iw-add-tile:disabled { opacity: .5; cursor: not-allowed; }
.iw-card-add-plus { display: inline-flex; }
.iw-card-add-plus svg { width: 26px; height: 26px; }

/* 卡片右上角的删除按钮：**常驻**，不靠 hover 才出现（触屏上根本没有 hover）。
   尺寸与外形沿用原来那颗 ⋮（28×28、1px 描边、圆角 8），只是不再是二级菜单 ——
   这里从头到尾只有"移除"一个动作。 */
.iw-card-remove { position: absolute; top: 6px; right: 6px; width: 28px; height: 28px;
                  display: inline-flex; align-items: center; justify-content: center;
                  border: 1px solid var(--yq-border); border-radius: 8px; background: #fff;
                  color: var(--yq-text-3); cursor: pointer; padding: 0; z-index: 2;
                  transition: color var(--yq-dur) var(--yq-ease),
                              border-color var(--yq-dur) var(--yq-ease),
                              background var(--yq-dur) var(--yq-ease); }
.iw-card-remove svg { width: 15px; height: 15px; }
.iw-card-remove:hover { color: var(--yq-danger); border-color: var(--yq-danger);
                        background: var(--yq-danger-weak); }
.iw-card-remove:focus-visible { outline: 2px solid var(--yq-primary); outline-offset: 1px; }

/* 当前输出格式的可调项。**不是 Advanced 面板** —— 无折叠、无分类、无二级导航。 */
/* ⚠️ Phase 19A1.2：从 `flex-end` 改成 `flex-start`。
   字段现在有固定宽度，helper 会在字段内换行 —— 行数在不同 locale 下**会不一样**。
   底对齐时，helper 多一行就会把上面的控件顶上去，两个控件的顶边不再齐；
   顶对齐则把对齐锚点放在 label + 控件这一段（它们的高度是恒定的），
   helper 各自向下延伸，长短互不影响。
   ⚠️ 实测 9 个 locale 最长 label = 70px，远小于 --yqw-field-w(168px)，
      所以 label 不会换行 —— 顶对齐因此是稳的，不是碰巧。 */
.iw-controls { display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: flex-start; }

@media (max-width: 560px) {
  /* 极窄屏保 2 列：一列会让每张图占满整行，又变回"横条"的观感（§13）。 */
  .iw-grid { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
             --iw-grid-gap: 10px; --iw-grid-pad: 10px; }
  /* 窄屏视觉方块在 8/8，热区同样四边各 10px（-2 仍落在卡片 8px 内边距里，
     不会越出卡片边框）。 */
  .iw-card-check-hit { top: -2px; left: -2px; }
  .iw-card-check { width: 20px; height: 20px; }
}


/* ══ 10A3-B：Completion → 提示 → Trust 是同一组 ═══════════════════════
   Founder 要求 trust 紧贴 completion（约 15px），而 body 那一档是 24px。
   用 wrapper 承载更紧的内部间距，**不给 trust 写负 margin** ——
   负 margin 会随父级 gap 变化而失准，那正是 §33 要避免的叠加问题。 */
.iw--workspace .iw-close { display: flex; flex-direction: column; gap: 15px; }
/* 空态里这一组只剩 trust。PDF 那条线的 trust 自带 12px 上外边距，
   Image 为了"completion → trust 约 15px"把它归零了 —— 于是空态会比 PDF 矮一档。
   ⚠️ Founder 要求两个产品的容器高度一致，所以**只在空态**把这 12px 补回来：
   ready 态一个像素不动，15px 的贴合关系不受影响。 */
.iw--workspace[data-yq-state="empty"] .iw-close { margin-top: 12px; }
/* 同一组里不需要再画一条分割线（§31）。⚠️ 只作用于 Image：
   PDF 那条线的 trust 仍然保留 border-top。 */
/* 同一组里不需要再画一条分割线（10A3-B §31）。⚠️ 但**盒高要与 PDF 那条线一致**
   （V0.0.1230 Founder：两个产品的容器高度要一样）：PDF 的 trust 是
   1px 边框 + 12px 上内边距，这里用 13px 上内边距补齐同样的高度，
   只是那条线不画出来。元素自身的 top 不受内边距影响，所以 10A3-B 定的
   "completion → trust 约 15px" 一点没变。 */
.iw--workspace .yqw-trust { border-top: 0; padding-top: 13px; margin-top: 0; }

/* ══ 10A3-B：重复图片 banner ══════════════════════════════════════════
   viewport 顶部居中、非阻断、可手动关、3 秒后淡出。position:fixed 因此
   **不参与文档流**，Workspace 不会被它推下去（§10）。
   配色沿用共享层已有的 amber 档（notice-warn 的三个值），不发明新色。 */
.iw-banner { position: fixed; top: 12px; left: 50%; transform: translateX(-50%);
             z-index: 60; display: flex; align-items: center; gap: 10px;
             max-width: min(92vw, 520px);
             background: #FFFBEB; border: 1px solid #FDE68A; border-radius: 8px;
             box-shadow: 0 4px 14px rgba(15, 23, 42, .10);
             padding: 8px 8px 8px 14px; color: #92400E;
             font-size: 13px; line-height: 18px;
             opacity: 1; transition: opacity 200ms ease; }
.iw-banner.is-fading { opacity: 0; }
.iw-banner-text { min-width: 0; }
.iw-banner-close { flex: 0 0 auto; width: 26px; height: 26px; padding: 0;
                   display: inline-flex; align-items: center; justify-content: center;
                   background: transparent; border: 0; border-radius: 6px;
                   color: inherit; cursor: pointer; }
.iw-banner-close svg { width: 14px; height: 14px; }
.iw-banner-close:hover { background: #FEF3C7; }
.iw-banner-close:focus-visible { outline: 2px solid var(--yq-primary); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) {
  /* 动画可以不要，但**最终一定要消失**（§14）—— 所以这里只去掉过渡，
     不去掉那次隐藏。 */
  .iw-banner { transition: none; }
}
