/*
  Memora 字幕侧边栏。

  排版是这个面板的全部价值：用户在**边看视频边扫字幕**，眼睛只有余光给这一列。
  所以三条规矩：
    1. 当前句必须一眼可辨 —— 整行换底 + 左侧色条 + 加粗，而不是只换个颜色。
    2. 非当前句不加粗，但正文仍用主文字色 —— 它们是内容，不是装饰。
    3. 行距给足（1.62）。字幕是口语断句，密排会糊成一片。

  面板只有 ~400px 宽，所以层级靠**底色和留白**拉开，不靠边框 —— 一条 400px 宽的
  横线在这个尺度上就是一道疤。全文件只有三处 1px 线：抬头下沿、分隔线、提问框
  外框，它们都是「两块东西的交界」，不是装饰。
*/

/* ---------- 设计变量 ---------- */

:root {
  /*
    不要写 `color-scheme`。Chrome 侧边栏会按它给整份文档铺一层不透明 Canvas，
    html/body 设 transparent 也透不出去 —— 开发页没有这块底，真侧边栏就有。
    深浅色只靠下面的 `prefers-color-scheme` 媒体查询翻令牌。
  */

  /* 卡片自己的白。页面底是透明的（见 html/body），不要再用这层给整页铺色。 */
  --bg: #ffffff;
  --bg-soft: #f8fafc;
  --bg-raised: #ffffff;

  /* 字：正文 → 次要 → 几乎只是占位（时间码、脚注）。 */
  --ink: #151c2c;
  --ink-soft: #465269;
  --ink-faint: #687386;

  --line: #e1e6ef;
  --line-soft: #edf1f6;

  /*
    品牌蓝 —— **和视频页的悬浮按钮、站点 CTA 是同一个值**（`content.css` 的
    #0188fe、`app/globals.css` 的 --blue-500「取自 logo 的海豚蓝」）。

    `--accent-deep` 刻意和 `--accent` **同色**：几处主色按钮写的是
    `linear-gradient(..., var(--accent), var(--accent-deep))`，同色就渲染成纯色 ——
    悬浮按钮是纯色的，面板里的按钮没有理由更花。想要一点立体感的话改这一个令牌
    就够（比如 #0b6fc9），五处渐变一起变，不用逐个去改。

    ⚠️ 别再换成别的蓝。0.5 开发期间这里被换成过 #2d7ff9 + #135cc5 渐变，结果
    插件内部出现三套蓝（悬浮按钮一套、侧边栏一套、popup 一套），用户一眼就看出来
    「这里怎么比别处深」。
  */
  --accent: #0188fe;
  --accent-ink: #0b6fc9;
  --accent-soft: #eaf4ff;
  --accent-line: #b8dcff;
  --accent-deep: #0188fe;

  --radius: 14px;
  --radius-sm: 10px;
  --shadow-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 4px 12px rgba(15, 23, 42, 0.05);
  --shadow-2: 0 6px 24px rgba(15, 23, 42, 0.16);
}

@media (prefers-color-scheme: dark) {
  :root {
    /*
      深色卡片面。页面底同样透明，不垫更深的一层，否则卡片四周又会露一圈框。
    */
    --bg: #1a2230;
    --bg-soft: #131a26;
    --bg-raised: #1a2230;

    --ink: #e6edf3;
    --ink-soft: #a4afbf;
    --ink-faint: #8390a2;

    --line: #232b36;
    --line-soft: #1b222c;

    /* 深色档同样是品牌蓝提亮，deep 依旧同色（见浅色块的说明）。 */
    --accent: #4aa3ff;
    --accent-ink: #8cc4ff;
    --accent-soft: #12243a;
    --accent-line: #27405c;
    --accent-deep: #4aa3ff;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 12px rgba(0, 0, 0, 0.3);
    --shadow-2: 0 6px 24px rgba(0, 0, 0, 0.55);
  }
}

* {
  box-sizing: border-box;
}

/*
  作者样式里的 display 会盖掉 UA 样式表的 `[hidden] { display: none }`。本文件的
  .composer / .selection 都写了 display: flex —— 于是 `el.xxx.hidden = true` 完全
  失效，提问框和选中动作条会永远浮在底部、叠在一起（0.5 的显示 bug）。
  这一条兜住所有用 hidden 属性控制显隐的元素，别删。
*/
[hidden] {
  display: none !important;
}

/*
  面板是一个**定高的应用外壳**，不是一篇会一直长下去的文档：抬头固定、字幕区自己
  滚、底部条固定。body 没有高度约束的话，几百句字幕会把文档撑到上万像素、整页一起
  滚 —— 那是 0.5 的另一个 bug。
*/
html {
  height: 100%;
  background: transparent;
}

body {
  margin: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: 400 14px/1.62 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'PingFang SC', 'Microsoft YaHei', sans-serif;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--accent-soft);
  color: var(--ink);
}

/* 滚动条：窄面板里默认那根太重，压成一条几乎看不见的细线。 */
#lines::-webkit-scrollbar,
#chat::-webkit-scrollbar {
  width: 8px;
}

#lines::-webkit-scrollbar-thumb,
#chat::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  border-radius: 999px;
  background: var(--line);
  background-clip: content-box;
}

#lines:hover::-webkit-scrollbar-thumb,
#chat:hover::-webkit-scrollbar-thumb {
  background: var(--ink-faint);
  background-clip: content-box;
}

/* ---------- 抬头 ---------- */

