/* ============================================================================
 * cfapi.ak888.chat —— 主题与动效层（theme.css）
 *
 * 定位：**在 app.css 之后加载**，只做「观感」——背景、光影、质感、动效。
 *       不改任何布局契约（尺寸 / 间距 / 网格 / 断点）都由 app.css 说了算。
 * 配套：fx.js（滚动进度、入场上浮、按钮涟漪、边框跟随光标、积分闪光）。
 *
 * ⚠ 四条**不能碰**的红线（tools/ui-layout-test.py 直接断言，踩过就红）：
 *   1) 卡片/面板 `border-radius` 必须 ≤ 10px（"克制，不是游戏风大圆角"）；
 *   2) 主按钮**不能有** background-image（不许渐变按钮）；
 *   3) 主按钮**不能有** box-shadow（不许光晕）；
 *   4) 控件高度必须 38px（按钮 / 输入框都走 --ctl-h）。
 *   另外 `body` 的 backgroundColor 必须是浅色（测试按亮度判定"前台默认浅色"），
 *   所以渐变只能加在 **background-image** 上，不许动 body 的底色。
 *
 * ⚠ 资产展示区（.darkzone）里的一切都走 app.css 的深色令牌，本文件不动它 ——
 *   只补一个「内高光」令牌，深色下自动收小。
 * ========================================================================== */

/* ================= 1. 背景：柔和的多层渐变（薄雾，不是色块） =================
 * 六层叠加：右上主光 + 左上暖调 + 右侧紫调 + 左下水汽 + 底部回光 + 竖向底色。
 * 全部是低透明度的大半径 radial-gradient —— 边界互相吃掉，肉眼看不出"圈"，
 * 只有一层淡淡的色彩流动感。这就是"柔和"的关键：**不要出现明显的圆形轮廓**。
 * （百分比是相对视口算的：body 上有 background-attachment: fixed。） */
:root {
  --bg-grad:
    radial-gradient(1400px 720px at 76% -16%, rgba(76, 141, 255, .20), transparent 60%),
    radial-gradient(1080px 600px at 2% -8%, rgba(217, 58, 63, .09), transparent 60%),
    radial-gradient(1200px 760px at 99% 36%, rgba(129, 116, 240, .11), transparent 62%),
    /* ★ 左中这一层是**量出来的**：第一版只在右上/右中给了色，
       实测左侧空白区几乎没变化（Δ 只有 -1.7），整页看着"一边有色一边发白"。
       补上左中冷调之后左右才对称（实测 Δ≈-7）。 */
    radial-gradient(900px 560px at 0% 46%, rgba(76, 141, 255, .10), transparent 62%),
    radial-gradient(1000px 640px at 8% 78%, rgba(45, 168, 168, .09), transparent 60%),
    radial-gradient(900px 560px at 64% 104%, rgba(76, 141, 255, .11), transparent 64%),
    linear-gradient(178deg, #eef4fe 0%, #f4f8fd 34%, #f7f9fc 62%, #f2f6fc 100%);

  /* 动效令牌 */
  --fx-ease: cubic-bezier(.22, .61, .36, 1);          /* 通用（进出都稳） */
  --fx-ease-out: cubic-bezier(.16, 1, .3, 1);         /* 入场（尾巴长，收得柔） */
  --fx-dur: .3s;

  /* 三级高度：e1 贴地 / e2 悬浮 / e3 抬起 */
  --fx-e1: 0 1px 2px rgba(16, 24, 40, .035);
  --fx-e2: 0 1px 2px rgba(16, 24, 40, .04), 0 16px 34px -28px rgba(16, 24, 40, .26);
  --fx-e3: 0 2px 5px rgba(16, 24, 40, .05), 0 30px 58px -32px rgba(16, 24, 40, .34);
  --fx-ring: 0 0 0 3px rgba(37, 99, 235, .13);        /* 输入框聚焦柔光 */

  /* 表面内高光 / 顶部光带：浅色下是白，深色下几乎没有 */
  --fx-hl: rgba(255, 255, 255, .72);
  --fx-sheen: rgba(255, 255, 255, .55);
}

/* 深色（后台 / 资产展示区）：内高光收小，别在暗面上糊一层白 */
:root[data-theme="dark"], .darkzone {
  --fx-hl: rgba(255, 255, 255, .05);
  --fx-sheen: rgba(255, 255, 255, .025);
  --fx-ring: 0 0 0 3px rgba(76, 141, 255, .18);
}

/* ================= 2. 表面：更柔的阴影 + 一条内高光 =================
 * 原来的面板是「1px 描边 + 平面白」，在白底上几乎没有层次。
 * 这里加两样东西，观感立刻从"网页表格"变成"卡片"：
 *   · 一层很淡的落影（越远越虚，不是硬边）
 *   · 顶部一条 1px 内高光（模拟顶光打在上边缘）
 * 圆角 8 → 10px（红线是 ≤10，取上限）。 */
.panel,
.card {
  border-radius: 10px;
  border-color: rgba(219, 227, 238, .95);
  box-shadow: inset 0 1px 0 var(--fx-hl), var(--fx-e2);
  transition: box-shadow var(--fx-dur) var(--fx-ease),
              border-color var(--fx-dur) var(--fx-ease),
              transform var(--fx-dur) var(--fx-ease);
}

/* 桌面：顶层块悬停时轻微抬起（只抬 2px，不给光晕、不改尺寸） */
@media (hover: hover) and (pointer: fine) {
  .wrap > .panel:hover,
  .wrap > .card:hover {
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 var(--fx-hl), var(--fx-e3);
    border-color: rgba(200, 212, 228, 1);
  }
}

/* 面板标题栏：平涂 → 顶部一条极淡的光带（有"层"了，但看不出渐变） */
.panel-hd,
.modal-hd {
  background-image: linear-gradient(180deg, var(--fx-sheen), rgba(255, 255, 255, 0));
}
.panel-t { letter-spacing: .015em; }

/* ================= 3. 控件：手感（过渡 / 按压 / 涟漪 / 聚焦） =================
 * 注意：**不给按钮加渐变、不给按钮加阴影**（红线 2/3）。手感靠"位移 + 过渡"。 */
.btn {
  position: relative;                 /* 涟漪的定位父级 */
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .18s var(--fx-ease),
              border-color .18s var(--fx-ease),
              color .18s var(--fx-ease),
              transform .12s var(--fx-ease);
}
.btn:active { transform: translateY(1px); }        /* 按下"沉"一下，不用 scale（别动几何） */
.btn:disabled { transform: none; }

/* 点击涟漪（fx.js 插入 .fx-rip）。用 currentColor：
   primary 上是白涟漪，ghost 上是深色涟漪 —— 一套样式通吃双主题。 */
.fx-rip {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, currentColor 0%, transparent 68%);
  opacity: .28; transform: scale(0);
  animation: fxRip .55s cubic-bezier(.2, .7, .3, 1) forwards;
}
@keyframes fxRip { to { transform: scale(1); opacity: 0; } }

