/* ui.css — 控件库（组件层）。

   位置：theme.css（令牌）之后、各页样式之前，由 base.html 全站引入。
   全部规则放在 @layer ui 内。层的顺序在 theme.css 开头声明为
   「reset, ui」，未分层的规则（theme.css 其余部分、各页样式、skins.css）
   一律优先于层内规则，所以页面只写版式、皮肤只写差异时都不需要提高
   选择器优先级，也不需要 !important。

   命名：「控件族-外观」，按样子命名，不按功能或页面命名。
     btn-solid / btn-glass / btn-outline / btn-ghost / btn-icon     按钮（btn-icon.is-bare 无底圆钮）
     pill-soft / pill-outline / pill-solid                          胶囊（筛选、标签）
     surface-glass / surface-flat / surface-float / surface-aurora  面（L1 / L0 / L2 / 极光底）
     surface-smoke / on-dark                                        深色画面上的烟色玻璃条、控件令牌
     seg + seg-item + seg-thumb                                     分段切换
     field / field-glass                                            输入框
     switch / slider                                                开关、滑块
     menu-float + menu-item (+ menu-cols)                           弹出菜单
     pop-float                                                      锚定浮层（配合 surface-float）
     tip-float（由 [data-tip] 触发）                                工具提示
     tile-grid + tile-ghost / tile-flat                             图块（图标 + 名称 + 说明）
     scrim                                                          遮罩
     toast                                                          提示
     state / state-line                                             空态、错误、载入
     skel / skel-line / skel-circle / skel-block                    骨架
     badge-soft / badge-solid / badge-outline / badge-glass         徽标
     avatar-ring / avatar-round                                     头像
     list-divided + list-row                                        列表行
     title-star / eyebrow / kbd / spinner                           小件
     page-col                                                       内容列（版式）
   尺寸与状态统一写成 is-*：is-sm、is-md、is-lg、is-block、is-on、is-open、
   is-error、is-loading、is-end、is-ok、is-danger、is-warn。有语义的状态
   优先用属性：disabled、aria-pressed、aria-selected、aria-current、
   aria-invalid、aria-busy。

   行为不挂在这些类上。脚本用 id 或 data-* 找元素，换外观只改类名。

   组件令牌：每个组件读取自己的一组自定义属性（--btn-*、--pill-*、
   --surface-*、--field-* 等），缺省时取 theme.css 的全局令牌。组件令牌
   只以 var(--x, 缺省值) 的形式读取，层内不在元素上赋值，因此皮肤在
   html[data-skin="…"] 上写一次即可作用于全站同类控件。 */

@layer ui {

/* ═══ 内容列 ═════════════════════════════════════════════════════════
   页面外层的内容列，左右边线由列宽令牌决定，页头、筛选条、网格与卡片都
   贴这一对边线。列本身不带左右内边距，到视口边缘的距离由 .page-wrap 的
   --gutter 提供。
     .page-col             var(--w-page)，标准列
     .page-col.is-narrow   var(--w-narrow)，文字流为主的列
     .page-col.is-read     var(--w-read)，长文与居中单卡
   页面里的某一块需要贴同一对边线而不包一层时，直接写
   max-width: var(--w-page); margin-inline: auto。 */
.page-col {
  max-width: var(--w-page);
  margin-inline: auto;
  position: relative; z-index: 1;
}
.page-col.is-narrow { max-width: var(--w-narrow); }
.page-col.is-read   { max-width: var(--w-read); }

/* ═══ 按钮 ═══════════════════════════════════════════════════════════
   五种外观共用一组基础规则，外观只决定底色、描边、字色与投影。
   高度由内边距与行高得出（默认约 40，is-sm 约 30，is-lg 约 46），不写
   min-height：皮肤只改 padding 即可得到紧凑的按钮。 */
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost, .btn-icon) {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--btn-gap, 6px);
  padding: var(--btn-pad, 11px 20px);
  border-radius: var(--btn-r, var(--r-pill));
  border: var(--bw) solid var(--_b, transparent);
  background: var(--_bg, none);
  color: var(--_fg, var(--text2));
  box-shadow: var(--_sh, none);
  font-family: var(--btn-font, var(--font-sans));
  font-size: var(--btn-fs, var(--fs-md));
  font-weight: var(--_fw, 700);
  letter-spacing: var(--btn-ls, .04em);
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-user-select: none; user-select: none;
  transition: background-color var(--dur-base), border-color var(--dur-base), color var(--dur-base),
              box-shadow var(--dur-base), filter var(--dur-base), transform var(--dur-fast), opacity var(--dur-base);
}
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost, .btn-icon) > svg { flex: none; }

/* 实心：强调色填充，页面上最重的一个动作 */
.btn-solid {
  --_bg: var(--btn-solid-bg, var(--accent-fill));
  --_fg: var(--btn-solid-fg, var(--on-accent));
  --_b:  var(--btn-solid-border, transparent);
  --_sh: var(--btn-solid-shadow,
           var(--accent-shadow),
           inset var(--edge-lit-x) var(--edge-lit-y) 0 rgba(255,255,255,.28));
}
/* 磨砂：平铺在页面上的次要按钮，底色与搜索框同一材质 */
.btn-glass {
  --_bg: var(--btn-glass-bg, var(--flat-grain, none) var(--flat-fill, var(--surface-hover)));
  --_fg: var(--btn-glass-fg, var(--blue2));
  --_b:  var(--btn-glass-border, var(--surface-hover));
  --_sh: var(--btn-glass-shadow,
           0 4px 16px rgba(var(--blue-rgb), .06),
           inset var(--edge-lit-x) var(--edge-lit-y) 0 var(--surface-hover));
}
/* 描边：小型工具按钮（排序、刷新、复制、翻页、返回、重试、取消） */
.btn-outline {
  --_bg: var(--btn-outline-bg, var(--surface));
  --_fg: var(--btn-outline-fg, var(--text2));
  --_b:  var(--btn-outline-border, var(--border));
  --_fw: 400;
}
/* 幽灵：文字按钮，只在悬停时出现底色并转为强调色 */
.btn-ghost {
  --_bg: var(--btn-ghost-bg, none);
  --_fg: var(--btn-ghost-fg, var(--text2));
  --_fw: 400;
  --btn-pad: 11px 10px;
}
/* 实心的危险变体：删除、清空等不可恢复的动作。底色在 --danger 上加深 12%，
   深色主题的 --danger 较亮，白字对比度不足 4.5:1。 */