header {
  flex: none;
  z-index: 2;
  padding: 13px 14px 10px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.title {
  font-weight: 600;
  font-size: 13.5px;
  line-height: 1.42;
  letter-spacing: -0.01em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 5px;
  color: var(--ink-faint);
  font-size: 12px;
}

.meta a {
  margin-left: auto;
  flex: none;
  color: var(--accent);
  text-decoration: none;
  cursor: pointer;
}

.meta a:hover {
  text-decoration: underline;
}

.tools {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 11px;
}

/*
  开关型 chip。未按下是「安静的轮廓」，按下是「实心的浅色块」——
  两者的差别必须比「换个字色」更强，否则在余光里根本看不出哪个开着。
*/
.chip {
  flex: none;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.chip:hover {
  border-color: var(--accent-line);
  color: var(--ink);
}

.chip[aria-pressed='true'] {
  border-color: transparent;
  background: var(--accent-soft);
  color: var(--accent-ink);
}

/* 语言开关不是「开/关」，是「切到另一种」—— 所以不用按下态，给它等宽字面。 */
#lang {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/*
  ⚠️ 选择器必须是 `.chip.reload-chip`（两个类），不能只写 `.reload-chip`。

  文件后面还有一段 `.chip { padding: 5px 11px }` 的主题覆盖 —— 同为单类选择器，
  后来者胜，会把这里的 `padding: 0` 盖掉。于是 30px 的方钮只剩 8px 的内容宽度，
  18px 的图标被压成 6×18 的一条。加一个类提高优先级，谁先谁后都不影响。
*/
.chip.reload-chip {
  display: inline-flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.chip.reload-chip svg {
  /* flex 子项默认可收缩 —— 不锁住的话外层一挤它就变形。 */
  flex: none;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- 字幕 / 对话：上下两块滚动区 ---------- */

/*
  高度完全由 flex-grow 的比值决定（flex-basis 是 0）—— 拖分隔线就是在改这两个
  变量，不用算像素、不用管窗口多高。抬头/分隔线/动作条/提问框都是 flex: none，
  先扣掉它们，剩下的才按比例分。

  ⚠️ 收起一半时，活着的那半必须拿 1（见 sidepanel.js 的 applySplit）：flex-grow
  的和小于 1 时浏览器只分配「和」那么多比例的剩余空间，剩下的空着。

  min-height: 88px 一条管两件事 —— 让它真的能收缩（flex 子项默认 min-height: auto，
  内容再高也不收缩，overflow 就永远不触发），同时给拖动一个地板。
*/
#lines,
#chat {
  min-height: 88px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

#lines {
  flex: var(--split-lines, 1) 1 0;
  padding: 6px 8px;
}

#chat {
  flex: var(--split-chat, 1) 1 0;
  padding: 12px;
  background: var(--bg-soft);
}

/*
  底部留白：最后一句也能滚到视线中间。

  ⚠️ 必须是**内容**（::after），不能是 padding-bottom。#lines 是 flex-basis: 0 的
  flex 子项，而一个盒子再怎么收缩也不可能小于它自己的 padding —— 写成
  padding-bottom: 40vh 等于给这一栏加了个高度地板，分屏比例直接失灵。
  50% 相对 #lines 自己的高度，拖完分隔线留白自动跟着变。
*/
#lines::after {
  content: '';
  display: block;
  height: 50%;
}

/* ---------- 字幕行 ---------- */

.line {
  position: relative;
  display: flex;
  gap: 10px;
  width: 100%;
  padding: 7px 10px 7px 8px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.line:hover {
  background: var(--line-soft);
  color: var(--ink);
}

/* 时间码：等宽数字，压到最淡 —— 它是坐标，不是内容。 */
.line .t {
  flex: none;
  width: 34px;
  padding-top: 2px;
  color: var(--ink-faint);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

.line .body {
  flex: 1;
  min-width: 0;
}

/* 译文：比原文小一号、淡一档，一眼能分出主次，又不至于读不动。 */
.line .tr {
  margin-top: 2px;
  color: var(--ink-faint);
  font-size: 12.5px;
  line-height: 1.5;
}

/* 双语开关只翻这个属性 —— 列表 DOM 不重建，高亮和滚动位置原样留着。 */
#lines[data-bilingual='false'] .tr {
  display: none;
}

/*
  当前句。三个信号叠加：整行换强调底色 + 左侧色条 + 正文加粗。
  只用其中一个都不够 —— 用户是**用余光**在扫这一列的。
*/
.line[data-current='true'] {
  background: var(--accent-soft);
  color: var(--ink);
  font-weight: 600;
}

.line[data-current='true']::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}

.line[data-current='true'] .t {
  color: var(--accent-ink);
}

.line[data-current='true'] .tr {
  color: var(--ink-soft);
  font-weight: 400;
}

/*
  选中的句子（可多选）。用**描边**，不用底色 —— 底色已经被「当前句」占了，
  两者经常同时落在一行上，必须是两个不打架的信号。
*/
.line[data-selected='true'] {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

/* ---------- 空状态 ---------- */

.empty {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 28px;
  color: var(--ink-soft);
  text-align: center;
}

.empty p {
  margin: 0 0 16px;
  max-width: 34ch;
  font-size: 13px;
  line-height: 1.72;
}

.empty button {
  padding: 9px 18px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow-1);
}

.empty button:hover {
  filter: brightness(1.06);
}

.empty .empty-reload {
  padding: 8px 16px;
  border: 1px solid var(--line);
  background: var(--bg-raised);
  color: var(--ink-soft);
  font-weight: 600;
  box-shadow: none;
}

.empty #empty-action:not([hidden]) + .empty-reload {
  margin-top: 8px;
}