/* 输入框：聚焦时给一圈柔光（不改高度、不改边框颜色） */
.input:focus { box-shadow: var(--fx-ring); }
.input { transition: border-color .18s var(--fx-ease), background-color .18s var(--fx-ease), box-shadow .22s var(--fx-ease); }

/* 页签：hover 有底、切态有过渡（原来只有颜色突变） */
.tab {
  border-radius: 8px 8px 0 0;
  transition: color .18s var(--fx-ease), border-color .22s var(--fx-ease),
              background-color .18s var(--fx-ease);
}
@media (hover: hover) and (pointer: fine) {
  .tab:hover { background-color: var(--surface2); }
}

/* 表格行悬停（只在有指针的设备上） */
@media (hover: hover) and (pointer: fine) {
  .tablewrap tbody tr:hover { background-color: var(--surface2); }
}

/* ================= 4. 顶栏：滚动进度 + 滚动状态 =================
 * 顶栏本来就有 ::before 那条 2px 品牌线（在流内、不随滚动变化）。
 * 这里补一条 ::after **压在它上面**，用 transform: scaleX(var(--fx-p)) 当阅读进度：
 *   · 锚在 0 时 scaleX(0) → 完全看不见，露出的还是原来那条品牌线（观感零变化）
 *   · 用 transform 而不是 width —— 宽度变化会每帧触发重排，scale 走合成层
 * z-index / 高度都不动，导航测试量的那些值一个不变。 */
.topbar {
  transition: box-shadow var(--fx-dur) var(--fx-ease),
              background-color var(--fx-dur) var(--fx-ease);
}
.topbar::after {
  content: ''; position: absolute; left: 0; top: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--ac), var(--ac2) 38%, var(--blue));
  transform: scaleX(var(--fx-p, 0)); transform-origin: 0 50%;
  pointer-events: none; opacity: .95;
}
.topbar.fx-scrolled {
  box-shadow: 0 12px 30px -20px rgba(16, 24, 40, .30);
}

