html, body, #root {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  background: transparent;
  overflow: hidden;
}

body {
  background: transparent;
  user-select: none;
  -webkit-user-select: none;
}

#root {
  display: flex;
  isolation: isolate;
}

button {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: transparent;
  color: inherit;
  padding: 0;
  /* Windows Chromium / WebView2 默认 user-agent style 会给 <button> 加 OS-native
     appearance（outset 边框 + 内阴影）、min-width / min-height（让 button 至少容下
     系统外观）、:focus 时的实线 outline。这些在 Vocab 词条这种嵌套 button 上叠加
     起来变成一圈灰色"大圈"。macOS WKWebView 处理较弱所以看不出来。一次性清掉。
     键盘焦点指示统一走 .ol-focus-ring + :focus-visible 走 box-shadow（不受 outline:0 影响）。 */
  appearance: none;
  -webkit-appearance: none;
  outline: none;
  min-width: 0;
  min-height: 0;
  box-sizing: border-box;
}

@keyframes ol-select-pop {
  from { opacity: 0; transform: translateY(-4px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* SelectLite popover 关闭动画 —— 反向收缩 + 淡出 + 上移，跟入场对偶。 */
@keyframes ol-select-pop-out {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(-4px) scale(.98); }
}

/* 键盘焦点指示：鼠标点击 (:focus) 不显示，键盘 Tab (:focus-visible) 才显示。
   用 box-shadow 而非 outline 是因为组件内联 style 可能用 outline:none
   把默认 ring 干掉，box-shadow 不受影响仍能上色。配合 pr-agent #407 的 a11y 要求。 */
.ol-focus-ring:focus-visible {
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.45);
}

input, textarea {
  font-family: inherit;
  user-select: text;
  -webkit-user-select: text;
}

a { color: inherit; text-decoration: none; }

@keyframes ol-window-enter {
  from {
    opacity: 0;
    transform: translate3d(0, 8px, 0) scale(0.992);
    filter: blur(8px);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
    filter: blur(0);
  }
}

@keyframes ol-modal-backdrop-in {
  from { opacity: 0; backdrop-filter: blur(0); -webkit-backdrop-filter: blur(0); }
  to   { opacity: 1; backdrop-filter: blur(8px) saturate(140%); -webkit-backdrop-filter: blur(8px) saturate(140%); }
}

@keyframes ol-modal-backdrop-out {
  from { opacity: 1; backdrop-filter: blur(8px) saturate(140%); -webkit-backdrop-filter: blur(8px) saturate(140%); }
  to   { opacity: 0; backdrop-filter: blur(0); -webkit-backdrop-filter: blur(0); }
}

@keyframes ol-modal-drawer-in {
  from {
    opacity: 0;
    transform: translate3d(12px, 0, 0) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@keyframes ol-modal-drawer-out {
  from {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
  to {
    opacity: 0;
    transform: translate3d(12px, 0, 0) scale(0.985);
  }
}

/* ── 假毛玻璃面（qa 追问框 / capsule 语音胶囊等透明浮窗）─────────────────────
   webview 拿不到透明窗口背后的桌面像素 —— CSS backdrop-filter 模糊不了桌面，
   是 Tauri 已知的上游限制（issue #2827 / #10064 / #6876）。所以这里**不做
   真实高斯模糊**：宿主元素保留半透明白底，这层 ::before 叠一张细颗粒噪点纹理
   （磨砂质感来源）；内描边高光与柔和阴影由宿主自带的 box-shadow 提供。
   纯静态 CSS，零运行时 / 动画开销，macOS / Windows / Linux 像素一致。
   宿主元素自带 border-radius 即可，::before 噪点层 inherit 圆角；宿主不要再设
   backdrop-filter（死代码）。 */
.ol-frost {
  position: relative;
  isolation: isolate;
  /* 体渐变 + 左上高光扫面 —— 半透明白底（~0.9），给磨砂面体积感而不是死平。 */
  background:
    radial-gradient(135% 86% at 15% -10%,
      rgba(255, 255, 255, 0.97) 0%,
      rgba(255, 255, 255, 0) 56%),
    linear-gradient(161deg,
      rgba(255, 255, 255, 0.93) 0%,
      rgba(244, 247, 252, 0.88) 100%);
}

.ol-frost::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  /* 不透明灰度噪点，normal 混合 —— 这是"磨砂颗粒"的来源。opacity 直接等于颗粒
     强度：0.1 几乎看不见，0.32 能明显看出磨砂质感又不脏。要更糙往 0.45 调。 */
  background-image: var(--ol-frost-grain);
  /* tile 与 SVG 视口同尺寸（100），stitchTiles 的无缝拼接才成立 */
  background-size: 100px 100px;
  opacity: 0.32;
  pointer-events: none;
}