.btn-solid.is-danger {
  --_bg: var(--btn-danger-bg, color-mix(in srgb, var(--danger) 88%, #000));
  --_fg: var(--btn-danger-fg, #fff);
  --_sh: var(--btn-danger-shadow,
           0 4px 14px rgba(220, 38, 38, .28),
           inset var(--edge-lit-x) var(--edge-lit-y) 0 rgba(255,255,255,.22));
}
/* 磨砂与圆钮的底色第一层是颗粒纹理，按纹理尺寸平铺 */
:is(.btn-glass, .btn-icon) { background-size: var(--grain-tile, auto); }
/* 圆形图标按钮：浮在内容上方的磨砂圆钮，也用于弹窗的关闭钮 */
.btn-icon {
  --_bg: var(--btn-icon-bg, var(--glass-grain, none) var(--surface-hover));
  --_fg: var(--btn-icon-fg, var(--blue2));
  --_b:  var(--btn-icon-border, var(--border));
  --_sh: var(--btn-icon-shadow, var(--glass-hi, none));
  width: var(--btn-h, 36px); height: var(--btn-h, 36px);
  padding: 0;
  border-radius: var(--btn-icon-r, 50%);
  font-size: var(--fs-lg); letter-spacing: 0;
  -webkit-backdrop-filter: var(--glass-thin); backdrop-filter: var(--glass-thin);
}
.btn-icon > svg { display: block; }

/* 尺寸 */
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-sm {
  --btn-pad: 7px 13px; --btn-fs: var(--fs-sm); --btn-gap: 5px; --btn-ls: .02em;
}
.btn-ghost.is-sm { --btn-pad: 7px 8px; }
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-lg {
  --btn-pad: 14px 22px; --btn-fs: var(--fs-base); --btn-gap: 8px;
}
/* 无底圆钮：嵌在导航条、工具条里，平时只有图标，悬停与按下保持时出现淡色底，
   不带描边、投影与模糊。 */
.btn-icon.is-bare {
  --_bg: var(--btn-bare-bg, none);
  --_fg: var(--btn-bare-fg, var(--text2));
  --_b: transparent;
  --_sh: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.btn-icon.is-sm { --btn-h: 28px; font-size: var(--fs-md); }
.btn-icon.is-lg { --btn-h: 44px; font-size: var(--fs-xl); }
.is-block:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost) { display: flex; width: 100%; }
/* 圆形图标钮：里面只有一个符号或图标的 btn-solid / btn-glass / btn-outline / btn-ghost，
   宽高取 --btn-h（默认 40px，is-sm 时 30px）。 */
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-icon {
  width: var(--btn-h, 40px); height: var(--btn-h, 40px);
  padding: 0; border-radius: var(--btn-icon-r, 50%); font-size: 16px; letter-spacing: 0;
}
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-icon.is-sm { --btn-h: 30px; font-size: var(--fs-base); }

/* 悬停：只在真实指针设备上，触屏上 :hover 会粘在最后点过的元素上 */
@media (hover: hover) {
  .btn-solid:hover:not(:disabled, [aria-disabled="true"]) {
    filter: brightness(1.06); transform: var(--btn-lift, translateY(-1px));
  }
  .btn-glass:hover:not(:disabled, [aria-disabled="true"]) {
    --_bg: var(--btn-glass-bg-hover, var(--flat-grain, none) var(--flat-fill-strong, var(--surface-strong)));
    --_b: var(--btn-glass-border-hover, rgba(var(--blue-rgb), .4));
    --_sh: var(--btn-glass-shadow-hover, 0 6px 18px rgba(var(--blue-rgb), .14));
    transform: var(--btn-lift, translateY(-1px));
  }
  .btn-outline:hover:not(:disabled, [aria-disabled="true"]) {
    --_bg: var(--btn-outline-bg-hover, var(--surface-hover));
    --_b: var(--btn-outline-border-hover, var(--border-hover));
    --_fg: var(--btn-outline-fg-hover, var(--blue2));
  }
  .btn-ghost:hover:not(:disabled, [aria-disabled="true"]) {
    --_bg: var(--btn-ghost-bg-hover, rgba(var(--blue-rgb), .1));
    --_fg: var(--btn-ghost-fg-hover, var(--blue2));
  }
  .btn-icon:hover:not(:disabled, [aria-disabled="true"]) {
    --_bg: var(--btn-icon-bg-hover, var(--glass-grain, none) var(--surface-strong));
    --_b: var(--btn-icon-border-hover, var(--border-hover));
  }
  .btn-icon.is-bare:hover:not(:disabled, [aria-disabled="true"]) {
    --_bg: var(--btn-bare-bg-hover, rgba(var(--blue-rgb), .1));
    --_fg: var(--btn-bare-fg-hover, var(--text));
    --_b: transparent;
  }
}
/* 按下：皮肤通过 --ui-press / --ui-press-shadow 改写按下效果 */
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost, .btn-icon):active:not(:disabled, [aria-disabled="true"]) {
  transform: var(--ui-press, scale(.97));
  box-shadow: var(--ui-press-shadow, var(--_sh, none));
  filter: none;
}
/* 按下态保持（切换按钮）：outline / ghost / icon 用强调色描边与字色 */
:is(.btn-outline, .btn-ghost, .btn-icon):is([aria-pressed="true"], .is-on) {
  --_fg: var(--btn-on-fg, var(--blue2));
  --_b: var(--btn-on-border, rgba(var(--blue-rgb), .55));
  --_bg: var(--btn-on-bg, rgba(var(--blue-rgb), .12));
}
/* 无底圆钮的按下保持与展开：淡色底，不加描边 */
.btn-icon.is-bare:is([aria-pressed="true"], .is-on) { --_b: transparent; }
.btn-icon.is-bare[aria-expanded="true"] {
  --_bg: var(--btn-bare-bg-hover, rgba(var(--blue-rgb), .1));
  --_fg: var(--btn-bare-fg-hover, var(--text));
}
/* 禁用与忙碌 */
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost, .btn-icon):is(:disabled, [aria-disabled="true"]) {
  opacity: .5; cursor: not-allowed; filter: none; transform: none;
}
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost, .btn-icon)[aria-busy="true"] {
  cursor: progress; opacity: .75;
}
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost)[aria-busy="true"]::before {
  content: ''; width: 12px; height: 12px; flex: none;
  border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent;
  animation: spin .7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  :is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost)[aria-busy="true"]::before { animation-duration: 2.4s; }
}


/* ═══ 胶囊 ═══════════════════════════════════════════════════════════
   筛选、标签、年度 / 月度这类可选项。选中（aria-pressed / aria-selected /
   aria-current / .is-on）一律变成实心，与 pill-solid 同一外观。 */
:is(.pill-soft, .pill-outline, .pill-solid) {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--pill-gap, 6px);
  max-width: 100%;
  padding: var(--pill-pad, 5px 12px);
  border-radius: var(--pill-r, var(--r-pill));
  border: var(--bw) solid var(--_b, transparent);
  background: var(--_bg, none);
  color: var(--_fg, var(--text2));
  box-shadow: var(--_sh, none);
  font-family: var(--pill-font, var(--font-sans));
  font-size: var(--pill-fs, var(--fs-sm));
  font-weight: 400;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color var(--dur-base), border-color var(--dur-base), color var(--dur-base), box-shadow var(--dur-base), transform var(--dur-fast);
}
:is(button, a):is(.pill-soft, .pill-outline, .pill-solid) { cursor: pointer; touch-action: manipulation; }
.pill-soft {
  --_bg: var(--pill-soft-bg, var(--surface));
  --_b:  var(--pill-soft-border, var(--border));
  --_fg: var(--pill-soft-fg, var(--text2));
}
.pill-outline {
  --_bg: var(--pill-outline-bg, transparent);
  --_b:  var(--pill-outline-border, var(--border));
  --_fg: var(--pill-outline-fg, var(--text2));
}
:is(.pill-solid,
    :is(.pill-soft, .pill-outline):is([aria-pressed="true"], [aria-selected="true"], [aria-current="true"], [aria-current="page"], .is-on)) {
  --_bg: var(--pill-on-bg, var(--accent-fill));
  --_b:  var(--pill-on-border, transparent);
  --_fg: var(--pill-on-fg, var(--on-accent));
  --_sh: var(--pill-on-shadow, none);
}
.pill-soft.is-sm, .pill-outline.is-sm, .pill-solid.is-sm { --pill-pad: 3px 9px; --pill-fs: var(--fs-xs); --pill-gap: 4px; }
.pill-soft.is-md, .pill-outline.is-md, .pill-solid.is-md { --pill-pad: 10px 14px; }
@media (hover: hover) {
  :is(button, a):is(.pill-soft, .pill-outline):not([aria-pressed="true"], [aria-selected="true"], [aria-current], .is-on, :disabled):hover {
    --_bg: var(--pill-hover-bg, var(--surface-hover));
    --_b:  var(--pill-hover-border, var(--border-hover));
    --_fg: var(--pill-hover-fg, var(--text));
  }
}
:is(button, a):is(.pill-soft, .pill-outline, .pill-solid):active:not(:disabled) {
  transform: var(--ui-press, scale(.95));
  box-shadow: var(--ui-press-shadow, var(--_sh, none));
}
:is(.pill-soft, .pill-outline, .pill-solid):disabled { opacity: .5; cursor: not-allowed; }
/* 胶囊里的用户可变文字（昵称、标签名）：超出胶囊的最大宽度时截断为省略号。
   胶囊是 inline-flex，文字容器需要 min-width: 0 才能收缩到小于内容宽度。
   完整文字放在 title 或 aria-label 里。 */
.pill-text { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 胶囊里的色点（棉花糖活动色） */
.pill-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--dot, var(--bow)); }
/* 一排胶囊 */
.pill-row {
  display: flex; flex-wrap: wrap; gap: 6px;
  justify-content: center;
}