.empty .empty-reload:hover {
  border-color: var(--accent-line);
  background: var(--accent-soft);
  color: var(--accent-ink);
  filter: none;
}

/*
  转圈。只在 showEmpty(..., spinning) 时出现 —— 「正在发生、等着就行」才配有它，
  错误状态不该转圈（转圈是在承诺它会好）。
*/
.empty[data-spinning='true']::before {
  content: '';
  display: block;
  width: 22px;
  height: 22px;
  margin: 0 0 16px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: memora-spin 0.8s linear infinite;
}

@keyframes memora-spin {
  to {
    transform: rotate(360deg);
  }
}

/* 别让转圈在「减少动态效果」的系统里一直快转。 */
@media (prefers-reduced-motion: reduce) {
  .empty[data-spinning='true']::before {
    animation-duration: 2.4s;
  }
}

/* ---------- 回到当前句 ---------- */

/* 唯一一个真正浮在内容之上的东西 —— 它是个瞬时提示，不该占版面。 */
/*
  「回到当前句」。

  贴在**字幕区的左上角**，不是浮在面板底部正中 —— 它管的是字幕那一栏的滚动位置，
  而底部正中是对话和提问框的地盘，一颗跟字幕有关的按钮浮在那里既挡输入又指错了地方。

  `top` 由 JS 在显示时按字幕区的实际位置算（抬头高度会随标题行数变），CSS 只定左边距。
*/
.resume {
  position: fixed;
  left: 12px;
  z-index: 4;
  padding: 7px 15px;
  border: 0;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow-2);
}

/* ---------- 收起来的那一条 ---------- */

/*
  分隔线拖到顶，字幕就收成这一条（点一下回到一半一半）。

  它**不是**一条写着「Captions」的把手。收起字幕不等于不想知道他在讲什么，只是
  不想让它占半屏 —— 所以这一条继续显示正在播的那一句，跟着播放走。一条只有标签的
  灰杠是纯占位；这一条在收起状态下仍然在干活。

  视觉上刻意跟展开时的「当前句」同源：左边同一根 3px 强调色条、同一套等宽时间码。
  用户不用重新学它是什么 —— 它就是那一行，被压成了一条。
*/
.collapsed-tab {
  flex: none;
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  /* 右边留出 chevron 的位置，否则长句子会盖到它底下。 */
  padding: 9px 32px 9px 14px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--accent-soft);
  color: var(--ink);
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
  transition: filter 0.12s ease;
}

.collapsed-tab:hover {
  filter: brightness(0.97);
}

@media (prefers-color-scheme: dark) {
  .collapsed-tab:hover {
    filter: brightness(1.25);
  }
}

/* 跟展开时当前句左边那根是同一根。 */
.collapsed-tab::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--accent);
}

.collapsed-tab .tab-icon {
  flex: none;
  display: flex;
  color: var(--accent-ink);
}

.collapsed-tab .tab-icon svg {
  width: 14px;
  height: 14px;
}

.collapsed-tab .t {
  flex: none;
  color: var(--accent-ink);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

/* 当前句本身 —— 一行，超了截断。它是这条的主角，所以用正文色不用次要色。 */
.collapsed-tab .tab-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 朝下的小箭头 —— 「点开会往下展」 */
.collapsed-tab::after {
  content: '';
  position: absolute;
  right: 14px;
  width: 5px;
  height: 5px;
  border-right: 1.5px solid var(--ink-faint);
  border-bottom: 1.5px solid var(--ink-faint);
  transform: translateY(-2px) rotate(45deg);
}

/* ---------- 分隔线 ---------- */

/*
  拖它改上下比例。视觉上只有一条 1px 的线，但热区是 11px —— 1px 的东西鼠标抓不住。
  抓手默认不画，鼠标靠近才浮出来：它是个每次会话按一两次的东西，常驻一根横杠
  只会把两块内容切得更碎。
*/
.split {
  flex: none;
  position: relative;
  height: 11px;
  cursor: row-resize;
  background: var(--bg);
}

.split::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 5px;
  height: 1px;
  background: var(--line);
}

.split::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 3px;
  width: 32px;
  height: 5px;
  margin-left: -16px;
  border-radius: 999px;
  background: var(--ink-faint);
  opacity: 0;
  transition: opacity 0.12s ease;
}

.split:hover::after,
.split:focus-visible::after,
.split[data-dragging='true']::after {
  opacity: 1;
}

.split[data-dragging='true']::after {
  background: var(--accent);
}

.split:focus-visible {
  outline: none;
}

/* 拖动时别让指针划过文字时选中一片蓝。 */
body[data-dragging='true'] {
  cursor: row-resize;
  user-select: none;
}

/* ---------- 对话 ---------- */

/* 下半屏还没有对话时，那句提示就是它的全部内容 —— 居中，不然像渲染坏了。 */
#chat[data-empty='true'] {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

#chat[data-empty='true'] .msg {
  max-width: 32ch;
  color: var(--ink-faint);
  font-size: 12.5px;
  line-height: 1.72;
}

.msg {
  margin-bottom: 14px;
}

.msg:last-child {
  margin-bottom: 0;
}

