@charset "UTF-8";
/* ==========================================================================
   JoySpeech · 全站风格族主题  theme-families.css
   --------------------------------------------------------------------------
   为什么单独开一个文件？
     全站原先把「配色」当成了「风格」—— 只换主色，字体 / 圆角 / 留白 / 阴影
     全都不变，所以换完还是同一副长相。现在改成三套**完整的设计语言**。
     实现方式：只覆盖 styles.css 里已经定义好的 --joy-* 令牌。
     ⚠️ 因此**完全不需要改动 54 万字节的 styles.css**（那是禁区，一改影响全站）。

   加载位置：
     必须排在 /static/styles.css **之后**。同权重靠"后来居上"取胜，
     再加上本文件用的是 html[data-theme="..."]（比 styles.css 的 :root 权重更高），
     双保险。

   三套风格：
     classic   A · JoySpeech 经典青   —— 刻意零覆盖，完全继承 :root（= 改造前的样子）
     magazine  B · 古典杂志风         —— 暖纸白 / 衬线 / 近直角 / 无阴影分层
     academic  C · 校园学术风         —— 护眼米灰 / 长行距 / 无阴影 / 大圆角胶囊

   夜览是**叠加维度**（html[data-night="true"]，见 styles.css 第 16124 行），
   本文件用 html[data-night="true"][data-theme="..."] 双属性选择器压过它。

   令牌使用频次（实测 styles.css，决定覆盖价值）：
     --joy-primary 774 次 · --joy-radius 279 次 · --joy-emerald 272 次
     --joy-border 108 次 · --joy-shadow 87 次 · --joy-surface 85 次
     --joy-foreground 74 次 · --joy-card 46 次 · --joy-font-sans 6 次
     --joy-leading 0 次（没人用 ⇒ 行距只能靠下面的显式规则）
   ========================================================================== */

/* ==========================================================================
   1. 自托管字体（OFL 授权，来自 Google Fonts，已本地化到 /static/fonts/）
   --------------------------------------------------------------------------
   为什么不用 Google CDN：国内访问不稳。只含 latin 子集；中文一律回退系统字体。
   ========================================================================== */