/* 触屏（粗指针）：胶囊、分段项与小号圆钮的高度提到约 32px，手指易点中。
   只改内边距与按钮令牌，皮肤自己写的内边距优先级更高，不受影响。 */
@media (pointer: coarse) {
  :is(.pill-soft, .pill-outline, .pill-solid) { --pill-pad: 8px 14px; }
  /* 后写的同特异性规则覆盖上面 .is-sm 的 --pill-pad */
  :is(.pill-soft, .pill-outline, .pill-solid).is-sm { --pill-pad: 8.5px 12px; }
  :is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-sm { --btn-pad: 8px 13px; }
  .btn-ghost.is-sm { --btn-pad: 8px 8px; }
  .btn-icon.is-sm,
  :is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-icon.is-sm { --btn-h: 32px; }
  /* 弹窗关闭钮：外观保持，命中区向四周扩 8px */
  .btn-icon.is-corner::after { content: ''; position: absolute; inset: -8px; }
  /* 小号按钮外观约 32px 高，命中区补到约 44px：上下各 6px，左右各 4px。
     只用 ::after，不改布局尺寸；相邻按钮间距不小于 8px 时热区不重叠。 */
  :is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-sm:not(.is-icon) { position: relative; }
  :is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost).is-sm:not(.is-icon)::after {
    content: ''; position: absolute; inset: -6px -4px;
  }
}


/* ═══ 面 ═════════════════════════════════════════════════════════════
   L1 surface-glass  直接放在页面上的卡片
   L0 surface-flat   卡片之内的块：只有淡色填充
   L2 surface-float  浮在内容之上：弹窗、菜单、HUD
   surface-aurora    极光底的页头卡（/me、/about）
   卡片内不再放 surface-glass；内部分组用 surface-flat。 */