.msg .who {
  margin-bottom: 4px;
  color: var(--ink-faint);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* 提问靠右、成块 —— 一眼分出「我说的」和「它说的」，不用读内容。 */
.msg[data-role='user'] {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}

.msg[data-role='user'] .body {
  display: inline-block;
  max-width: 88%;
  padding: 8px 12px;
  border-radius: var(--radius) var(--radius) 3px var(--radius);
  background: var(--accent);
  color: #fff;
  text-align: left;
}

/* 回答是要读的，所以铺满、不加气泡 —— 气泡会把长文切成窄条。 */
.msg[data-role='assistant'] .body {
  color: var(--ink);
}

.msg .cite {
  margin-bottom: 6px;
  padding: 3px 0 3px 9px;
  border-left: 2px solid var(--accent-line);
  color: var(--ink-faint);
  font-size: 12px;
  line-height: 1.5;
  white-space: pre-line;
}

.msg[data-role='user'] .cite {
  max-width: 88%;
  text-align: left;
}

/* 回答里的时间出处：点了播放器跳过去。蓝的，因为能点（和字幕行的时间戳同一个意思）。 */
.msg .body .cite-time {
  margin: 0 2px;
  padding: 0 6px;
  border: 0;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font: inherit;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  line-height: 1.6;
  vertical-align: 1px;
  cursor: pointer;
}

.msg .body .cite-time:hover {
  color: var(--accent);
}

/* 「它读了哪里」—— 用户凭它判断这个回答有没有根据。 */
.msg .trace {
  margin-top: 6px;
  color: var(--ink-faint);
  font-size: 11px;
  line-height: 1.5;
}

.msg .actions {
  margin-top: 8px;
}

.msg .actions button {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.35;
  cursor: pointer;
}

.msg .actions button:hover:not(:disabled) {
  border-color: var(--accent-line);
  color: var(--accent-ink);
}

.msg .actions button:disabled {
  opacity: 0.55;
  cursor: default;
}

/* ---------- 选中一句之后的动作条 ---------- */

/*
  为什么是底部一条，而不是跟在被选中那一行后面：字幕列表是**一直在滚**的
  （跟随播放），行内按钮会跟着滚出屏幕，而用户点它的时候正是他停下来思考的时候。
  固定在底部，他找得到。
*/
.selection {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 10px 0;
  padding: 8px 10px;
  border: 1px solid var(--accent-line);
  border-radius: var(--radius);
  background: var(--accent-soft);
}

.selection span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-soft);
  font-size: 12px;
}

.selection button {
  flex: none;
  padding: 5px 11px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
  cursor: pointer;
}

.selection button:last-child {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  color: var(--ink-soft);
}

.selection .selection-copy {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--accent-line);
  background: var(--bg-raised);
  color: var(--accent-ink);
}

.selection-copy svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.selection-copy .check-icon {
  display: none;
}

.selection-copy[data-copied='true'] {
  border-color: color-mix(in srgb, #16a34a 40%, var(--line));
  background: color-mix(in srgb, #16a34a 10%, var(--bg-raised));
  color: #15803d;
}

.selection-copy[data-copied='true'] .copy-icon {
  display: none;
}

.selection-copy[data-copied='true'] .check-icon {
  display: block;
}

.selection button:disabled {
  opacity: 0.55;
  cursor: default;
}

/* ---------- 提问框 ---------- */

.composer {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 12px 12px;
  background: var(--bg);
}

.composer .quote {
  width: 100%;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 3px 0 3px 9px;
  border-left: 2px solid var(--accent);
  color: var(--ink-faint);
  font-size: 12px;
  line-height: 1.5;
}

.composer .quote-text {
  flex: 1;
  min-width: 0;
  /* 多选的引用是多行的（每行一句带时间码）—— 折三行封顶，别把提问框顶走。 */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: pre-line;
}

.quote-remove {
  flex: none;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: -2px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-faint);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.quote-remove:hover {
  background: var(--line-soft);
  color: var(--ink);
}

.quote-remove svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
}

/*
  输入框 + 发送键是一个整体：外框是 .composer-box，textarea 无边框铺满它，
  发送键绝对定位在右下角。做成一体是因为它俩在语义上就是一个控件 ——
  两个并排的独立方块会让人以为发送键管的是别的东西。
*/
.composer-box {
  position: relative;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-soft);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.composer-box:focus-within {
  border-color: var(--accent);
  background: var(--bg-raised);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.composer textarea {
  display: block;
  width: 100%;
  /* 默认三行起步，长问题不用挤在一条缝里；再长就自己滚。 */
  min-height: 76px;
  max-height: 180px;
  /* 右下角给发送键让位，否则文字会跑到它底下。 */
  padding: 10px 46px 10px 12px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink);
  font: inherit;
  resize: none;
  outline: none;
}

.composer textarea::placeholder {
  color: var(--ink-faint);
}

/* 回车图标：跟键盘上按的那个键长得一样，不用再写 Send。 */
.send {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: #fff;
  cursor: pointer;
  transition: opacity 0.12s ease, filter 0.12s ease;
}

.send svg {
  width: 15px;
  height: 15px;
}

.send:hover {
  filter: brightness(1.08);
}

.send:disabled {
  opacity: 0.45;
  cursor: default;
}

/* 输入框空着时发送键压下去 —— 不禁用（禁用了没法解释为什么），只是不抢眼。 */
.composer-box:not(:focus-within) .send[data-empty='true'] {
  opacity: 0.4;
}

/* ---------- 0.7 · 卡片层 ---------- */

/*
  这一层把面板从「三条通栏」改成「三张卡片」：视频身份一张、字幕一张、
  对话一张，中间用间隙分开。html/body 透明、无描边 —— 外壳不占一层，
  看起来就像三张卡直接铺在侧边栏上。

  为什么值得改：通栏布局靠 1px 分隔线划分区域，而这个面板只有 ~400px 宽 —— 一条
  400px 的横线在这个尺度上就是一道疤（文件开头那三条规矩里已经写过）。卡片用
  **留白 + 底色**划分，同一件事不用画线就说清楚了，而且「字幕是一块、对话是另一块」
  这个结构一眼可见，不用读内容去猜。

  卡片贴着侧边栏四边（--gutter: 0）：Chrome 侧边栏自己有一层底，再留一圈
  外边距就会读成「外面还有一个 div」。开发页没有那层底，所以那边看不出来。

  ⚠️ 这一层只改**外观**，不碰 flex / 滚动 / 分屏那套（--split-lines、
  #lines::after、[hidden] 那几条）—— 那些是反复踩坑验出来的，见上面各自的注释。
  卡片的外边距走 margin，不走 padding：#lines 是 flex-basis: 0 的伸缩项，
  盒子不可能小于自己的 padding，加 padding 等于给它焊一个高度地板。
*/

:root {
  /* 卡片离面板左右边各留多少。Chrome 侧边栏里必须是 0，否则那圈缝就是「外框」。 */
  --gutter: 0;
  --card-radius: 16px;
  --card-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 10px rgba(15, 23, 42, 0.035);

  /*
    双语图标。做成令牌是因为它要在 mask 里用两遍（-webkit- 前缀一遍、标准一遍），
    内联两份一模一样的 data URI 只会让下次改图标时漏掉一份。
    单引号包属性值、`<` `>` 转成 %3C %3E —— data URI 里出现裸的 `#` 或 `"` 都会
    把这条声明整个解析坏掉。
  */
  --icon-languages: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 8 6 6'/%3E%3Cpath d='m4 14 6-6 2-3'/%3E%3Cpath d='M2 5h12'/%3E%3Cpath d='M7 2h1'/%3E%3Cpath d='m22 22-5-10-5 10'/%3E%3Cpath d='M14 18h6'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: dark) {
  :root {
    --card-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 10px rgba(0, 0, 0, 0.22);
  }
}

body {
  background: transparent;
  letter-spacing: -0.005em;
}

/* ---------- 抬头卡片 ---------- */

header {
  margin: var(--gutter) var(--gutter) 0;
  padding: 15px 15px 13px;
  border: 0;
  border-radius: var(--card-radius);
  background: var(--bg-raised);
  box-shadow: var(--card-shadow);
}

.context-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 18px;
}