/* ================= 5. 动效：入场上浮 / 弹层 / 积分闪光 =================
 * .fx-rise 是 **JS 加上的**（fx.js 只给"首屏之外"的元素加）：
 * 万一 JS 挂了或跑得慢，页面上的内容始终是完全可见的 —— 不会出现"一片空白"。 */
.fx-rise { opacity: 0; transform: translateY(10px); }
.fx-rise.fx-in { animation: fxRise .5s var(--fx-ease-out) both; }
@keyframes fxRise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* 弹层入场：只做「上浮 + 淡入」，**不用 scale** ——
   有测试会量 .modal-in 的宽度，缩放会让它在动画中途量到偏小的值。 */
.modal.on .modal-in { animation: fxPop .3s var(--fx-ease-out) both; }
@keyframes fxPop {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* 积分变化时闪一圈光（fx.js 监听 #ptsAll 文本变化）。
   用 box-shadow 扩散，**不动几何** —— 顶栏控件尺寸有测试盯着。 */
.pill.pts.fx-flash { animation: fxFlash .7s var(--fx-ease); }
@keyframes fxFlash {
  0%   { box-shadow: 0 0 0 0 rgba(37, 99, 235, .34); }
  100% { box-shadow: 0 0 0 10px rgba(37, 99, 235, 0); }
}

/* ================= 6. 细节：滚动条 / 选中 / 焦点 ================= */
@media (min-width: 721px) and (pointer: fine) {
  html { scrollbar-width: thin; scrollbar-color: var(--line2) transparent; }
  html::-webkit-scrollbar { width: 12px; height: 12px; }
  html::-webkit-scrollbar-track { background: transparent; }
  html::-webkit-scrollbar-thumb {
    background-color: var(--line2); border-radius: 999px;
    border: 3px solid transparent; background-clip: content-box;
  }
  html::-webkit-scrollbar-thumb:hover { background-color: var(--tx4); }
}

::selection { background: rgba(217, 58, 63, .16); }

/* 键盘焦点：给一条柔和的蓝圈；输入框自己有柔光，就不叠加轮廓了 */
:focus-visible { outline: 2px solid rgba(37, 99, 235, .5); outline-offset: 2px; }
.input:focus-visible, select:focus-visible { outline: none; }

/* ================= 7. 面板边框跟随光标（外链 CSS+JS 的那点"高级感"） =================
 * 做法：1px 的描边圈上用 mask 挖空内容区，只让"边框本身"被一圈光扫到。
 * 只在**支持 mask-composite** 的浏览器生效 —— 不支持时整块规则不解析，
 * 否则那圈 radial-gradient 会铺满整个面板（压住正文），所以这个 @supports 是必须的。
 * 光只落在 1px 边框上，正文不受影响。 */
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .panel { position: relative; }        /* .item / .pcard 自带 relative，面板没有 */
  .panel::after {
    content: ''; position: absolute; inset: 0; padding: 1px;
    border-radius: inherit;
    background: radial-gradient(240px circle at var(--fx-mx, 50%) var(--fx-my, 50%),
                rgba(37, 99, 235, .40), rgba(37, 99, 235, 0) 72%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
    opacity: 0; transition: opacity var(--fx-dur) var(--fx-ease);
    pointer-events: none;
  }
  @media (hover: hover) and (pointer: fine) {
    .panel:hover::after { opacity: 1; }
  }
}

/* ================= 8. 手机端：底部留出安全区 ================= */
@media (max-width: 720px) {
  .wrap { padding-bottom: calc(36px + env(safe-area-inset-bottom, 0px)); }
  /* 手机上不做"抬升"，改成"按下变色"—— 触屏上悬停本来就不存在 */
  .btn:active { background-color: var(--surface3); }
}

/* ================= 9. 减少动态效果（系统级偏好） =================
 * 一律**保留结果、去掉过程**：内容照常显示，只是不再动。 */
@media (prefers-reduced-motion: reduce) {
  .fx-rise, .fx-rise.fx-in {
    opacity: 1 !important; transform: none !important; animation: none !important;
  }
  .fx-rip { display: none; }
  .topbar::after { display: none; }
  .modal.on .modal-in, .pill.pts.fx-flash { animation: none; }
  .btn, .input, .tab, .panel, .card, .topbar, .panel-hd {
    transition: none !important;
  }
  .wrap > .panel:hover, .wrap > .card:hover { transform: none; }
}
