/**
 * AI 回答里的分步执行（步骤化执行 / Plan-and-Execute）
 *
 * 气泡是一条**步骤流**：一步一块，块内依次是
 * 「步骤标题 → 过程 → 工具卡片 → 这一步产出的正文」。
 * **块内一切默认收着**（过程、工具卡片、正文），只有等待确认的那一步与计划最后一步跑完时
 * 自动展开（判定在 ai-steps.js 的 _shouldOpen）；待授权草稿卡片例外，它需要用户点头，常显。
 *
 * 视觉分寸的唯一原则：**过程弱、正文强**。标题行与过程区跟 .ai-tool-call 完全同构
 * （小字号、低透明度、可折叠），正文段则用与普通回答一模一样的排版——它就是答案本身，
 * 只是被切成了几段。两者之间靠一条细分隔线串起来，让用户看出「这几块是一串的」。
 *
 * ⚠️ **小字号只能加在过程那几个子元素上，不能加在 .ai-step-block 上**：
 * 正文段是块的子节点，加在块上它就得靠一个写死的字号把自己「调回去」，
 * 与气泡本身的 0.9375rem 迟早对不上。让它自然继承气泡的排版才是对的。
 *
 * 同理，`.ai-step-flow` 挂在 `.ai-message-content` **里面**（见 ai-steps.js）：
 * 那 60 多条 `.ai-message-content h1 / ol / table …` 是后代选择器，
 * 正文段挪到外面就一条都吃不到，用户看到的就是「模板格式全丢了」。
 *
 * 差别只有一处：**进行中的那一步要看得出来**，多步任务一跑好几分钟，
 * 用户需要一眼确认「它还在动」——标题最左侧（箭头的位置）转圈，箭头暂时让位。
 */

.ai-step-flow {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 4px;
}