.context-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-faint);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

/* 实心圆点 —— 「这条是你现在正在看的那个」。 */
.live-dot {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}

.live-dot::after {
  content: '';
  position: absolute;
  inset: -3px;
  border: 1px solid var(--accent);
  border-radius: inherit;
  opacity: 0;
  animation: memora-live 2.2s ease-out infinite;
}

@keyframes memora-live {
  45% { opacity: 0.35; }
  100% { opacity: 0; transform: scale(1.7); }
}

.context-row a {
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.context-row a::after {
  content: '↗';
  margin-left: 4px;
  font-size: 11px;
}

.context-row a:hover {
  text-decoration: underline;
}

/*
  标题 + 时长并排一行，时长贴在**标题末尾那一行的右端**（`align-items: flex-end`）。

  为什么不把时长做成标题里的行内元素：`.title` 是 `-webkit-line-clamp: 2` 的截断盒，
  跟在文字后面的行内节点会连同第三行一起被裁掉 —— 标题一长，时长就无声地消失了。
  拆成两个 flex 子项，时长永远在，标题该截断照样截断。
*/
.title-row {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  margin-top: 9px;
}

.title {
  flex: 1;
  min-width: 0;
  margin-top: 0;
  color: var(--ink);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.02em;
}

/*
  抬头第二行只放**视频时长**（钟表图标 + 7:12）。

  这里以前还并排放着作者名 —— 拿掉了。用户是从这个视频的播放页点进来的，作者是谁
  他刚看过；而「这条要看多久」是他在决定「要不要现在读完这份字幕」时唯一用得上的
  数字。一行里塞两样，两样都会被扫过去。
*/
.meta {
  /* flex: none —— 时长不参与压缩，被挤掉的应该是标题（它自己会截断）。 */
  flex: none;
  display: flex;
  align-items: center;
  gap: 5px;
  /* 跟标题最后一行的基线对齐:标题行高 1.4×16=22.4，时长自己 17，差的补回去。 */
  margin-top: 0;
  padding-bottom: 3px;
  min-height: 17px;
  color: var(--ink-faint);
  font-size: 12.5px;
}

.meta .meta-icon {
  flex: none;
  display: flex;
  width: 14px;
  height: 14px;
}

.meta .meta-icon svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

#segment-count {
  flex: none;
  font-variant-numeric: tabular-nums;
}

/*
  ⚠️ 必须 wrap。四颗 chip 全是 flex: none，侧边栏被拖到 ~340px 以下时它们挤不进
  一行，最右那颗直接顶出面板、整个面板多一条横向滚动条（实测 340px 宽时
  scrollWidth 370）。

  折行之后靠 `.reload-chip { margin-left: auto }` 把工具那两颗推到第二行的右端 ——
  用的是 `.reload-chip { margin-left: auto }`，不是插一个 flex-grow 的空占位元素：
  auto 外边距在换行的 flex 里**逐行**结算，而占位元素的 flex-grow 只在它自己落到的
  那一行有效。而且占位元素本身也占一个 flex 槽位、多吃一份 gap —— 就那 8px，
  英文界面在 398px 宽时刚好挤不下、把「中文」挤到第二行。
*/
.tools {
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 13px;
}

/*
  两类 chip，形状一样、分量不一样：

    开关型（跟随播放 / 双语）—— 浅蓝底、蓝字、无描边。它们**当前是什么状态**是
      用户要一眼看到的，所以给足颜色。
    工具型（重载 / 语言）—— 白底细描边，推到右边。它们是「偶尔点一下」的东西，
      抢了颜色就会跟开关型混成一片。
*/
.chip {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 6px 13px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--ink-soft);
  font-size: 12.5px;
  font-weight: 600;
}