.surface-glass {
  position: relative;
  background: var(--surface-glass-bg, var(--l1-bg));
  border: var(--surface-glass-border, var(--l1-border));
  border-radius: var(--surface-r, var(--r-panel));
  box-shadow: var(--surface-glass-shadow, var(--l1-shadow));
  padding: var(--surface-pad, var(--pad-card));
  min-width: 0;
}
.surface-flat {
  background: var(--surface-flat-bg, var(--l0-fill));
  border: var(--surface-flat-border, var(--l0-border));
  border-radius: var(--surface-flat-r, var(--r-inner));
  padding: var(--surface-flat-pad, var(--s-2));
}
.surface-float {
  background-color: var(--surface-float-bg, var(--l2-bg));
  background-image: var(--glass-grain, none);
  background-size: var(--grain-tile, auto);
  -webkit-backdrop-filter: var(--l2-blur); backdrop-filter: var(--l2-blur);
  border: var(--bw) solid var(--surface-float-border, var(--card-border));
  border-radius: var(--surface-r, var(--r-panel));
  box-shadow: var(--surface-float-shadow, var(--l2-shadow)), var(--glass-hi, 0 0 #0000);
  padding: var(--surface-pad, var(--pad-card));
  color: var(--text);
}
.surface-aurora {
  position: relative; z-index: 1;
  overflow: hidden;
  border-radius: var(--surface-r, var(--r-panel));
  border: var(--bw) solid var(--hero-edge);
  background: var(--surface-aurora-bg,
    radial-gradient(ellipse 60% 55% at 85% 20%, rgba(var(--bow-rgb), 0.6), transparent 70%),
    radial-gradient(ellipse 50% 45% at 90% 90%, rgba(206,196,244,0.8), transparent 70%),
    radial-gradient(ellipse 40% 50% at 15% 85%, rgba(255,255,255,0.5), transparent 70%),
    linear-gradient(115deg, var(--hero-a) 0%, var(--hero-c) 45%, var(--hero-b) 100%));
  box-shadow: var(--surface-aurora-shadow,
    calc(var(--shadow-dx) * 13px) 14px 44px rgba(46,74,102,0.14),
    var(--edge-lit-x) var(--edge-lit-y) 0 rgba(255,255,255,0.7) inset);
}
[data-theme="dark"] .surface-aurora {
  background: var(--surface-aurora-bg,
    radial-gradient(ellipse 60% 55% at 85% 20%, rgba(var(--bow-rgb), 0.35), transparent 70%),
    radial-gradient(ellipse 50% 45% at 90% 90%, rgba(120,110,190,0.25), transparent 70%),
    linear-gradient(115deg, var(--hero-a) 0%, var(--hero-c) 45%, var(--hero-b) 100%));
  box-shadow: var(--surface-aurora-shadow,
    calc(var(--shadow-dx) * 13px) 14px 44px rgba(0,0,0,0.4),
    var(--edge-lit-x) var(--edge-lit-y) 0 rgba(207,228,246,0.12) inset);
}
.is-tight:is(.surface-glass, .surface-float) { --surface-pad: var(--s-3); }

/* 深色底上的控件：.on-dark 只改写组件令牌，不画底。用于始终压在深色画面
   或深色遮罩上的一组控件（查看器顶栏、播放器控制条）。深色底不随主题翻转，
   所以这里取固定的半透明白，不取 --surface-*：那组令牌在浅色主题下是浅底，
   压在深色画面上会变成一块亮斑。 */
:is(.on-dark, .surface-smoke) {
  --btn-icon-bg: rgba(255, 255, 255, .1);
  --btn-icon-bg-hover: rgba(255, 255, 255, .2);
  --btn-icon-fg: #eef2fa;
  --btn-icon-border: transparent;
  --btn-icon-border-hover: transparent;
  --btn-icon-shadow: none;
  --btn-on-fg: #fff;
  --btn-on-bg: rgba(255, 255, 255, .22);
  --btn-on-border: transparent;
  --btn-outline-bg: rgba(255, 255, 255, .12);
  --btn-outline-fg: #eef2fa;
  --btn-outline-border: rgba(255, 255, 255, .28);
  --btn-outline-bg-hover: rgba(255, 255, 255, .22);
  --btn-outline-fg-hover: #fff;
  --btn-outline-border-hover: rgba(255, 255, 255, .4);
  --btn-ghost-fg: rgba(238, 242, 250, .86);
  --btn-ghost-fg-hover: #fff;
  --btn-ghost-bg-hover: rgba(255, 255, 255, .14);
  --pill-soft-bg: rgba(255, 255, 255, .1);
  --pill-soft-border: transparent;
  --pill-soft-fg: rgba(238, 242, 250, .9);
  --pill-hover-bg: rgba(255, 255, 255, .2);
  --pill-hover-border: transparent;
  --pill-hover-fg: #fff;
  --on-dark-fg: #eef2fa;
  --on-dark-fg2: rgba(238, 242, 250, .66);
  --on-dark-accent: #a8d2f4;
  color: var(--on-dark-fg);
}
/* 烟色玻璃：压在视频、音频画面上的深色半透明条，内部控件按 .on-dark 着色。
   不加亮色描边，边缘只靠模糊与顶部一道极淡的内高光区分。 */
.surface-smoke {
  background: var(--surface-smoke-bg, rgba(10, 14, 24, .58));
  -webkit-backdrop-filter: blur(16px) saturate(1.4); backdrop-filter: blur(16px) saturate(1.4);
  border-radius: var(--surface-smoke-r, var(--r-md));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 4px 16px rgba(0, 0, 0, .24);
  padding: var(--surface-smoke-pad, var(--s-2));
}


/* ═══ 分段切换 ═══════════════════════════════════════════════════════
   .seg 是槽，.seg-item 是各段，.seg-thumb 是滑块。滑块的位置由
   KiraUI.seg()（shared.js）计算；没有滑块时选中段自己填色。 */
.seg {
  position: relative;
  display: inline-flex; align-items: stretch; gap: 0;
  width: fit-content; max-width: 100%;
  padding: 3px;
  border-radius: var(--seg-r, var(--r-pill));
  border: var(--bw) solid var(--seg-border, var(--border));
  background: var(--seg-bg, var(--flat-grain, none) var(--flat-fill, var(--surface-hover)));
  background-size: var(--grain-tile, auto);
}
.seg-thumb {
  position: absolute; top: 3px; left: 3px;
  height: calc(100% - 6px); width: 0;
  border-radius: var(--seg-thumb-r, var(--r-pill));
  background: var(--seg-on-bg, var(--accent-fill));
  box-shadow: var(--seg-on-shadow, var(--accent-shadow));
  pointer-events: none;
  z-index: 0;
}
.seg-item {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: var(--seg-pad, 6px 15px);
  border: 0; border-radius: var(--seg-thumb-r, var(--r-pill));
  background: none;
  color: var(--seg-fg, var(--text2));
  font-family: var(--font-sans); font-size: var(--seg-fs, var(--fs-md)); font-weight: 400; line-height: 1.2;
  letter-spacing: .04em; white-space: nowrap; text-decoration: none;
  cursor: pointer; touch-action: manipulation;
  transition: color var(--dur-base), background-color var(--dur-base), transform var(--dur-fast);
}
.seg-item > svg { flex: none; }
.seg-item:is([aria-selected="true"], [aria-pressed="true"], [aria-checked="true"], [aria-current="page"], .is-on) {
  color: var(--seg-on-fg, var(--on-accent));
}
/* 没有滑块的 .seg：选中段自己画底 */
.seg:not(:has(> .seg-thumb)) > .seg-item:is([aria-selected="true"], [aria-pressed="true"], [aria-checked="true"], [aria-current="page"], .is-on) {
  background: var(--seg-on-bg, var(--accent-fill));
  box-shadow: var(--seg-on-shadow, var(--accent-shadow));
}
@media (hover: hover) {
  .seg-item:not([aria-selected="true"], [aria-pressed="true"], [aria-checked="true"], [aria-current="page"], .is-on):hover {
    color: var(--seg-hover-fg, var(--blue2));
  }
}
.seg-item:active { transform: var(--ui-press, scale(.95)); }
.seg-item:disabled { opacity: .45; cursor: not-allowed; }
.seg.is-sm { --seg-pad: 4px 10px; --seg-fs: var(--fs-sm); }
/* 占满一行：各段等分宽度 */
.seg.is-block { display: flex; width: 100%; }
.seg.is-block > .seg-item { flex: 1 1 0; min-width: 0; }
/* 触屏：分段项高度提到约 32px（写在 .is-sm 之后，同特异性时后者生效） */
@media (pointer: coarse) {
  .seg { --seg-pad: 8.5px 15px; }
  .seg.is-sm { --seg-pad: 9.1px 12px; }
}


/* ═══ 输入框 ═════════════════════════════════════════════════════════
   聚焦态只有一种：描边取主色并带一圈 3px 的光环。
   窄屏与触屏上字号不小于 16px，否则 iOS Safari 聚焦时会放大页面。 */
:is(.field, .field-glass) {
  display: block; width: 100%;
  padding: var(--field-pad, 9px 12px);
  border: var(--bw) solid var(--_b, var(--field-border, var(--border)));
  border-radius: var(--field-r, var(--r-inner));
  background: var(--field-bg, var(--surface-muted));
  color: var(--text);
  font: inherit; font-size: var(--field-fs, var(--fs-base)); line-height: 1.5;
  outline: none;
  -webkit-appearance: none; appearance: none;
  transition: border-color var(--dur-base), box-shadow var(--dur-base), background-color var(--dur-base);
}
textarea:is(.field, .field-glass) { resize: vertical; min-height: 84px; }
select.field {
  padding-right: 30px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%237f9cba' stroke-width='1.6' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat; background-position: right 11px center;
}
.field-glass {
  --field-r: var(--r-pill);
  padding: var(--field-pad, 13px 20px);
  line-height: 1.2;
  background-color: var(--field-glass-bg, var(--flat-fill, var(--surface-hover)));
  background-image: var(--flat-grain, none);
  background-size: var(--grain-tile, auto);
  --_b: var(--field-glass-border, var(--surface-hover));
  font-size: var(--field-fs, var(--fs-lg));
  box-shadow: 0 4px 16px rgba(var(--blue-rgb), .06), inset var(--edge-lit-x) var(--edge-lit-y) 0 var(--surface-hover);
}
:is(.field, .field-glass)::placeholder { color: var(--text3); }
:is(.field, .field-glass):focus,
:is(.field, .field-glass):focus-visible {
  --_b: var(--field-focus-border, var(--blue2));
  box-shadow: var(--field-focus-ring, 0 0 0 3px rgba(var(--blue-rgb), .32));
  outline: none;
}
.field-glass:focus { background-color: var(--flat-fill-strong, var(--surface-strong)); }
:is(.field, .field-glass)[aria-invalid="true"] { --_b: var(--danger); }
:is(.field, .field-glass):is(:disabled, [readonly]:not(textarea)) { opacity: .55; cursor: not-allowed; }
@media (max-width: 600px), (pointer: coarse) {
  :is(.field, .field-glass) { font-size: max(16px, var(--field-fs, var(--fs-base))); }
}
/* 磨砂圆盘：渐变封面中央托住线稿图标的圆盘，直接子元素放 44px 的线稿 svg，
   图标取 currentColor；浅色封面加 .is-deep 改用深蓝，深色主题回到白色。 */
.disc-frost { position: relative; z-index: 1; display: grid; place-items: center; flex: none; width: 64px; height: 64px; border-radius: 50%; color: #fff; background: rgba(255,255,255,.34); box-shadow: inset 0 0 0 1px rgba(255,255,255,.5), 0 6px 14px rgba(20,30,60,.16); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: transform .25s; }
.disc-frost > svg { width: 44px; height: 44px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.disc-frost.is-deep { color: var(--blue2-deep); }
[data-theme="dark"] .disc-frost.is-deep { color: #fff; }

/* 数据到达后内容淡入：在真实内容容器上加 .fade-in，动画结束后由页面脚本摘掉类名。
   起点取 .55 而不是 0：容器同时容纳骨架与真实内容，从 0 起步会在骨架被替换的瞬间出现一帧空白。
   不写 fill-mode：forwards 会在动画结束后保留层叠上下文，影响内部 backdrop-filter 与 z-index。 */
@keyframes ui-fade-in { from { opacity: .55; } }
.fade-in { animation: ui-fade-in .24s var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .fade-in { animation: none; } }

/* 阅读进度细线：固定在视口顶端的 2px 线，--p（0 至 1）由 shared.js 随滚动写入。
   只在长文页面出现；页面不足两屏时隐藏。 */
.read-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 9000;
  pointer-events: none;
}
.read-progress[hidden] { display: none; }
.read-progress > i {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, var(--blue), var(--blue2));
  transform-origin: 0 50%; transform: scaleX(var(--p, 0));
}

/* 浮动标签：.field-float 内依次放 input.field 与 label。输入框必须写 placeholder=" "，
   标签在未聚焦且无内容时压在输入框内，聚焦或有内容时缩小并上移到框内上沿。
   输入框上内边距加大，为上浮的标签留位置。 */
.field-float { position: relative; display: block; }
.field-float > .field { padding-top: 20px; padding-bottom: 6px; }
.field-float > label {
  position: absolute; left: 13px; top: 0; bottom: 0; display: flex; align-items: center; pointer-events: none;
  font-size: var(--fs-base); line-height: 1.4; color: var(--text3);
  transform-origin: 0 50%;
  transition: transform var(--dur-base) var(--ease-out), color var(--dur-base);
}
.field-float > .field:focus + label,
.field-float > .field:not(:placeholder-shown) + label { transform: translateY(-10px) scale(.78); }
@media (max-width: 600px), (pointer: coarse) { .field-float > label { font-size: 16px; } }
.field-float > .field:focus + label { color: var(--blue2); }
@media (prefers-reduced-motion: reduce) { .field-float > label { transition: none; } }

/* 带左侧图标的输入框：.field-wrap 内放 .field-icon 与输入框 */
.field-wrap { position: relative; display: flex; align-items: center; }
.field-wrap > .field-icon {
  position: absolute; left: 16px; color: var(--text3); pointer-events: none;
  transition: color var(--dur-base);
}
.field-wrap > :is(.field, .field-glass):focus ~ .field-icon { color: var(--blue2); }
.field-wrap > .field-icon ~ :is(.field, .field-glass),
.field-wrap > :is(.field, .field-glass):has(~ .field-icon) { padding-left: 44px; }


/* ═══ 开关 ═══════════════════════════════════════════════════════════ */
input[type="checkbox"].switch {
  -webkit-appearance: none; appearance: none;
  width: 32px; height: 18px; margin: 0; flex: none;
  border-radius: var(--r-pill);
  background: var(--switch-bg, var(--surface-muted));
  border: var(--bw) solid var(--border);
  position: relative; cursor: pointer;
  transition: background var(--dur-base), border-color var(--dur-base);
  vertical-align: middle;
}
input[type="checkbox"].switch::before {
  content: '';
  position: absolute; top: 2px; left: 2px;
  width: 12px; height: 12px; border-radius: var(--switch-thumb-r, 50%);
  background: var(--text3);
  transition: transform var(--dur-base) var(--ease-spring), width var(--dur-fast) ease-out, background var(--dur-base);
}
input[type="checkbox"].switch:checked {
  background: var(--switch-on-bg, var(--accent-fill)); border-color: transparent;
}
input[type="checkbox"].switch:checked::before { background: #fff; transform: translateX(14px); }
/* 按住时滑块头拉宽到 16px；开启状态下右缘保持贴边（2 + 10 + 16 = 28，轨道内宽 30） */
input[type="checkbox"].switch:not(:disabled):active::before { width: 16px; }
input[type="checkbox"].switch:checked:not(:disabled):active::before { transform: translateX(10px); }
input[type="checkbox"].switch:disabled { opacity: .45; cursor: not-allowed; }


/* ═══ 滑块 ═══════════════════════════════════════════════════════════
   原生 input[type=range]。轨道 6px，滑块 16px，触屏放大到 22px。 */
input[type="range"].slider {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; height: 22px; margin: 0;
  background: transparent; cursor: pointer;
  touch-action: manipulation;
}
input[type="range"].slider::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: var(--slider-track, rgba(var(--blue-rgb), .18)); }
input[type="range"].slider::-moz-range-track { height: 6px; border-radius: 3px; background: var(--slider-track, rgba(var(--blue-rgb), .18)); }
input[type="range"].slider::-webkit-slider-thumb {
  -webkit-appearance: none; width: 16px; height: 16px; margin-top: -5px;
  border-radius: var(--slider-thumb-r, 50%); border: 2px solid #fff; background: var(--slider-thumb, var(--blue));
  box-shadow: 0 1px 3px rgba(0, 0, 0, .28);
  transition: box-shadow var(--dur-base);
}
input[type="range"].slider::-moz-range-thumb {
  box-sizing: border-box; width: 16px; height: 16px;
  border-radius: var(--slider-thumb-r, 50%); border: 2px solid #fff; background: var(--slider-thumb, var(--blue));
  box-shadow: 0 1px 3px rgba(0, 0, 0, .28);
  transition: box-shadow var(--dur-base);
}
input[type="range"].slider:focus-visible { outline: none; }
input[type="range"].slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .32); }
input[type="range"].slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .32); }
input[type="range"].slider:disabled { opacity: .45; cursor: not-allowed; }
@media (pointer: coarse) {
  input[type="range"].slider { height: 32px; }
  input[type="range"].slider::-webkit-slider-thumb { width: 22px; height: 22px; margin-top: -8px; }
  input[type="range"].slider::-moz-range-thumb { width: 22px; height: 22px; }
}


