    /* ═══════════════════════════════════════════════════════════════
       SPSSAU 品牌设计体系
       主色 #178AEC · 深海军蓝 #031E5F · 亮蓝底 #F3F9FE
       语义绿 #3AC258 · 点缀金/琥珀 · 中性灰 #1D1D1F/#666/#999
       扁平实底风格, 不使用渐变/光晕等装饰
       ═══════════════════════════════════════════════════════════════ */
    :root {
      /* 原生控件(滚动条/表单)的明暗跟着走。深色由 [data-theme="dark"] 显式指定, 这里给
         light 兜底 —— index.html 里那颗初始化脚本会在首帧前就把 data-theme 落到具体值,
         没脚本时仍按浅色渲染。 */
      color-scheme: light;
      --brand: #178AEC;
      /* SPSSAU 品牌蓝(全站主色) */
      --h-head: 56px;
      /* 左栏 LOGO 行(门头)的高度 */
      --rail-w: 300px;
      /* 提问定位条容器的宽度上限。定位条不占对话列的列宽 —— 它浮在正文右缘上, 见
         .qa-rail; 里头那张列表是按内容撑宽、右对齐的, 所以这条只是个上界, 展开到多宽
         由卡片自己定: 现在给文字的是 186px, 约 15 个汉字(见 .qa-t 的宽度预算)。
         改卡片宽度改那边那个数, 别改这条 —— 改这条不动任何看得见的东西。
         展开时会压住正文右缘一条 —— 它有白底和阴影, 这是设计里认下的代价 */
      --rail-gap: 6px;
      /* 定位条压在右缘, 对话列右侧留这么宽。原先 58 是给"那排刻度线"让的道 —— 刻度线
         已经不画了(入口改成一颗胶囊, 见 .qa-pill), 那道空档跟着作废: 留着它, 正文右缘
         就白窄 52px, 而那 52px 里什么也没有。
         收到 6 与 .chat 的左内边距同值: 消息卡片左右对称, 输入框右缘与卡片右缘仍是
         同一条线(见 .input-bar)。触屏上原先还有一条"还没提问时把 58 收回来"的例外
         (chat.css 里 :has(> .qa-rail[hidden])), 也一并删了 —— 现在没有要收回的东西。 */


      --brand-deep: #0E78D0;
      /* 悬停加深 */
      --navy: #031E5F;
      /* 品牌深海军蓝(标题/强调) */
      --brand-soft: #EAF4FE;
      /* 浅蓝底(选中/标签) */
      --bg-tint: #F3F9FE;
      /* 页面浅蓝底 */
      --green: #3AC258;
      --green-deep: #2BAF4B;
      --green-soft: #E9F9EE;
      --green-border: #C9EDD3;
      --amber: #E6A23C;
      --amber-soft: #FDF4E5;
      --amber-border: #F3DFAE;
      --red: #E6402F;
      --red-soft: #FEEFED;
      --red-border: #F7C7C1;
      --ink: #1D1D1F;
      /* 主文本 */
      --ink-2: #33404F;
      /* 次级文本(正文) */
      --muted: #566A82;
      /* 弱文本。原 #7A8CA3 对白底只有 3.44:1, 而它几乎全用在 11~13px 的小字上
         (状态/标签/用量行), 正文口径的 AA 要 4.5:1。压暗后: 白卡 5.56 / 页面底 5.24 / 浅块 4.88。 */
      --faint: #637183;
      /* 提示文本。原 #9FB0C4 只有 2.21:1, 同上压暗: 白卡 4.98 / 页面底 4.69。
         与 --muted 的层级改成靠两点拉开 —— 更亮一档(45% vs 42%)且更灰(饱和度 14% vs 20%);
         因为过了 4.5:1 这条线, 两个灰阶在浅底上已经拉不开更大的明度差了。
         另: .nav-resize::after 拿它当拖拽把手的底色(非文字), 顺带满足 3:1 的组件口径。 */
      --line: #E3EDF7;
      /* 常规分隔线 */
      --line-soft: #EAF1F9;
      --card: #ffffff;
      --shadow-sm: 0 1px 2px rgba(3, 30, 95, .05), 0 2px 8px rgba(3, 30, 95, .04);
      /* 浮层(下载菜单/坐标值/改名面板)投影: 深色下黑阴影贴在深卡上会消失, 故单独列一条
         加重; 浅色取原值 0 2px 8px rgba(0,0,0,.12)。 */
      --shadow-pop: 0 2px 8px rgba(0, 0, 0, .12);
      --ring: 0 0 0 3px rgba(23, 138, 236, .16);
      /* ── 皮肤第二层 ── 下面这批是组件里"比品牌 token 更细"的颜色, 原本散在 chat.css /
         data-panel.css 里当裸十六进制写死。收成变量不是图整齐: 深色模式下这些浅蓝/浅灰
         要整体反转, 不 token 化就得在每个组件里各写一段 [data-theme="dark"]。名字按
         "干什么用"取, 不按"是什么色"取。 */
      --card-2: #F6FAFD;
      /* 次浅底: 悬浮行 / 嵌套块 / 斑马纹里那层白里带蓝的底 */
      --card-3: #E9EFF7;
      /* 灰蓝底: 代码块 / 输入框 / 更压一档的嵌块 */
      --brand-tint: #D8E9FC;
      /* 蓝底(比 --brand-soft 深一档): 强调块 / 选中标签的实底 */
      --line-strong: #C6D9EF;
      /* 强调描边 / 滚动条滑块: 比 --line 更蓝更实, 给"要抓人眼"的边 */
      --ink-strong: #111827;
      /* 强文本: 代码 / 数字 / 最重的那一档字 */
      --navy-ink: #0E5C9E;
      /* 蓝色强调文字: 链接 / 表头可点的蓝字 */
      --ghost: #AEB8C4;
      /* 装饰浅灰: 段线 / 禁用占位那类"看得见但不抢戏"的灰 */
      --amber-deep: #9A6512;
      /* 琥珀深字: 角标/小字说明(底与边框已有 --amber-soft / --amber-border) */
      --hl-bg: #FFE08A;
      /* 搜索命中高亮底: 琥珀黄, 比 --amber-soft 深一档 —— 那层 #FDF4E5 贴在白卡上几乎看不见 */
      --hl-ink: #5B4300;
      /* 命中高亮字: 深棕压黄底, 两种皮肤都写死深字, 不再 color:inherit(深色下会继承成浅字) */
      --red-deep: #B42318;
      /* 红深字: 危险文案(底与边框已有 --red-soft / --red-border) */
      --overlay: rgba(255, 255, 255, .93);
      /* 半透明白罩: 吸顶条/遮罩那类"糊一层白盖住底下内容"的底, 深色下换成深罩 */
      --overlay-soft: rgba(255, 255, 255, .72);
      /* 更透一档的白罩: 上传投放区那种要"隐约透出底色"的落点 */
      --tip-bg: #1D1D1F;
      /* 气泡底(#tip / #toast): 白字压深底的通用做法, 两种皮肤下都保持"深底白字",
         所以不跟 --ink 走(那会在深色下反转成浅底), 这里单列一个恒深的量 */
      --mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
      --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
        "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    }

    /* ── 深色皮肤 ──
       整套变量只覆盖这一处, 由 <html data-theme="dark"> 触发; 浅色值见上面的 :root。
       只有浅色/深色两态(用户点哪颗就是哪颗, 不再跟随系统), CSS 只认两个确定的态。
       配色原则: 蓝黑底(不是纯黑)、文字往上提亮、品牌蓝在深底上再亮一档才稳过 4.5:1。 */
    [data-theme="dark"] {
      color-scheme: dark;
      --brand: #3D9BEC;
      --brand-deep: #6BB4F2;
      --navy: #DCE6F5;
      --brand-soft: #122A45;
      --brand-tint: #16334F;
      --bg-tint: #0D1421;
      --green: #3AC258;
      --green-deep: #4CCB6A;
      --green-soft: #12281A;
      --green-border: #1E412A;
      --amber: #E8A94A;
      --amber-soft: #2E2313;
      --amber-border: #4A3A1E;
      --amber-deep: #E0A84E;
      --hl-bg: #E8A94A;
      /* 命中高亮底: 深色下不能再靠 --amber-soft(#2E2313) —— 那层棕和页面底 #0D1421 分不开 */
      --hl-ink: #241A00;
      /* 命中高亮字: 深字压亮黄, 与浅色皮肤同一套"高亮笔"观感 */
      --red: #F0584A;
      --red-soft: #2E1714;
      --red-border: #4A251F;
      --red-deep: #F08078;
      --ink: #E8EDF5;
      --ink-2: #C6CEDB;
      --ink-strong: #F4F7FB;
      --muted: #98A4B8;
      --faint: #7E8BA0;
      --ghost: #55627A;
      --navy-ink: #6FB0EE;
      --line: #2A3547;
      --line-soft: #222B3A;
      --line-strong: #33425C;
      --card: #161E2C;
      --card-2: #131B28;
      --card-3: #1B2436;
      --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4), 0 2px 8px rgba(0, 0, 0, .3);
      --shadow-pop: 0 2px 12px rgba(0, 0, 0, .55);
      --ring: 0 0 0 3px rgba(61, 155, 236, .28);
      --overlay: rgba(22, 30, 44, .93);
      --overlay-soft: rgba(22, 30, 44, .72);
      --tip-bg: #2B3648;
    }

    /* ── 触屏: 命中区下限 ──
       44 是 Apple HIG 的数, 也是 Android 48dp 打八折 —— 取小的那条, 两边都不算失礼。
       定义在 media 里是因为它是个"有触摸屏才有"的量: 桌面读不到它, 也就不会用到它
       (用法见 chat.css / data-panel.css 里那批 ::after)。
       判据用 any-pointer 而不是 hover: 接了妙控键盘的 iPad 报 hover:hover, 但手指还在
       屏幕上, 这条得照样生效。而它只喂命中区、不喂外观, 所以落在带触摸屏的 Windows
       笔记本上也无害 —— 那台机器的桌面观感一个像素都不会动。 */
    @media (any-pointer: coarse) {
      :root {
        --tap: 44px;
      }
    }

    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    html,
    body {
      height: 100%;
    }

    /* ── 触屏按下的原生高亮: 全站关掉 ──
       手指按下去时浏览器会盖一层自己的高亮, 而它是个**不吃 border-radius 的矩形**:
       站内按钮多是胶囊(999px)与圆形(50%), 那一瞬间就是一块方角矩形压在椭圆上(全屏那颗
       最明显)。触屏上还更方 —— @media (any-pointer: coarse) 给这批按钮挂了一圈 44px 高的
       ::after 命中区(见 chat.css / viz-charts.js), 矩形比胶囊本身更大。
       .qa-pill 早先单独关过一次(chat.css), 但只关了那一颗; 这里升成全站口径。
       该属性**可继承**, 写在 html 上即覆盖所有后代(含 ::after 命中区), 不必逐个列;
       谁想单独找回原生高亮, 在自己那条规则里覆盖即可(继承不会盖掉自带声明)。
       按下反馈因此改由各按钮自己的 :active 担 —— 胶囊/圆形那批已补, 见 chat.css
       与 data-panel.css 里各自 :hover 旁边多出来的 :active。 */
    html {
      -webkit-tap-highlight-color: transparent;
    }

    body {
      font-family: var(--font);
      background: var(--bg-tint);
      color: var(--ink);
      font-size: 14px;
      display: flex;
      flex-direction: column;
      -webkit-font-smoothing: antialiased;
      text-rendering: optimizeLegibility;
    }

    ::selection {
      background: rgba(51, 190, 247, .28);
    }

    .container {
      position: relative;
      z-index: 1;
      width: 100%;
      /* 1080 是对话列的宽度, 末尾 40 是这个容器自己的左右内边距 —— 两截加在一起才是
         容器宽度, 整块仍然居中。少算那 40, 窗口再宽对话列也会差 40 到不了 1080。
         (原来这里还加一条 --rail-w 给右上角控件/定位条让位, 控件搬到左栏、定位条浮起
         之后就不必了: 宽窗口多出来的那截现在归绘图栏, 见 --viz-w / VIZ_W_MAX。) */
      max-width: calc(1080px + 40px);
      margin: 0 auto;
      flex: 1;
      /* flex 项默认 min-width:auto = 内容的 min-content, 会把容器顶到比可用空间还宽:
         一段不折行的长内容(宽表格、长串)就能把列撑出侧栏之外, 页面随之横向溢出。
         归零后容器才是真的"占满剩余空间", 超宽内容在自己的行内滚动。 */
      min-width: 0;
      display: flex;
      flex-direction: column;
      min-height: 0;
      padding: 0 20px;
    }

    /* ═══════════════════════════════════════════════════════════════
       触屏 / 平板适配 —— 下面几条都关在 media query 里:
       桌面(鼠标 + 宽窗口)读不到它们, 观感因此逐像素不变。
       全站只有两个判据, 别混用:
         (hover: none)        悬停是不是唯一通路 —— 担**所有看得见的**改动
         (any-pointer: coarse) 设备上有没有手指 —— 只担**隐形的**热区扩张
       分开是因为接了妙控键盘的 iPad 报 hover:hover, 若热区键在 hover 上, 带键盘的
       iPad 会留着 24px 的小按钮; 反过来带触摸屏的 Windows 笔记本 any-pointer 为真,
       那下面就不能有任何看得见的东西, 否则那台笔记本的桌面观感就破了。
       ═══════════════════════════════════════════════════════════════ */

    /* ── 视口高度 ──
       iOS 地址栏收起/展开会改可见高度, 而 height:100% 跟的是静态那一档 —— 地址栏一收,
       底下就空出一条, 输入框跟着往上跳一下。dvh 跟的是"此刻可见高度", 跳的是它自己,
       输入框钉在下沿不动。老于 iOS 15.4 的没有 dvh, 退回 -webkit-fill-available
       (那是 iOS 上"可见高度"的老写法), 认不得 dvh 的浏览器会丢掉后一条, 前一条留着。
       桌面两条都不写: 桌面没有会收起的地址栏, 100% 与 100dvh 在那儿本来就是同一个数。 */
    @media (hover: none) {

      html,
      body {
        height: -webkit-fill-available;
        height: 100dvh;
      }

      /* ── 长按出提示 ──
         [data-tip] 在触屏上靠长按弹气泡(见 index.html 的 initTip)。得先按掉 iOS 的
         "拷贝/共享"系统菜单, 否则长按 500ms 后两样一起冒出来, 谁也读不了。
         只关菜单, 不关 user-select: 有些 [data-tip] 元素里装的是要选中的正文
         (变量名、文件名)。 */
      [data-tip] {
        -webkit-touch-callout: none;
      }
    }