.chip:hover {
  background: var(--line-soft);
  color: var(--ink);
}

.chip[aria-pressed='true'] {
  border-color: transparent;
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: none;
}

.chip[aria-pressed='true']:hover {
  background: color-mix(in srgb, var(--accent-soft) 80%, var(--accent));
}

/* 实心三角 = 播放。跟播放器上那颗是同一个符号，不用再解释「跟随」是跟随什么。 */
#follow::before {
  content: '';
  flex: none;
  width: 0;
  height: 0;
  margin-right: 7px;
  border-style: solid;
  border-width: 4.5px 0 4.5px 7px;
  border-color: transparent transparent transparent currentColor;
}

#follow:disabled {
  opacity: 0.45;
  cursor: default;
}

/*
  双语开关的图标（一个「译」字符号）。

  ⚠️ 用 mask 而不是 background-image：图标要跟着 chip 的文字色走（未按下是灰的、
  按下是蓝的、深色档又换一套）。background-image 里的颜色是写死在那份 SVG 里的，
  换不了；mask 只取形状，颜色来自 `background: currentColor`。

  之所以不像别处那样用 <svg> 元素：这颗按钮的文案是 `textContent = t(...)` 写进去的
  （切语言时整颗重写），塞进去的子节点会被一起冲掉。放 CSS 里就不用去动那条逻辑。
*/
#bilingual::before {
  content: '';
  flex: none;
  width: 15px;
  height: 15px;
  margin-right: 7px;
  background: currentColor;
  -webkit-mask: var(--icon-languages) center / contain no-repeat;
  mask: var(--icon-languages) center / contain no-repeat;
}

/* 工具型那两颗：白底 + 描边，靠 reload 的 margin-left: auto 推到右边。 */
.chip.reload-chip,
#lang {
  border-color: var(--line);
  background: var(--bg-raised);
  color: var(--ink-soft);
}

.chip.reload-chip:hover,
#lang:hover {
  border-color: var(--accent-line);
  background: var(--accent-soft);
  color: var(--accent);
}

.chip.reload-chip {
  width: 32px;
  height: 32px;
  margin-left: auto;
}

#lang {
  min-width: 44px;
  padding-inline: 10px;
  font-weight: 700;
  justify-content: center;
}

/* ---------- 字幕卡片 ---------- */

/*
  字幕是**一张卡里的一列行**，不是一堆各自浮着的小块。

  行与行之间用一条贯通的细线分开，行本身不圆角、不留外边距 —— 这一列的阅读方式是
  「从上往下扫」，每行都做成独立的胶囊反而会把连续的一段话切成互不相干的碎片。
  唯一破例的是当前句：它必须从这一列里跳出来。

  border-radius + overflow-y: auto ——「卡片」和「滚动容器」是同一个元素，圆角会
  把滚到边上的行裁齐。
*/
#lines {
  margin: var(--gutter) var(--gutter) 0;
  padding: 0;
  border-radius: var(--card-radius);
  background: var(--bg-raised);
  box-shadow: var(--card-shadow);
  scroll-padding-block: 44%;
}

.line {
  gap: 12px;
  padding: 11px 14px;
  border-radius: 0;
  color: var(--ink);
  line-height: 1.55;
  transition: background 0.14s ease;
}

/* 分隔线画在「后一行的上边」，这样第一行顶到卡片边缘时不会多出一条。 */
.line + .line {
  margin-top: 0;
  box-shadow: inset 0 1px 0 var(--line-soft);
}

.line:hover {
  background: var(--bg-soft);
}

.line .t {
  width: 40px;
  padding-top: 1px;
  color: var(--ink-faint);
  font-size: 12.5px;
  font-weight: 500;
}

.line .body {
  font-size: 13.5px;
  font-weight: 500;
}

.line .tr {
  margin-top: 3px;
  color: var(--ink-faint);
  font-weight: 400;
  font-size: 12.5px;
}

/*
  当前句。浅蓝底 + 左边一根 3px 蓝条 + 正文加粗 —— 三个信号叠加，因为用户是**用
  余光**扫这一列的（见文件开头）。底色铺满整行、和上下行之间不留缝，它是这一列
  的一部分，不是浮在上面的另一个东西。
*/
.line[data-current='true'] {
  margin-block: 0;
  padding-block: 11px;
  background: var(--accent-soft);
  color: var(--ink);
  box-shadow: none;
}

.line[data-current='true'] + .line {
  box-shadow: none;
}

.line[data-current='true']::before {
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  border-radius: 0;
  box-shadow: none;
}

.line[data-current='true'] .t {
  color: var(--accent);
  font-weight: 600;
}

.line[data-current='true'] .body > div:first-child {
  font-weight: 700;
}

.line[data-current='true'] .tr {
  color: var(--ink-soft);
  font-weight: 400;
}

.line[data-selected='true'] {
  outline-width: 2px;
  outline-offset: -2px;
}

/* ---------- 分隔线（两张卡之间的缝） ---------- */

/*
  卡片布局之后，分隔线不再是「一条线」而是「两张卡之间的缝」—— 所以 ::before 那条
  1px 不画了，缝本身就是分界。

  但缝是看不出来能拖的，所以中间那颗小把手 **常驻**（opacity: 1），不再是 hover
  才浮现。它是这个面板里唯一一个「不点就不知道能拖」的交互，藏起来等于没有。
*/
.split {
  height: 14px;
  background: transparent;
}