/* ═══ 弹出菜单 ═══════════════════════════════════════════════════════
   .menu-float 平时不可见；加 .is-open 后从 transform-origin 处弹出。
   打开、关闭、键盘与点外部关闭由 KiraUI.menu() 负责。 */
.menu-float {
  position: absolute; z-index: 60;
  min-width: 140px;
  padding: 4px;
  background-color: var(--menu-bg, var(--surface-strong));
  background-image: var(--glass-grain, none);
  background-size: var(--grain-tile, auto);
  -webkit-backdrop-filter: var(--glass-regular); backdrop-filter: var(--glass-regular);
  border: var(--bw) solid var(--menu-border, var(--border));
  border-radius: var(--menu-r, var(--r-inner));
  box-shadow: var(--menu-shadow, 0 8px 28px rgba(var(--blue-rgb), .16)), var(--glass-hi, 0 0 #0000);
  max-height: calc(100dvh - 90px);
  overflow-y: auto; overscroll-behavior: contain;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translate(var(--pop-dx, 0), var(--pop-dy, -4px)) scale(.96);
  transform-origin: var(--menu-origin, top right);
  transition: opacity var(--dur-fast) ease, transform var(--dur-fast) ease, visibility 0s var(--dur-fast);
}
.menu-float.is-open {
  opacity: 1; visibility: visible; pointer-events: auto; transform: none;
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out), visibility 0s;
}
/* 深色：--surface-strong 是 .2 透明度的浅蓝，菜单后面的文字会透出来；
   默认皮肤下改用与对话框一致的深色底 */
:root[data-theme="dark"]:not([data-skin]) .menu-float { background-color: var(--menu-bg, var(--surface-modal)); }
@media (prefers-reduced-motion: reduce) {
  .menu-float, .menu-float.is-open { transform: none; transition: none; }
}
.menu-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 7px 10px;
  border: 0; border-radius: calc(var(--menu-r, var(--r-inner)) - 4px);
  background: none;
  color: var(--menu-fg, var(--text));
  font: inherit; font-size: var(--fs-sm); text-align: left; text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast);
}
/* 触屏：菜单项高度 28px 不够点，取 40px（主题菜单在 nav.css 里另有取值） */
@media (pointer: coarse) { .menu-item { padding: 12px 12px; } }
.menu-item:hover, .menu-item:focus-visible { background: rgba(var(--blue-rgb), .1); }
.menu-item:is([aria-checked="true"], [aria-selected="true"], [aria-current="true"], .is-on) {
  background: rgba(var(--blue-rgb), .15); color: var(--blue2); font-weight: 700;
}
.menu-item:focus-visible { outline-offset: -2px; }
.menu-sep { height: 1px; margin: 4px 8px; background: var(--border); }
/* 两列菜单项；菜单内的小节标题用 .eyebrow */
.menu-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 4px; }
.menu-float > .eyebrow { padding: 8px 10px 4px; }
.menu-float > .seg { margin-bottom: 4px; }
/* 定位在视口上的菜单：left / top 由 KiraUI.place() 写入，不随父元素定位 */
.menu-float.is-fixed { position: fixed; top: 0; left: 0; z-index: var(--pop-z, 9999); }


/* ═══ 锚定浮层 ═══════════════════════════════════════════════════════
   .pop-float 与 .surface-float 同用：外观来自 surface-float，这里只管
   定位与开合。left / top 与展开方向（--pop-origin）由 KiraUI.place() 按
   锚点写入；开合、Esc、焦点循环与点外部关闭由 KiraUI.menu() 负责。
   打开时 180ms（--dur-base）淡入，由 0.96 放大并从靠近锚点一侧移动 4px（--pop-dx / --pop-dy
   由 KiraUI.place() 写入，缺省为下方锚点的 -4px）；与 .menu-float 同一曲线。
   减少动态效果时直接切换。 */
.pop-float {
  position: fixed; top: 0; left: 0; z-index: var(--pop-z, 9999);
  max-height: calc(100dvh - 80px);
  overflow-y: auto; overscroll-behavior: contain;
  transform-origin: var(--pop-origin, center top);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translate(var(--pop-dx, 0), var(--pop-dy, -4px)) scale(.96);
  transition: opacity var(--dur-fast) ease, transform var(--dur-fast) ease, visibility 0s var(--dur-fast);
}
.pop-float.is-open {
  opacity: 1; visibility: visible; pointer-events: auto; transform: none;
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out), visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .pop-float, .pop-float.is-open { transform: none; transition: none; }
}


/* ═══ 工具提示 ═══════════════════════════════════════════════════════
   带 data-tip 的元素在悬停（仅 hover: hover 的设备）或键盘聚焦（:focus-visible）
   300ms 后，下方出现一枚小标签。data-tip 有值时显示该值，为空时显示 aria-label，
   只有图标的按钮因此只需维护 aria-label 一处。
   标签由 KiraUI.tip() 生成：一个挂在 <body> 下的 .surface-float.tip-float，
   位置由 KiraUI.place() 写入并限制在视口内。不画在元素自己的 ::after 上：
   导航这类 overflow 容器会裁掉它，皮肤也占用了部分按钮的伪元素。
   出现时 120ms 淡入并下移 2px；减少动态效果时直接切换。 */