.ai-step-block {
    color: var(--text-secondary, #6b7280);
}

.ai-step-toggle,
.ai-step-fold,
.ai-step-tools {
    font-size: 0.78rem;
}

.ai-step-block + .ai-step-block {
    border-top: 1px solid var(--border-color, rgba(120, 120, 128, 0.18));
    padding-top: 10px;
}

.ai-step--failed {
    color: #b91c1c;
}

[data-theme="dark"] .ai-step--failed,
html.dark .ai-step--failed {
    color: #fca5a5;
}

/* 停在这一步等用户确认：用强调色点出来，让人一眼看到「现在轮到我了」 */
.ai-step--awaiting .ai-step-toggle {
    opacity: 1;
    color: var(--kb-accent, var(--primary-color, #3b82f6));
}

/* 还没轮到的步骤（排在等待步之后、或已停止）：弱化，但不是失败 */
.ai-step--pending .ai-step-toggle {
    opacity: 0.5;
}

/* 正在跑的那一步稍微亮一点：多步任务要让用户看出「还在动」 */
.ai-step--running .ai-step-toggle {
    opacity: 1;
    color: var(--primary-color, #3b82f6);
}

.ai-step-toggle {
    width: 100%;
    min-height: 0;
    padding: 1px 0;
    border: none;
    background: transparent;
    color: inherit;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 6px;
    cursor: pointer;
    font-weight: 400;
    line-height: 1.5;
    text-align: left;
    opacity: 0.75;
    transition: opacity 0.15s ease;
}

.ai-step-toggle:hover {
    opacity: 1;
}

/* 与 .ai-tool-call-chevron 同理：锁死盒高再居中，吸收字形在 em 盒里的位置差异 */
.ai-step-chevron,
.ai-step-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 1.5em;
    line-height: 1;
    flex: 0 0 auto;
    font-size: 0.95em;
}

/*
 * 只有中间那个图标要下压，箭头保持行盒居中。
 *
 * align-items:center 对齐的是**行盒**，中文的墨迹中心并不落在行盒中心上，所以图标
 * 看着比文字高——补偿量随字体族变化，见 reading-theme.css。
 * 箭头不跟着动：它是个小而对称的字形，眼睛是拿它跟行的整体位置比，不是跟中文的
 * 墨迹重心比；一起下压反而会让箭头显得掉下去。
 */
.ai-step-icon {
    position: relative;
    top: var(--kb-icon-optical-shift, 0.06em);
}

.ai-step-chevron {
    transform: rotate(-90deg);
    transition: transform 0.15s ease;
}

/* 正在跑：最左侧转圈顶替箭头的位置（同一个盒），块仍可点开看进度 */
.ai-step-spinner {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 1.5em;
    line-height: 1;
    flex: 0 0 auto;
    font-size: 0.95em;
}

.ai-step--running > .ai-step-toggle .ai-step-chevron {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    .ai-step-spinner {
        animation: none;
    }
}

.ai-step--open > .ai-step-toggle .ai-step-chevron {
    transform: none;
}

.ai-step-title {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ai-step-duration {
    flex: 0 0 auto;
    opacity: 0.7;
    font-variant-numeric: tabular-nums;
}

/*
 * 块里的一切都跟着块一起收：过程区、思考区、工具卡片、本步正文。多步任务里十几张卡片
 * 与几段中间正文全铺开时，用户要往上翻很久才找得到最后那一步的答案；最后一步会自动展开
 * （ai-steps.js）。草稿卡片（.ai-step-drafts）刻意不收：它等着用户点「授权并保存」。
 */
.ai-step-block:not(.ai-step--open) > .ai-step-body,
.ai-step-block:not(.ai-step--open) > .ai-step-thinking,
.ai-step-block:not(.ai-step--open) > .ai-step-tools,
.ai-step-block:not(.ai-step--open) > .ai-step-content {
    display: none;
}

/*
 * 块内的二级折叠区（过程区 .ai-step-body / 思考区 .ai-step-thinking）：块展开后它们
 * **仍各自收着**，只露一行标题。汇报步的摘要就是整份答案的原文（几千字 Markdown 源码），
 * 思考比正文长几倍是常态——展开块是为了看结论，不该先被它们顶开一屏。
 * 标题行与步骤标题同构（小字、低透明度、箭头在前），正文区照气泡顶上的
 * .ai-reasoning-body 限高滚动，不然一步想了两千字就把整条步骤流撑走。
 */
.ai-step-fold {
    padding-left: 26px;
}

/* 过程区什么都没有（还没跑、没摘要、没旁白）时整块不占位，不再画一行「（无输出）」 */
.ai-step-fold--empty {
    display: none;
}

.ai-step-fold-toggle {
    min-height: 0;
    padding: 1px 0;
    border: none;
    background: transparent;
    color: inherit;
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-weight: 400;
    line-height: 1.5;
    opacity: 0.7;
    transition: opacity 0.15s ease;
}

.ai-step-fold-toggle:hover {
    opacity: 1;
}

.ai-step-fold-chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 1.5em;
    line-height: 1;
    flex: 0 0 auto;
    font-size: 0.95em;
    transform: rotate(-90deg);
    transition: transform 0.15s ease;
}

.ai-step-fold--open > .ai-step-fold-toggle .ai-step-fold-chevron {
    transform: none;
}

.ai-step-fold-body {
    display: none;
    margin: 2px 0 6px;
    padding-left: 20px;
    max-height: 190px;
    overflow-y: auto;
    overscroll-behavior: contain;
    word-break: break-word;
    line-height: 1.6;
}

.ai-step-fold--open > .ai-step-fold-body {
    display: block;
}

/* 思考文本比摘要再弱一档：它是模型的自言自语，不是执行记录 */
.ai-step-thinking > .ai-step-fold-body {
    white-space: pre-wrap;
    opacity: 0.6;
}

.ai-step-detail {
    white-space: pre-wrap;
    word-break: break-word;
    line-height: 1.6;
    opacity: 0.85;
}

.ai-step-detail--error {
    color: #b91c1c;
}

[data-theme="dark"] .ai-step-detail--error,
html.dark .ai-step-detail--error {
    color: #fca5a5;
}

/* 模型在这一步说的话。只活在本次会话里，刷新后不再有——所以比摘要更弱一档 */
.ai-step-aside {
    margin-top: 4px;
    white-space: pre-wrap;
    word-break: break-word;
    line-height: 1.6;
    opacity: 0.6;
}

.ai-step-tools {
    padding-left: 26px;
}

/*
 * 这一步产出的待授权草稿卡片。与 .ai-step-tools 同一档缩进（都对齐 .ai-step-body 的 26px），
 * 但排在正文之后：工具调用是过程，草稿是结论。
 */
.ai-step-drafts {
    padding-left: 26px;
}

/*
 * 步骤下挂的工具行，图标要比基础补偿再低一点点。
 *
 * 这半档纯粹是照着屏幕定的，没有度量依据：同一套规则在顶层的工具行（.ai-tool-panel 下）
 * 看着是正的，缩进到步骤里之后就显得偏高——参照物从「气泡左缘」换成了上一行的步骤标题，
 * 眼睛的判断跟着变了。所以只在这个嵌套位置补，别把它提到 .ai-tool-call-icon 上去。
 */
.ai-step-tools .ai-tool-call-icon {
    top: calc(var(--kb-icon-optical-shift, 0.06em) + 0.02em);
}

/**
 * 这一步产出的正文。
 *
 * 这里**不设字号、不设行高、不设颜色**：它就是用户要的答案，排版应当与普通回答完全一致，
 * 由 `.message-bubble` 与 `.ai-message-content …` 那套规则接管。写死任何一项都会让它
 * 和普通回答慢慢分叉。
 */
.ai-step-content {
    margin-top: 6px;
    word-break: break-word;
}

.ai-step-content > :first-child {
    margin-top: 0;
}

.ai-step-content > :last-child {
    margin-bottom: 0;
}