.split::before {
  display: none;
}

.split::after {
  top: 4.5px;
  width: 34px;
  height: 5px;
  margin-left: -17px;
  border: 0;
  border-radius: 999px;
  background: var(--line);
  box-shadow: none;
  opacity: 1;
}

.split:hover::after,
.split:focus-visible::after,
.split[data-dragging='true']::after {
  background: var(--accent);
}

/* ---------- 对话卡片 ---------- */

/*
  对话这张卡刻意比字幕那张**偏蓝一点**，不是纯白：两张白卡叠在一起、中间只隔一条
  缝的话，会读成「一张卡被划了一道」。差一点点色温就够把它们分成两件东西。
*/
#chat {
  margin: 0 var(--gutter);
  padding: 16px 14px;
  /* 底下跟输入框拼成一块：底边直角，顶边还是卡的圆角。 */
  border-radius: var(--card-radius) var(--card-radius) 0 0;
  background: color-mix(in srgb, var(--accent-soft) 42%, var(--bg-raised));
  box-shadow: var(--card-shadow);
}

#chat[data-empty='true'] {
  align-items: center;
  justify-content: center;
}

/*
  ⚠️ 这个上限管的是**整块**，包括底下那三条起手式。原来是 360px —— 于是面板拖到
  460px 宽时，那一排起手式还是被夹在 360px 里，前两条明明放得下却硬是换了行。
  正文别读成长行是靠 `p` 自己的 `max-width: 28ch`，不该由外层代劳。
*/
.chat-welcome {
  width: 100%;
  max-width: 480px;
  margin: auto;
  color: var(--ink-soft);
  text-align: center;
}

.chat-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 14px;
}

.chat-mark img {
  display: block;
  width: 116px;
  height: auto;
  object-fit: contain;
}

.chat-welcome h2 {
  margin: 0 0 8px;
  color: var(--ink);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.02em;
}

.chat-welcome p {
  margin: 0 auto;
  max-width: 28ch;
  color: var(--ink-faint);
  font-size: 12.5px;
  line-height: 1.6;
}

/*
  三个起手式。白底卡片式按钮（不是全圆的胶囊）—— 它们承载的是一整句话，
  胶囊形在这个长度上会显得很松散。

  排布是**各自按内容宽、居中换行**：前两条并排一行，第三条落到第二行居中。
  没写死两列网格，也不让它们 `flex-grow` 撑满 —— 侧边栏的宽度是用户自己拖出来的，
  撑满会随宽度长出一片空白，只有内容宽才在任何宽度下都是紧的。

  ⚠️ 尺寸是**倒推出来的**，不是随手写的：字号 11.5px、左右内边距 10px、gap 6px、
  图标 15px —— 目标是「中文在 398px（侧边栏默认宽度）里前两条能并排」。
  任何一个数往上加，中文也会掉成三行。

  末尾原本还有一个 `›`，去掉了：它连 margin 值 36px，而实测英文前两条只剩 17px
  余量（350 可用 / 332.8 需要），加回来就又是三行。

  ⚠️ 一度以为「英文放不下要改文案」—— 那是被下面那条 `font` 简写的坑骗了：
  简写整条被丢，按钮一直按浏览器默认的 Arial 13.33px 排，比设计值宽了 ~20px。
  改成长写之后英文自然就并排了，一个字都不用改。**下次觉得「这排怎么放不下」，
  先去 DevTools 看一眼 computed font-size 是不是 13.3333px。**
*/
.quick-prompts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 16px;
}

.quick-prompts button {
  flex: 0 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-raised);
  color: var(--ink);
  /*
    ⚠️ 不能写 `font: 600 11.5px/1.3 inherit` 的简写。`inherit` 不是合法的字体族名，
    只能当**整条属性**的值（`font: inherit`）；混在简写里,整条声明会被当成语法错误
    丢掉 —— 按钮于是回落到浏览器默认的 Arial 13.33px/400，字号、字重、字体三样
    一起失效。这条坑了很久:起手式一直是按 13.33px Arial 排的,比设计值宽了 ~20px,
    英文两条并排差的那 17px 就是这么来的。本文件里同样的简写有 7 处，全改长写了。
  */
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.3;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
  transition: border-color 0.14s ease, color 0.14s ease, transform 0.14s ease,
    box-shadow 0.14s ease;
}

.quick-prompts .prompt-icon {
  flex: none;
  display: flex;
  color: var(--accent);
}

/* 实心图标：SVG 自己写的是 fill="currentColor"，这里只管尺寸。 */
.quick-prompts .prompt-icon svg {
  width: 15px;
  height: 15px;
}

.quick-prompts button:hover {
  border-color: var(--accent-line);
  box-shadow: 0 4px 12px rgba(1, 136, 254, 0.1);
  transform: translateY(-1px);
}

.msg {
  margin-bottom: 16px;
}

.msg .who {
  margin-bottom: 5px;
  font-size: 10px;
  letter-spacing: 0.07em;
}

.msg[data-role='user'] .body {
  max-width: 90%;
  padding: 9px 12px;
  border-radius: 14px 14px 4px 14px;
  background: var(--accent);
  box-shadow: 0 4px 12px rgba(1, 136, 254, 0.16);
}

.msg[data-role='assistant'] .body {
  padding: 11px 12px;
  border: 1px solid var(--line-soft);
  border-radius: 4px 14px 14px 14px;
  background: var(--bg-raised);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
}

/* ---------- 收起来那一条 ---------- */