.tip-float {
  position: fixed; top: 0; left: 0; z-index: var(--tip-z, 10003);
  --surface-pad: 4px 8px;
  --surface-r: var(--tip-r, var(--r-inner));
  max-width: min(280px, calc(100vw - 24px));
  font: 400 var(--fs-sm)/1.5 var(--font-sans); letter-spacing: normal;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  pointer-events: none;
  opacity: 0; visibility: hidden;
  transform: translateY(-2px);
  transition: opacity var(--dur-fast) ease, transform var(--dur-fast) ease, visibility 0s var(--dur-fast);
}
.tip-float.is-open {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .tip-float, .tip-float.is-open { transform: none; transition: none; }
}


/* ═══ 图块 ═══════════════════════════════════════════════════════════
   .tile-grid       等宽网格，列数取 --tile-cols（默认 2），is-3 为三列
   .tile-ghost      无底图块：图标 + 名称 + 一行说明，悬停出现淡色底；
                    aria-current="page" 或 .is-on 时与导航滑块同一填色
   .tile-flat       与 surface-flat 同用的工具格：上行图标与控件（开关、
                    键帽、箭头），下行名称
   is-wide          横跨整行 */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(var(--tile-cols, 2), minmax(0, 1fr));
  gap: var(--tile-gap, 4px);
}
.tile-grid.is-3 { --tile-cols: 3; --tile-gap: 8px; }
.tile-grid > .is-wide { grid-column: 1 / -1; }
.tile-title { font-size: var(--fs-sm); line-height: 16px; font-weight: 700; white-space: nowrap; }
.tile-sub {
  font-size: var(--fs-xs); line-height: 16px; color: var(--text3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile-ghost {
  display: grid; grid-template-columns: 14px minmax(0, 1fr); column-gap: 8px; align-items: center;
  min-height: 48px; padding: var(--tile-pad, 8px 12px);
  border-radius: var(--tile-r, var(--r-inner));
  color: var(--tile-fg, var(--text)); text-decoration: none;
  transition: background-color var(--dur-base), color var(--dur-base), box-shadow var(--dur-base), transform var(--dur-fast);
}
.tile-ghost > svg { grid-row: 1; color: var(--text2); }
.tile-ghost > .tile-title { grid-row: 1; }
.tile-ghost > .tile-sub { grid-column: 2; }
@media (hover: hover) {
  .tile-ghost:not([aria-current="page"], .is-on):hover { background: var(--tile-hover-bg, rgba(var(--blue-rgb), .1)); }
  .tile-flat:hover { background: var(--tile-hover-bg, rgba(var(--blue-rgb), .1)); }
}
.tile-ghost:is([aria-current="page"], .is-on) {
  background: var(--tile-on-bg, var(--accent-fill));
  box-shadow: var(--tile-on-shadow, var(--accent-shadow));
  color: var(--tile-on-fg, var(--on-accent));
}
.tile-ghost:is([aria-current="page"], .is-on) > :is(svg, .tile-sub) { color: inherit; opacity: .85; }
.tile-flat {
  display: grid; grid-template-rows: 20px 16px; row-gap: 4px; align-content: center;
  min-width: 0; min-height: 56px;
  --surface-flat-pad: 8px 12px;
  font: inherit; text-align: left; color: var(--text);
  cursor: pointer; touch-action: manipulation;
  -webkit-appearance: none; appearance: none;
  transition: background-color var(--dur-base), transform var(--dur-fast);
}
.tile-flat > .tile-top { display: flex; align-items: center; justify-content: space-between; gap: 4px; color: var(--text2); }
.tile-flat > .tile-title { font-weight: 400; overflow: hidden; text-overflow: ellipsis; }
.tile-flat .kbd { font-size: 10px; line-height: 14px; padding: 0 4px; }
:is(.tile-ghost, .tile-flat):active { transform: var(--ui-press, scale(.97)); }


/* ═══ 遮罩与对话框 ════════════════════════════════════════════════════
   .scrim 铺满视口；其中的 .surface-float 即对话框。隐藏时用 visibility
   而不只是 opacity：透明的遮罩仍在 Tab 顺序里。打开时 visibility 不延迟，
   否则紧接着的 focus() 落在不可见元素上无效。 */
.scrim {
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: var(--scrim-bg, rgba(30, 50, 80, .45));
  -webkit-backdrop-filter: var(--glass-thin); backdrop-filter: var(--glass-thin);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity var(--dur-slow), visibility 0s var(--dur-slow);
}
[data-theme="dark"] .scrim { --scrim-bg: rgba(8, 14, 26, .6); }
/* 深色遮罩：看图、看视频时铺满视口的暗底，两种主题下一样深，
   上面的控件配合 .on-dark 使用。 */
.scrim.is-dark {
  --scrim-bg: var(--scrim-dark-bg, rgba(6, 10, 20, .9));
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.scrim.is-open {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity var(--dur-slow), visibility 0s;
}
.scrim > .surface-float {
  --surface-float-bg: var(--dialog-bg, var(--l2-bg));
  position: relative;
  width: 100%; max-width: var(--dialog-w, 460px);
  max-height: var(--dialog-h, 80dvh);
  display: flex; flex-direction: column;
  transform: scale(.94) translateY(8px);
  transition: transform var(--dur-slow) var(--ease-spring);
}
.scrim.is-open > .surface-float { transform: none; }
/* 减少动态效果：对话框随遮罩淡入，不做缩放、位移与过冲 */
@media (prefers-reduced-motion: reduce) {
  .scrim > .surface-float { transform: none; transition: none; }
}
/* 对话框右上角的关闭钮 */
.surface-float > .btn-icon.is-corner { position: absolute; top: 12px; right: 12px; z-index: 1; }
/* 悬停旋转用独立的 rotate 属性：按下的缩放写在 transform 上，两者叠加而不互相覆盖 */
@media (hover: hover) {
  .btn-icon.is-corner {
    transition: background-color var(--dur-base), border-color var(--dur-base), color var(--dur-base), box-shadow var(--dur-base),
                filter var(--dur-base), transform var(--dur-fast), opacity var(--dur-base), rotate var(--dur-slow) ease;
  }
  .btn-icon.is-corner:hover { rotate: 90deg; }
}

/* 紧凑对话框：图标、标题、一段说明、一排按钮，居中排布。KiraUI.confirm 使用。
   is-danger 的图标盘换成红色底，按钮行放在 .btn-row 里。 */
.surface-float.is-compact {
  --dialog-w: 360px;
  align-items: center; text-align: center;
  padding: 26px 24px 20px;
}
.surface-float.is-compact > .title-star { justify-content: center; margin-bottom: var(--s-2); }
.surface-float.is-compact > .title-star::before { display: none; }
.surface-float.is-compact > .state-icon { margin-bottom: 14px; font-size: 20px; }
.surface-float.is-compact > p {
  margin: 0; max-width: 28em;
  font-size: var(--fs-md); line-height: 1.7; color: var(--text2);
  white-space: pre-line; overflow-wrap: anywhere;
}
.state-icon.is-glyph.is-danger {
  --state-plate: radial-gradient(circle at 35% 25%, rgba(220, 38, 38, .26), rgba(220, 38, 38, .12) 70%);
  color: var(--danger-text);
}
.state-icon.is-glyph.is-danger > svg { animation: none; }
/* 一排按钮：靠右，最重的动作在最右。窄屏上各占一半宽度 */
.btn-row { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
.surface-float.is-compact > .btn-row { width: 100%; justify-content: center; }
.surface-float.is-compact > .btn-row > * { flex: 1 1 0; }


/* ═══ 提示 ═══════════════════════════════════════════════════════════
   shared.js showToast() 生成 #kiralu-toast.toast。 */
.toast {
  /* 高于 .scrim（10000）、搜索面板（10001）与 .tip（10003）：弹窗内触发的提示也要可见 */
  position: fixed; z-index: 10010;
  left: 50%; bottom: calc(32px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 8px;
  max-width: calc(88vw - env(safe-area-inset-left) - env(safe-area-inset-right));
  /* 固定最小高度而不用垂直内边距：带「撤销」按钮的提示与普通提示同高（36px） */
  min-height: 36px; padding: 0 22px;
  border-radius: var(--toast-r, var(--r-pill));
  background-color: var(--toast-bg, rgba(30, 60, 100, .78));
  background-image: var(--glass-grain, none);
  background-size: var(--grain-tile, auto);
  -webkit-backdrop-filter: var(--glass-thick); backdrop-filter: var(--glass-thick);
  color: var(--toast-fg, #fff);
  font-size: var(--fs-md); letter-spacing: .5px; white-space: nowrap;
  box-shadow: 0 4px 20px rgba(var(--blue-rgb), .25), inset 0 1px 0 rgba(255,255,255,.1);
  overflow: hidden;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateX(-50%) translateY(12px);
  transition: opacity var(--dur-slow) ease, transform var(--dur-slow) var(--ease-spring), visibility 0s var(--dur-slow);
}
.toast.is-open {
  opacity: 1; visibility: visible; pointer-events: auto; transform: translateX(-50%) translateY(0);
  transition: opacity var(--dur-slow) ease, transform var(--dur-slow) var(--ease-spring), visibility 0s;
}
/* 手机端右下角的回到顶部钮（右下 16px、36px 见方）占到底部约 52px：
   钮显示时提示上移到它之上 */
@media (max-width: 580px) {
  html:not(.chrome-hidden) body:has(#backTop.show) .toast { bottom: calc(68px + env(safe-area-inset-bottom)); }
}
.toast.is-error { --toast-bg: var(--toast-error-bg, rgba(120, 45, 55, .84)); }
.toast-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.toast-icon {
  flex: none; width: 16px; height: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.18); color: #fff; font-size: var(--fs-xs); line-height: 1;
}
.toast-action {
  flex: none; margin-left: 4px; padding: 2px 10px;
  font: inherit; font-size: var(--fs-sm); cursor: pointer;
  color: inherit; background: rgba(255,255,255,.18);
  border: 1px solid rgba(255,255,255,.35); border-radius: var(--r-pill);
  transition: background-color var(--dur-base);
}
.toast-action:hover { background: rgba(255,255,255,.3); }
/* 减少动态效果：提示只淡入淡出，保留水平居中所需的 translateX */
@media (prefers-reduced-motion: reduce) {
  .toast, .toast.is-open { transform: translateX(-50%); }
  .toast { transition: opacity var(--dur-slow) ease, visibility 0s var(--dur-slow); }
  .toast.is-open { transition: opacity var(--dur-slow) ease, visibility 0s; }
}


/* ═══ 空态 / 错误 / 载入 ════════════════════════════════════════════
   .state       卡片大小的一块：图标、一句标题、一句说明，可带按钮
   .state-line  列表底部的一行：加载中 / 到底啦 / 本页加载失败 */
.state {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  gap: 6px; padding: var(--state-pad, 26px 16px);
  text-align: center; color: var(--text3);
}
/* 背景一层极淡的星点网格，表明这里是设计过的空白 */
.state::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(currentColor 1px, transparent 1px), radial-gradient(currentColor 1px, transparent 1px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  opacity: .05;
  -webkit-mask: radial-gradient(closest-side, #000 30%, transparent 78%);
          mask: radial-gradient(closest-side, #000 30%, transparent 78%);
}
.state-icon {
  font-size: var(--state-icon, 26px); line-height: 1; opacity: .6; filter: grayscale(.25);
  animation: es-float 4.5s ease-in-out infinite;
}
/* 线稿图标：淡色圆盘里放一枚 SVG，图标来自 /img/state-icons.svg，用法
     <span class="state-icon is-glyph"><svg><use href="/img/state-icons.svg#search"/></svg></span>
   圆盘直径 2.7em、图标 1.6em，随 --state-icon 缩放。颜色令牌 --state-line、
   --state-fill、--state-spark、--state-bad，缺省取全局令牌；图标文件读取的是
   下面赋值的 --glyph-*。emoji 写法仍可用，用于没有对应线稿的场合。 */
.state-icon.is-glyph {
  --glyph-line: var(--state-line, var(--blue2));
  --glyph-fill: var(--state-fill, var(--surface-strong));
  --glyph-spark: var(--state-spark, var(--blue));
  --glyph-bad: var(--state-bad, var(--danger));
  display: grid; place-items: center;
  width: 2.7em; height: 2.7em; border-radius: var(--state-icon-r, 50%);
  background: var(--state-plate, radial-gradient(circle at 35% 25%, rgba(var(--blue-rgb), .26), rgba(var(--blue-rgb), .12) 70%));
  opacity: 1; filter: none; animation: none;
}
.state-icon.is-glyph > svg {
  width: 1.6em; height: 1.6em; overflow: visible;
  animation: es-float 4.5s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .state-icon.is-glyph > svg { animation: none; } }
.state-title { font-family: var(--font-display); font-size: var(--fs-md); color: var(--text2); }
.state-hint { font-size: var(--fs-xs); color: var(--text3); letter-spacing: .3px; }
.state > :is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost) { flex: none; margin-top: 6px; }
.state.is-lg { --state-pad: 56px 20px; --state-icon: 38px; }
.state.is-lg .state-title { font-size: 16px; font-weight: 700; }
.state.is-lg .state-hint { font-size: var(--fs-sm); }
@media (prefers-reduced-motion: reduce) { .state-icon { animation: none; } }

.state-line {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 18px; padding: var(--state-line-pad, 10px 0 28px);
  color: var(--text3); font-size: var(--fs-sm); text-align: center;
}
.state-line:empty { padding-bottom: 10px; }
/* 「到底啦」两侧的星与渐隐线 */
.state-line.is-end::before,
.state-line.is-end::after {
  content: '✦'; flex: 0 0 auto; position: relative;
  font-size: 9px; color: var(--text3); opacity: .7;
}
.state-line.is-end::before { padding-left: 46px; background: linear-gradient(to right, transparent, var(--border)) left center / 40px 1px no-repeat; }
.state-line.is-end::after  { padding-right: 46px; background: linear-gradient(to left, transparent, var(--border)) right center / 40px 1px no-repeat; }
.state-line.is-loading::before {
  content: ''; width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid rgba(var(--blue-rgb), .25); border-top-color: var(--blue);
  animation: spin .8s linear infinite;
}

/* 圆形转圈 */
.spinner {
  display: inline-block; width: var(--spinner-size, 28px); height: var(--spinner-size, 28px);
  border-radius: 50%;
  border: 2px solid rgba(var(--blue-rgb), .2); border-top-color: var(--blue);
  animation: spin .8s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .spinner, .state-line.is-loading::before { animation-duration: 2.4s; } }


/* ═══ 骨架 ═══════════════════════════════════════════════════════════
   形状由页面决定（歌单行、投稿卡、棉花糖卡），灰条的材质只有这一种。 */
:is(.skel, .skel-line, .skel-circle, .skel-block) {
  display: block;
  background: var(--skel-bg, rgba(var(--blue-rgb), .12));
  border-radius: var(--skel-r, 6px);
  animation: sk-pulse 1.2s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * 80ms);
}
.skel-line { height: var(--skel-h, 10px); border-radius: var(--skel-r, 999px); }
.skel-circle { border-radius: var(--skel-circle-r, 50%); aspect-ratio: 1; }
.skel-block { border-radius: var(--skel-r, var(--r-inner)); }
@media (prefers-reduced-motion: reduce) {
  :is(.skel, .skel-line, .skel-circle, .skel-block) { animation: none; }
}

/* ═══ 徽标 ═══════════════════════════════════════════════════════════
   文字旁的小标记。颜色用 is-ok / is-danger / is-warn 切换。 */
:is(.badge-soft, .badge-solid, .badge-outline, .badge-glass) {
  display: inline-flex; align-items: center; gap: 3px;
  padding: var(--badge-pad, 1px 8px);
  border-radius: var(--badge-r, var(--r-pill));
  border: var(--bw) solid transparent;
  font-size: var(--badge-fs, var(--fs-xs)); font-weight: 700; line-height: 1.5;
  letter-spacing: .02em; white-space: nowrap;
  font-variant-numeric: tabular-nums;
  vertical-align: middle;
  --_c: var(--badge-c, var(--blue2));
  --_rgb: var(--badge-rgb, var(--blue-rgb));
}
.badge-soft { background: rgba(var(--_rgb), .13); color: var(--_c); }
.badge-outline { background: var(--surface-muted); border-color: rgba(var(--_rgb), .35); color: var(--_c); font-weight: 400; }
.badge-solid { background: var(--badge-solid-bg, var(--accent-fill)); color: var(--on-accent); }
.badge-glass {
  background: var(--chip-fill, rgba(255,255,255,.82)); color: var(--text);
  -webkit-backdrop-filter: var(--glass-thin); backdrop-filter: var(--glass-thin);
  font-weight: 400;
}
.is-muted:is(.badge-soft, .badge-outline) { --badge-c: var(--text3); }
.is-ok:is(.badge-soft, .badge-outline, .badge-solid) { --badge-c: var(--ok-text); --badge-rgb: 22, 163, 74; --badge-solid-bg: var(--ok-solid, var(--ok)); }
.is-danger:is(.badge-soft, .badge-outline, .badge-solid) { --badge-c: var(--danger-text); --badge-rgb: 220, 38, 38; --badge-solid-bg: var(--danger); }
.is-warn:is(.badge-soft, .badge-outline, .badge-solid) { --badge-c: var(--warn-text); --badge-rgb: 245, 158, 11; --badge-solid-bg: var(--warn-solid, var(--warn)); }
.is-sm:is(.badge-soft, .badge-solid, .badge-outline, .badge-glass) { --badge-pad: 0 6px; --badge-fs: 10px; }


/* ═══ 头像 ═══════════════════════════════════════════════════════════
   avatar-ring：3px 白边 + 2px --bow 外环 + 投影，用于人物主头像。
   avatar-round：圆形裁切加一道细边，用于列表与回复里的小头像。
   尺寸写在 --avatar-size，圆角写在 --avatar-r（缺省 50%，方形皮肤改为 0）。 */
:is(.avatar-ring, .avatar-round) {
  display: block; flex: none;
  width: var(--avatar-size, 64px); height: var(--avatar-size, 64px);
  border-radius: var(--avatar-r, 50%); object-fit: cover;
}
.avatar-ring {
  border: 3px solid var(--avatar-edge, rgba(255,255,255,.95));
  box-shadow: 0 0 0 2px var(--avatar-ring, var(--bow)),
              calc(var(--shadow-dx) * 6px) 8px 22px rgba(var(--blue-rgb), .25);
}
.avatar-round {
  --avatar-size: 24px;
  border: 2px solid var(--avatar-edge, rgba(255,255,255,.9));
  box-shadow: 0 0 0 1px var(--avatar-ring, var(--bow));
}
[data-theme="dark"] :is(.avatar-ring, .avatar-round) { --avatar-edge: rgba(255,255,255,.3); }


/* ═══ 列表行 ═════════════════════════════════════════════════════════
   .list-divided 的直接子元素之间画一道细分隔线。 */
.list-divided > * + * { border-top: 1px solid var(--list-divider, var(--divider)); }
.list-row {
  display: flex; align-items: center; gap: var(--list-gap, 10px);
  padding: var(--list-pad, 8px 0);
  min-width: 0;
  font-size: var(--fs-md); color: var(--text);
}
.list-row > .list-grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row > .list-end { flex: none; color: var(--list-end-fg, var(--blue2)); font-size: var(--fs-sm); white-space: nowrap; font-variant-numeric: tabular-nums; }
.list-row > img { width: 22px; height: 22px; object-fit: contain; flex: none; }


/* ═══ 小件 ═══════════════════════════════════════════════════════════ */
/* 带星形的卡片标题；星形是 theme.css 的 --star-mask 遮罩，随 currentColor，不依赖字体 */
.title-star {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 var(--s-3);
  font-family: var(--font-display); font-size: var(--fs-lg); font-weight: 700;
  letter-spacing: .02em; color: var(--text);
}
.title-star::before {
  content: ''; flex: none; width: 11px; height: 11px;
  background: var(--blue);
  -webkit-mask: var(--star-mask) center / contain no-repeat;
          mask: var(--star-mask) center / contain no-repeat;
}
/* 眉题：11px、.18em 字距；is-rule 在右侧延伸一道细线 */
.eyebrow {
  display: flex; align-items: center; gap: 8px;
  font-size: var(--fs-xs); font-weight: 400; letter-spacing: .18em; color: var(--eyebrow-fg, var(--text3));
}
.eyebrow.is-rule::after { content: ''; flex: 1; height: 1px; background: rgba(var(--bow-rgb), .35); }
/* 键帽 */
.kbd {
  display: inline-block;
  padding: 1px 6px;
  border-radius: var(--r-xs);
  border: var(--bw) solid var(--border);
  background: var(--surface-strong);
  color: var(--text3);
  font: 400 var(--fs-xs)/1.4 var(--font-sans);
}

/* 仅供读屏使用的文字与 live 区：不占位、不可见，仍在无障碍树中 */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* hidden 属性：浏览器默认的 display:none 优先级低于任何作者样式，
   上面给控件写了 display，这里补回。 */
:is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost, .btn-icon,
    .pill-soft, .pill-outline, .pill-solid, .pill-row, .seg, .seg-item,
    .field, .field-glass, .field-wrap, .surface-glass, .surface-flat, .surface-float, .surface-aurora, .surface-smoke,
    .menu-float, .pop-float, .tip-float, .tile-ghost, .tile-flat, .scrim, .toast, .state, .state-line, .list-row, .title-star, .eyebrow, .kbd,
    .badge-soft, .badge-solid, .badge-outline, .badge-glass, .avatar-ring, .avatar-round)[hidden] { display: none; }

/* 减少动态效果：按钮、胶囊、分段项没有位移与缩放的弹回，状态变化直接切换；
   关闭钮的悬停旋转一并取消。 */
@media (prefers-reduced-motion: reduce) {
  :is(.btn-solid, .btn-glass, .btn-outline, .btn-ghost, .btn-icon,
      .pill-soft, .pill-outline, .pill-solid, .seg-item),
  .btn-icon.is-corner {
    transition: none;
  }
  .btn-icon.is-corner:hover { rotate: none; }
}

/* 强制配色（Windows 高对比度）：背景色与渐变被系统改写，靠颜色区分的选中态
   会消失。选中态改用 Highlight / HighlightText 实心填充；滑块是叠在项下面的
   装饰层，此时隐藏，由各项自己填色。星屑类装饰层不承载信息，直接隐藏。 */
@media (forced-colors: active) {
  .nav-slider, .seg-thumb { display: none; }
  .read-progress > i { background: Highlight; }
  :is(.site-nav a[aria-current], .site-nav a.active,
      .seg-item:is([aria-selected="true"], [aria-pressed="true"], [aria-checked="true"], [aria-current="page"], .is-on),
      :is(.pill-soft, .pill-outline):is([aria-pressed="true"], [aria-selected="true"], [aria-checked="true"], [aria-current="true"], [aria-current="page"], .is-on),
      .pill-solid,
      [role="tab"][aria-selected="true"],
      [role="menuitemradio"][aria-checked="true"],
      [role="option"][aria-selected="true"]) {
    forced-color-adjust: none;
    /* !important：无滑块的 .seg 与皮肤给选中段写了渐变底与投影，特异性更高 */
    background: Highlight !important;
    box-shadow: none !important;
    color: HighlightText !important;
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  .btn-icon:is([aria-pressed="true"], .is-on) {
    forced-color-adjust: none;
    outline: 2px solid Highlight;
    outline-offset: 0;
  }
  input[type="checkbox"].switch { forced-color-adjust: none; background: Canvas; border-color: ButtonText; }
  input[type="checkbox"].switch::before { background: ButtonText; }
  input[type="checkbox"].switch:checked { background: Highlight; border-color: Highlight; }
  input[type="checkbox"].switch:checked::before { background: HighlightText; }
  input[type="checkbox"].switch:disabled { border-color: GrayText; }
  input[type="checkbox"].switch:disabled::before { background: GrayText; }
  #stardust-canvas, .hero-stars, .av-star, .sparkle, .bg-deco { display: none; }
}

} /* @layer ui */