@font-face{font-family:'Fraunces';font-style:normal;font-weight:400 700;font-display:swap;src:url('/static/fonts/fraunces-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Literata';font-style:normal;font-weight:400 700;font-display:swap;src:url('/static/fonts/literata-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:300 700;font-display:swap;src:url('/static/fonts/outfit-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'Source Serif 4';font-style:normal;font-weight:400 700;font-display:swap;src:url('/static/fonts/source-serif-4-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}

/* ==========================================================================
   1.5 译文专用字体令牌（派总 2026-09-18 第四轮 需求 3）
   --------------------------------------------------------------------------
   为什么需要单独一个令牌：
     杂志风 / 学术风各有一条 `html[data-theme="..."] p { font-family: 衬线栈 }`，
     它命中的是**所有 <p>**，译文的 <p class="transcript-translation"> 被一并改成衬线。
     派总要求译文恒定使用「经典青」那套字体，所以译文不能跟着风格族的正文走。
   ⚠️ 不能写 `var(--joy-font-sans)`：该令牌在 magazine / academic 下已被换成 'Outfit'，
      不是经典青的字体 ⇒ 写了等于没改。这里显式固定经典青的正文栈
      （＝ styles.css 第 148 行 body 的 font-family）。
   ========================================================================== */
:root {
  --joy-font-translation: "Inter", "PingFang SC", "Noto Sans SC", "Microsoft YaHei", system-ui, -apple-system, sans-serif;
}

/* ==========================================================================
   2. A · JoySpeech 经典青  （data-theme="classic"）
   --------------------------------------------------------------------------
   ⚠️ 刻意**不写任何变量覆盖**。
   这样 data-theme="classic" 时全部令牌继承 :root 的原始定义
   ＝ 与改造前 100% 一致，等于给"不想折腾"的用户留了一个零风险的默认值。
   ========================================================================== */
html[data-theme="classic"] { /* 有意留空：见上方说明 */ }

/* ==========================================================================
   3. B · 古典杂志风  magazine
   --------------------------------------------------------------------------
   暖纸白底 + 大衬线标题 + 收窄正文 + 近乎直角 + 卡片不用阴影（靠边框与底色分层）
   取值来自派总已确认的样板 .theme-b，一比一保真。
   ========================================================================== */
html[data-theme="magazine"] {
  /* ---- 纸面与文字 ---- */
  --joy-background: #FBFAF7;
  --joy-card: #FBFAF7;
  --joy-card-foreground: #1A1714;
  --joy-surface: #FBFAF7;
  --joy-surface-2: #F5F2EB;
  --joy-surface-3: #EFE9DC;
  --joy-muted: #F5F2EB;
  --joy-foreground: #1A1714;
  --joy-muted-foreground: #5C5449;
  --joy-border: #E3DCD0;
  --joy-input: #CFC5B4;

  /* ---- 中性阶：把系统默认的冷灰整条改成暖灰（纸感的关键） ---- */
  --joy-neutral-0: #FFFFFF;
  --joy-neutral-50: #FBFAF7;
  --joy-neutral-100: #F5F2EB;
  --joy-neutral-200: #E3DCD0;
  --joy-neutral-300: #CFC5B4;
  --joy-neutral-400: #A99C88;
  --joy-neutral-500: #8C8377;
  --joy-neutral-600: #5C5449;
  --joy-neutral-700: #3E3830;
  --joy-neutral-800: #2A251E;
  --joy-neutral-900: #1A1714;
  --joy-neutral-950: #0F0D0B;

  /* ---- 品牌色：深青绿（墨色感）+ 暖米点缀 ----
     ⚠️ --joy-primary-soft / -glow / -06…-50 / --joy-state-info / --blue
        这些在 :root 里是用 var(--joy-primary) 派生的，会自动跟随，不必重写。 */
  --joy-primary: #0F766E;
  --joy-primary-light: #14B8A6;
  --joy-primary-dark: #0B5A54;
  --joy-primary-foreground: #FFFFFF;

  /* ---- 品牌色阶：:root 里是硬编码的青色阶，不会跟随 ⇒ 必须重算 ----
     用 color-mix 从主色派生，保证与主色永远同宗同调。 */
  --joy-emerald-50:  color-mix(in srgb, #0F766E 6%, #FFFFFF);
  --joy-emerald-100: color-mix(in srgb, #0F766E 13%, #FFFFFF);
  --joy-emerald-200: color-mix(in srgb, #0F766E 26%, #FFFFFF);
  --joy-emerald-300: color-mix(in srgb, #0F766E 42%, #FFFFFF);
  --joy-emerald-400: color-mix(in srgb, #0F766E 62%, #FFFFFF);
  --joy-emerald-500: color-mix(in srgb, #0F766E 86%, #FFFFFF);
  --joy-emerald-600: #0F766E;
  --joy-emerald-700: #0B5A54;
  --joy-emerald-800: color-mix(in srgb, #0F766E 84%, #000000);
  --joy-emerald-900: color-mix(in srgb, #0F766E 66%, #000000);
  --joy-emerald-950: color-mix(in srgb, #0F766E 42%, #000000);

  --joy-ring: #14B8A6;

  /* ---- 圆角：近乎直角（杂志的硬朗感）---- */
  --joy-radius-sm: 2px;
  --joy-radius: 2px;
  --joy-radius-md: 2px;
  --joy-radius-lg: 2px;
  --joy-radius-xl: 2px;
  --joy-radius-2xl: 2px;
  /* --joy-radius-full 保持 9999px（头像、圆点还需要） */

  /* ---- 阴影：卡片一律不要阴影，靠 1px 边框分层。
         只给 2xl（模态框）留一点，否则弹窗会"浮不起来"。 ---- */
  --joy-shadow-xs: none;
  --joy-shadow-sm: none;
  --joy-shadow-md: none;
  --joy-shadow-lg: none;
  --joy-shadow-xl: none;
  --joy-shadow-2xl: 0 20px 50px -12px rgba(26, 23, 20, 0.18);
  --joy-shadow-primary: none;
  --joy-shadow-primary-lg: none;

  /* ---- 字体与行距 ---- */
  --joy-font-sans: 'Outfit', system-ui, "PingFang SC", "Microsoft YaHei", sans-serif;
  --joy-leading-tight: 1.25;
  --joy-leading-normal: 1.62;
  --joy-leading-relaxed: 1.82;
}

/* UI 骨架用 Outfit（无衬线），正文改用衬线 —— 这是"杂志感"的来源 */
html[data-theme="magazine"] body,
html[data-theme="magazine"] button,
html[data-theme="magazine"] input,
html[data-theme="magazine"] select,
html[data-theme="magazine"] textarea {
  font-family: var(--joy-font-sans);
}
html[data-theme="magazine"] p,
html[data-theme="magazine"] li,
html[data-theme="magazine"] blockquote,
html[data-theme="magazine"] .article-body {
  font-family: 'Source Serif 4', Georgia, "Songti SC", "SimSun", "Noto Serif SC", serif;
  line-height: 1.82;
}
html[data-theme="magazine"] h1,
html[data-theme="magazine"] h2,
html[data-theme="magazine"] h3,
html[data-theme="magazine"] h4 {
  font-family: 'Fraunces', Georgia, "Songti SC", "SimSun", "Noto Serif SC", serif;
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* ==========================================================================
   4. C · 校园学术风  academic
   --------------------------------------------------------------------------
   护眼米灰底 + 无边框无阴影 + 超长行距 + 大圆角（小元件做胶囊）+ 衬线正文
   取值来自派总已确认的样板 .theme-c，一比一保真。
   ========================================================================== */
html[data-theme="academic"] {
  /* ---- 纸面与文字（偏绿灰的护眼米）---- */
  --joy-background: #EEF1EC;
  --joy-card: #F6F8F3;
  --joy-card-foreground: #1E2620;
  --joy-surface: #F6F8F3;
  --joy-surface-2: #E7EBE4;
  --joy-surface-3: #DFEDE7;
  --joy-muted: #E7EBE4;
  --joy-foreground: #1E2620;
  --joy-muted-foreground: #5A665C;
  --joy-border: #DCE2D8;
  --joy-input: #C8D0C4;

  /* ---- 中性阶：整条改成偏绿的灰 ---- */
  --joy-neutral-0: #FFFFFF;
  --joy-neutral-50: #F6F8F3;
  --joy-neutral-100: #EEF1EC;
  --joy-neutral-200: #DCE2D8;
  --joy-neutral-300: #C8D0C4;
  --joy-neutral-400: #A3AFA6;
  --joy-neutral-500: #8B978C;
  --joy-neutral-600: #5A665C;
  --joy-neutral-700: #3D4A41;
  --joy-neutral-800: #2A342D;
  --joy-neutral-900: #1E2620;
  --joy-neutral-950: #121814;

  /* ---- 品牌色：学院墨绿 ---- */
  --joy-primary: #1F7A6B;
  --joy-primary-light: #3F8E7C;
  --joy-primary-dark: #155C50;
  --joy-primary-foreground: #FFFFFF;

  /* ---- 品牌色阶 ---- */
  --joy-emerald-50:  color-mix(in srgb, #1F7A6B 6%, #FFFFFF);
  --joy-emerald-100: #DFEDE7;
  --joy-emerald-200: #C2DCD4;
  --joy-emerald-300: #9BC5B9;
  --joy-emerald-400: #6FA89A;
  --joy-emerald-500: #3F8E7C;
  --joy-emerald-600: #1F7A6B;
  --joy-emerald-700: #155C50;
  --joy-emerald-800: color-mix(in srgb, #1F7A6B 84%, #000000);
  --joy-emerald-900: color-mix(in srgb, #1F7A6B 66%, #000000);
  --joy-emerald-950: color-mix(in srgb, #1F7A6B 42%, #000000);

  --joy-ring: #3F8E7C;

  /* ---- 圆角：大元件圆润，小元件直接做胶囊（学术风的柔和感）---- */
  --joy-radius-sm: 9999px;
  --joy-radius: 18px;
  --joy-radius-md: 18px;
  --joy-radius-lg: 20px;
  --joy-radius-xl: 24px;
  --joy-radius-2xl: 28px;

  /* ---- 阴影：一律不要，纯留白 + 底色分层 ---- */
  --joy-shadow-xs: none;
  --joy-shadow-sm: none;
  --joy-shadow-md: none;
  --joy-shadow-lg: none;
  --joy-shadow-xl: none;
  --joy-shadow-2xl: 0 18px 44px -14px rgba(30, 38, 32, 0.16);
  --joy-shadow-primary: none;
  --joy-shadow-primary-lg: none;

  /* ---- 字体与行距（长行距 = 读起来最舒服）---- */
  --joy-font-sans: 'Outfit', system-ui, "PingFang SC", "Microsoft YaHei", sans-serif;
  --joy-leading-tight: 1.3;
  --joy-leading-normal: 1.7;
  --joy-leading-relaxed: 1.95;
}

html[data-theme="academic"] body,
html[data-theme="academic"] button,
html[data-theme="academic"] input,
html[data-theme="academic"] select,
html[data-theme="academic"] textarea {
  font-family: var(--joy-font-sans);
}
html[data-theme="academic"] p,
html[data-theme="academic"] li,
html[data-theme="academic"] blockquote,
html[data-theme="academic"] .article-body {
  font-family: 'Literata', Georgia, "Songti SC", "SimSun", "Noto Serif SC", serif;
  line-height: 1.95;
}
html[data-theme="academic"] h1,
html[data-theme="academic"] h2,
html[data-theme="academic"] h3,
html[data-theme="academic"] h4 {
  font-family: 'Literata', Georgia, "Songti SC", "SimSun", "Noto Serif SC", serif;
  font-weight: 600;
  letter-spacing: -0.005em;
}

/* --------------------------------------------------------------------------
   译文不受风格族「正文衬线体」影响（派总 2026-09-18 第四轮 需求 3 / 4）
   --------------------------------------------------------------------------
   需求 3：杂志风 / 学术风下的译文字体 = 「经典青」同款（无衬线 Inter 栈）。
   需求 4：译文颜色跟随本风格主色 --joy-primary，不再用写死的青绿
           （styles.css 是 #008B8B，己方 #059669；在暖纸底 / 米灰底上不搭）。

   权重说明：本组 (0,2,1) 与 (0,4,0) 高于 styles.css 的
     .transcript-translation (0,1,0) 与 .transcript-entry.self-speaker .transcript-translation (0,3,0)，
     且本文件后加载 ⇒ 覆盖生效。

   ⚠️ 为什么这几条必须带 `!important`：
      styles.css 第 20559 行有一条 `.realtime-translation { color: #008B8B !important; }`
      （实时气泡的译文）。普通声明压不过 `!important`，不加 `!important` 的话
      **实时阶段**的译文会一直是写死的青绿，只有定稿后才跟着风格走 —— 半截生效最难查。
   ⚠️ 只覆盖 magazine / academic 两套。classic 按本文件约定保持零覆盖
      （它本来就跑在这套字体与这组颜色上，无需重写）。
   ⚠️ 行距一并写回 1.6：magazine 的 `p` 规则带进来 1.82、academic 带进来 1.95，
      那是给正文长段落设计的；套在会议气泡内的短句上会散得不像一句话。
   ⚠️ 颜色由 --joy-primary 派生 ⇒ 夜览（html[data-night] 下主色变浅）自动跟随，不用另写规则。
   ⚠️ 己方/他人仍保留层级：他人＝主色柔化，己方＝主色纯色 + 字重 600。
   ⚠️ 权重校验（实测过 computed style，不是靠推算）：
      他人译文 (0,2,1)+important > styles.css 的 (0,1,0)+important ✅
      己方译文 (0,4,1)+important > 上一条 ✅（实时气泡也带 self-speaker，一并覆盖）
   -------------------------------------------------------------------------- */
html[data-theme="magazine"] .transcript-translation,
html[data-theme="academic"] .transcript-translation {
  font-family: var(--joy-font-translation);
  line-height: 1.6;
  color: color-mix(in srgb, var(--joy-primary) 82%, var(--joy-muted-foreground)) !important;
}
html[data-theme="magazine"] .transcript-entry.self-speaker .transcript-translation,
html[data-theme="academic"] .transcript-entry.self-speaker .transcript-translation {
  color: var(--joy-primary) !important;
  font-weight: 600;
  border-top-color: color-mix(in srgb, var(--joy-primary) 28%, transparent);
}

/* ==========================================================================
   5. 夜览叠加（html[data-night="true"]，与风格正交）
   --------------------------------------------------------------------------
   styles.css 第 16124 行用 html[data-night="true"]（属性选择器 ×1）覆盖了一整套
   深色令牌。本文件用 html[data-night="true"][data-theme="..."]（属性选择器 ×2）
   压过它，只改回「纸面质感 + 主色」，中性阶沿用深色版本即可。
   取值来自派总已确认的样板 body.night.theme-b / .theme-c。
   ========================================================================== */
html[data-night="true"][data-theme="magazine"] {
  --joy-background: #151310;
  --joy-card: #151310;
  --joy-card-foreground: #EDE8DE;
  --joy-surface: #151310;
  --joy-surface-2: #1D1A15;
  --joy-surface-3: #262119;
  --joy-muted: #1D1A15;
  --joy-foreground: #EDE8DE;
  --joy-muted-foreground: #9A9186;
  --joy-border: #2A2620;
  --joy-input: #3A342B;
  --joy-primary: #5FBFAE;
  --joy-primary-light: #7ED4C4;
  --joy-primary-dark: #3E9C8C;
  --joy-primary-foreground: #0F0D0B;
  --joy-ring: #5FBFAE;
  /* 深色纸面上不该再有投影 */
  --joy-shadow-xs: none;
  --joy-shadow-sm: none;
  --joy-shadow-md: none;
  --joy-shadow-lg: none;
  --joy-shadow-xl: none;
}

html[data-night="true"][data-theme="academic"] {
  --joy-background: #101512;
  --joy-card: #161C18;
  --joy-card-foreground: #E6EDE7;
  --joy-surface: #161C18;
  --joy-surface-2: #1B221D;
  --joy-surface-3: #16241F;
  --joy-muted: #1B221D;
  --joy-foreground: #E6EDE7;
  --joy-muted-foreground: #9AAAA1;
  --joy-border: #26302A;
  --joy-input: #334038;
  --joy-primary: #57B8A0;
  --joy-primary-light: #78CCB8;
  --joy-primary-dark: #3C917B;
  --joy-primary-foreground: #0C120F;
  --joy-ring: #57B8A0;
  --joy-shadow-xs: none;
  --joy-shadow-sm: none;
  --joy-shadow-md: none;
  --joy-shadow-lg: none;
  --joy-shadow-xl: none;
}

/* ==========================================================================
   风格选择器（原「调色盘」）· 重设计
   --------------------------------------------------------------------------
   这里一次解决两件事：
   ① 视觉 —— 旧版是「白底圆球 + 灰底下拉」，颜色全部硬编码
      （#fff / rgba(0,0,0,…) / #333），所以 A/B/C 三套风格下它都是同一副灰脸。
      现在整段改用 --joy-* 令牌 ⇒ 三风格与夜览全部自动适配。
   ② 交互 —— 「点一下就自己跑」的根因在 site-common.js（onDragStart 里
      无条件把 right 改成 auto，已修）。这里再撤掉 styles.css 中
      :hover/:active 的 transform: scale()：缩放在拖拽语境下会被误读成「在跑」。

   ⚠️ 本段依旧不修改 styles.css 一个字节：
      同权重 + 排在 styles.css 之后 ⇒ 后来居上覆盖。
   ========================================================================== */

/* ---- 浮层阴影 ----
   styles.css 的 --joy-shadow-* 在杂志/学术风里已被整条置为 none（扁平语言），
   但悬浮在最上层的小面板总需要一点分离感，故给调色盘单配一套。 */
html {
  --jp-float: 0 12px 32px -10px rgba(0, 0, 0, 0.18), 0 2px 8px -2px rgba(0, 0, 0, 0.08);
  --jp-btn-shadow: 0 2px 10px -3px rgba(0, 0, 0, 0.16);
}
html[data-theme="magazine"] {
  --jp-float: 0 16px 36px -16px rgba(26, 23, 20, 0.3), 0 2px 6px -2px rgba(26, 23, 20, 0.08);
  --jp-btn-shadow: 0 2px 8px -3px rgba(26, 23, 20, 0.22);
}
html[data-theme="academic"] {
  --jp-float: 0 16px 36px -16px rgba(30, 38, 32, 0.26), 0 2px 6px -2px rgba(30, 38, 32, 0.08);
  --jp-btn-shadow: 0 2px 8px -3px rgba(30, 38, 32, 0.2);
}
html[data-night="true"] {
  --jp-float: 0 18px 44px -14px rgba(0, 0, 0, 0.62), 0 2px 8px -2px rgba(0, 0, 0, 0.45);
  --jp-btn-shadow: 0 2px 12px -3px rgba(0, 0, 0, 0.55);
}

/* ---- 容器：默认固定右上角，可拖拽 ---- */
.theme-palette {
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: var(--joy-z-max);
  font-family: var(--joy-font-sans);
}

/* ---- 触发按钮：一颗「当前主色的小徽章」 ---- */
.theme-palette-btn {
  width: 40px;
  height: 40px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--joy-card);
  color: var(--joy-primary);
  border: 1px solid var(--joy-border);
  border-radius: var(--joy-radius-full);
  box-shadow: var(--jp-btn-shadow);
  cursor: grab;
  position: relative;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
  transition:
    background var(--joy-transition-fast),
    border-color var(--joy-transition-fast),
    color var(--joy-transition-fast),
    box-shadow var(--joy-transition-fast);
}

/* ⚠️ 状态反馈刻意【不用 transform】。
   旧版 :hover→scale(1.08) / :active→scale(0.95)，与拖拽时写 left/top 叠加，
   极易被看成「按钮自己跑了一下」。改用「底色 + 描边 + 光晕」表达。 */
.theme-palette-btn:hover,
.theme-palette-btn:focus,
.theme-palette-btn:active {
  transform: none;
}
.theme-palette-btn:hover {
  background: var(--joy-primary-soft);
  border-color: var(--joy-primary);
  box-shadow: 0 0 0 4px var(--joy-primary-10), var(--jp-btn-shadow);
}
.theme-palette-btn:active {
  background: var(--joy-primary-10);
  border-color: var(--joy-primary);
  cursor: grabbing;
}
.theme-palette-btn:focus-visible {
  outline: 2px solid var(--joy-primary);
  outline-offset: 2px;
}
.theme-palette-btn svg {
  display: block;
  pointer-events: none;
}

/* ---- 下拉面板：卡片式，靠 1px 边框立轮廓（不靠阴影） ---- */
.theme-palette-dropdown {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 292px;
  max-width: calc(100vw - 24px);
  max-height: 62vh;
  overflow-y: auto;
  padding: 8px;
  display: none;
  flex-direction: column;
  gap: 2px;
  background: var(--joy-card);
  color: var(--joy-foreground);
  border: 1px solid var(--joy-border);
  border-radius: var(--joy-radius-lg);
  box-shadow: var(--jp-float);
  transform-origin: top right;
}
.theme-palette-dropdown.show {
  display: flex;
  animation: jp-dropdown-in 170ms cubic-bezier(0.34, 1.4, 0.64, 1);
}

/* 靠近屏幕边缘时由 JS 加类翻转展开方向，避免面板被裁掉 */
.theme-palette-dropdown.drop-up {
  top: auto;
  bottom: calc(100% + 10px);
  transform-origin: bottom right;
}
.theme-palette-dropdown.drop-left {
  right: auto;
  left: 0;
  transform-origin: top left;
}
.theme-palette-dropdown.drop-up.drop-left {
  transform-origin: bottom left;
}

@keyframes jp-dropdown-in {
  from {
    opacity: 0;
    transform: translateY(-6px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@media (prefers-reduced-motion: reduce) {
  .theme-palette-dropdown.show {
    animation: none;
  }
}

/* ---- 选项行 ---- */
.theme-palette-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  background: transparent;
  color: var(--joy-foreground);
  border: 1px solid transparent;
  border-radius: var(--joy-radius-md);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background var(--joy-transition-fast),
    border-color var(--joy-transition-fast),
    color var(--joy-transition-fast);
}
.theme-palette-item:hover {
  background: var(--joy-primary-soft);
  color: var(--joy-primary);
}
.theme-palette-item.active {
  background: var(--joy-primary-soft);
  border-color: var(--joy-primary-30);
  color: var(--joy-primary);
  font-weight: 700;
}
html[data-night="true"] .theme-palette-item.active {
  border-color: var(--joy-primary-50);
}
.theme-palette-item .theme-name {
  flex: 1 1 auto;
  white-space: nowrap;
}
.theme-palette-item .theme-check {
  flex: 0 0 auto;
  color: var(--joy-primary);
}

/* ---- 色板圆点：改用内阴影取代原来的白色描边 ----
   （纯白描边在杂志风的米白纸面上完全看不出来） */
.theme-swatch {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  border-radius: var(--joy-radius-full);
  box-shadow:
    0 0 0 1px var(--joy-border),
    inset 0 0 0 2px var(--joy-card);
}

/* ---- 兼容保留：分隔线与锁标（黑金下线后已无锁，留着防止漏出旧硬编码色） ---- */
.theme-palette-divider {
  height: 1px;
  margin: 4px 0;
  background: var(--joy-border);
}
.theme-palette-item .theme-lock {
  margin-left: auto;
  font-size: 11px;
  color: var(--joy-muted-foreground);
}

/* ==========================================================================
   面板分区标题 + 语言选择区（2026-09-16 语言选择器并入同一个悬浮球）
   --------------------------------------------------------------------------
   语言 20 项，单列会把面板撑得很长 ⇒ 两列网格。
   语言名一律显示「母语原名」（English / 日本語 / العربية），
   这是通用做法：切错了也能凭母语名找回来。
   全部沿用 --joy-* 令牌 ⇒ A/B/C 三风格 + 夜览自动适配。
   ========================================================================== */

.theme-panel-title {
  margin: 0;
  padding: 5px 10px 6px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--joy-muted-foreground);
}

.theme-lang-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
}

.theme-lang-item {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 7px 8px;
  background: transparent;
  color: var(--joy-foreground);
  border: 1px solid transparent;
  border-radius: var(--joy-radius-md);
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background var(--joy-transition-fast),
    border-color var(--joy-transition-fast),
    color var(--joy-transition-fast);
}
.theme-lang-item:hover {
  background: var(--joy-primary-soft);
  color: var(--joy-primary);
}
.theme-lang-item.active {
  background: var(--joy-primary-soft);
  border-color: var(--joy-primary-30);
  color: var(--joy-primary);
  font-weight: 700;
}
html[data-night="true"] .theme-lang-item.active {
  border-color: var(--joy-primary-50);
}

.theme-lang-item .theme-lang-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.theme-lang-item .theme-check {
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  color: var(--joy-primary);
}

/* 窄屏：面板宽度交给 max-width 限制，语言改回单列免得挤成两行 */
@media (max-width: 420px) {
  .theme-lang-grid {
    grid-template-columns: 1fr;
  }
}

/* RTL（阿拉伯语）：面板锚点跟着换一侧，勾标与色板顺序镜像 */
html[dir="rtl"] .theme-palette-dropdown {
  right: auto;
  left: 0;
  transform-origin: top left;
}
html[dir="rtl"] .theme-lang-item,
html[dir="rtl"] .theme-palette-item {
  text-align: right;
}

/* ==========================================================================
   修复：顶部「测试阶段横幅」压住了固定的站点头部（2026-09-17）
   --------------------------------------------------------------------------
   现象：页面停在最顶端时，右上角一排按钮（注册 / 登录 / 开始使用 /
         个人中心 / 退出 / 我的消息）点不动。
   根因：.site-header 是 position:fixed; top:0; height:64px; z-index:1000，
         而 .site-testing-banner 在**正常文档流**里从 y=0 开始、z-index:9999，
         层级更高 ⇒ 横幅盖在头部上方 46px 高度上。
         （横幅是后期加的，加的时候头部还没变固定，所以两处都没错，凑一起才错。）
   修法：把横幅下移一个头部高度。横幅仍在文档流里，滚动时照旧跟着走。
   ⚠️ 原定义在 styles.css（禁区文件，不直接改），故在此覆盖。
   ========================================================================== */
.site-testing-banner {
  margin-top: 64px;
}