/* 字幕收起时它顶替整张字幕卡，所以它自己也得是一张卡。 */
.collapsed-tab {
  margin: var(--gutter) var(--gutter) 0;
  padding: 11px 32px 11px 14px;
  border: 0;
  border-radius: var(--card-radius);
  /* 左边那根 3px 色条是 top/bottom 拉通的方块，不裁的话会戳出圆角外面。 */
  overflow: hidden;
  background: var(--accent-soft);
  box-shadow: var(--card-shadow);
}

.collapsed-tab .t {
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 600;
}

/* ---------- 选中动作条 ---------- */

.selection {
  z-index: 3;
  margin: var(--gutter) var(--gutter) 0;
  padding: 8px 9px 8px 11px;
  border-color: var(--accent-line);
  border-radius: var(--card-radius);
  background: var(--accent-soft);
  box-shadow: var(--card-shadow);
}

.selection button {
  background: var(--accent);
  font-weight: 600;
}

/* ---------- 提问框 ---------- */

/*
  提问框浮在页面底色上，不再是一条带上边线的底栏 —— 上面三块都是卡片了，它也得是。
  外层 .composer 只负责留出间距，卡片是里面的 .composer-box。

  跟对话区贴在一起：padding 0、顶边直角。左右/--gutter 仍然是 0，别加回外框。
*/
.composer {
  gap: 8px;
  padding: 0;
  border-top: 0;
  background: transparent;
  box-shadow: none;
}

.composer .quote {
  padding-inline: 9px 2px;
}

.composer-box {
  border-color: var(--line);
  border-radius: 0 0 var(--card-radius) var(--card-radius);
  background: var(--bg-raised);
  box-shadow: var(--card-shadow);
}

.composer-box:focus-within {
  border-color: var(--accent);
  background: var(--bg-raised);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.composer textarea {
  /* 两行起步。三行的话空状态那三个起手式会被顶出视野。 */
  min-height: 52px;
  max-height: 140px;
  padding: 15px 56px 15px 14px;
  border-radius: 0 0 var(--card-radius) var(--card-radius);
  font-size: 13px;
  line-height: 1.45;
}

/*
  发送键是**圆的**，不是圆角方块 —— 面板里所有方形的东西（卡片、起手式、chip）
  都是「容器」，只有它是「按下去会发生一件事」的那颗。形状上分开，不用靠颜色。
*/
.send {
  right: 9px;
  bottom: 9px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 3px 10px rgba(1, 136, 254, 0.28);
}

.send svg {
  width: 18px;
  height: 18px;
}

.send:hover {
  filter: brightness(1.08);
}

/* ---------- 回到当前句 ---------- */

/* left 跟着 --gutter 走，否则改一次边距它就贴在卡片边线上。 */
.resume {
  left: calc(var(--gutter) + 8px);
  padding: 8px 14px;
  background: var(--ink);
  color: var(--bg-raised);
  font-weight: 600;
  box-shadow: 0 8px 22px rgba(15, 23, 42, 0.22);
}

/* ---------- 空状态 ---------- */

.empty {
  margin: var(--gutter);
  border-radius: var(--card-radius);
  background: var(--bg-raised);
  box-shadow: var(--card-shadow);
}

.empty button {
  background: var(--accent);
  font-weight: 600;
  box-shadow: 0 3px 10px color-mix(in srgb, var(--accent) 24%, transparent);
}

.empty button:hover {
  filter: brightness(1.05);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--accent) 30%, transparent);
}

.empty .empty-reload {
  border-color: var(--line);
  background: var(--bg-raised);
  color: var(--ink-soft);
  font-weight: 600;
  box-shadow: none;
}

.empty .empty-reload:hover {
  border-color: var(--accent-line);
  background: var(--accent-soft);
  color: var(--accent);
  filter: none;
}

/* ---------- 窄面板 / 矮面板 ---------- */

@media (max-width: 360px) {
  /* 面板已经很窄了，内边距先让出去 —— 内容比留白重要。
     不要改 --gutter：Chrome 侧边栏里那圈外边距就是「外框」，窄了也不能加回来。 */
  header {
    padding-inline: 12px;
  }

  .line {
    padding-inline: 11px;
  }

  #chat {
    padding-inline: 11px;
  }

  .quick-prompts button:last-child {
    display: none;
  }
}

@media (max-height: 720px) {
  .chat-mark {
    display: none;
  }

  .chat-welcome h2 {
    margin-top: 0;
  }

  .quick-prompts {
    margin-top: 10px;
  }

  .quick-prompts button:last-child {
    display: none;
  }
}

/* ---------- 深色 ---------- */

/*
  ⚠️ 这一段必须留在文件**最后**：它覆盖的是上面刚定义的卡片规则，同优先级下
  后来者胜。往下加新规则的话，凡是深色档要改的，都得再往这里补一条。
*/
@media (prefers-color-scheme: dark) {
  /* 深色下卡片靠「比页面底更亮」浮起来，投影几乎看不见，所以描边补一道。 */
  header,
  #lines,
  #chat,
  .composer-box,
  .empty,
  .collapsed-tab {
    border: 1px solid var(--line);
  }

  .chip {
    background: color-mix(in srgb, var(--bg-soft) 70%, transparent);
  }

  .line + .line {
    box-shadow: inset 0 1px 0 var(--line);
  }

  .msg[data-role='user'] .body {
    box-shadow: none;
  }

  .quick-prompts button:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  }

  .send {
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
  }

  .resume {
    background: var(--bg-raised);
    color: var(--ink);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5);
  }
}

@media (prefers-reduced-motion: reduce) {
  .live-dot::after {
    animation: none;
  }

  .quick-prompts button,
  .line {
    transition: none;
  }
}
