/* Bubble texture presets. Every color is derived from the active theme (no color literals).
   Load after css/chat/chat-render.css. "plain" adds no overrides at all.
   - 每一档的「标志性内阴影」都收在 --kb-inset / --kb-inset-user 里，
     基础态与悬停态共用这两个变量 —— 悬停时不会把该档的质感换掉。
   - 发送失败的气泡走 :not(.msg-failed)，一律不吃这些规则，
     警告外观完全由 css/chat/chat-render.css 的 .msg.user.msg-failed 决定（不复制第二份常量）。 */

/* ===== 磨砂玻璃 ===== */
html[data-bubble="frost"] {
    --kb-inset: inset 0 1px 0 color-mix(in srgb, var(--text-primary) 10%, transparent),
                inset 0 -1px 0 color-mix(in srgb, var(--text-primary) 4%, transparent);
    --kb-inset-user: inset 0 1px 0 color-mix(in srgb, var(--glass-border, var(--border, rgba(255, 255, 255, 0.3))) 70%, transparent);
}
/* ★ 2026-10-30 磨砂气泡不再用 backdrop-filter（宝宝：「聊了一会儿之后往上翻特别卡，不加载新消息也卡」）。
   实测：300 条气泡 = 300 个模糊层，手指一滑每一帧都要把它们**背后**的东西重新采样模糊一遍
   （p95 从 16.7ms 掉到 33.4ms、约 20~30 帧/秒），只放 60 条又满帧 —— 正好对上「聊久了才卡」。
   气泡背后本来就是主题的渐变 + 封面图，把底色抬到 88% 不透明后肉眼几乎没差，却不需要任何实时模糊。
   绝不许把 backdrop-filter 加回气泡：要更透就调这个百分比，不要调模糊。 */
html[data-bubble="frost"] .msg.assistant .bubble,
html[data-bubble="frost"] .msg.user:not(.msg-failed) .bubble {
    border-color: var(--glass-border, var(--border, rgba(255, 255, 255, 0.3)));
}
html[data-bubble="frost"] .msg.assistant .bubble {
    background-color: color-mix(in srgb, var(--bubble-assistant) 88%, transparent);
    box-shadow: var(--kb-inset), var(--shadow-sm);
}
html[data-bubble="frost"] .msg.user:not(.msg-failed) .bubble {
    background-color: color-mix(in srgb, var(--bubble-user) 88%, transparent);
    box-shadow: var(--kb-inset-user), 0 2px 12px var(--bubble-user-glow);
}

/* ===== 纸感哑光 ===== */
html[data-bubble="matte"] {
    --kb-inset: inset 0 1px 0 color-mix(in srgb, var(--text-primary) 5%, transparent),
                inset 0 -1px 0 color-mix(in srgb, var(--text-primary) 4%, transparent);
    --kb-inset-user: inset 0 1px 0 color-mix(in srgb, var(--glass-border, var(--border, rgba(255, 255, 255, 0.3))) 58%, transparent);
}
html[data-bubble="matte"] .msg.assistant .bubble,
html[data-bubble="matte"] .msg.user:not(.msg-failed) .bubble {
    background-image: linear-gradient(160deg,
        color-mix(in srgb, var(--text-primary) 3%, transparent),
        transparent 58%);
}
html[data-bubble="matte"] .msg.assistant .bubble {
    box-shadow: var(--kb-inset), var(--shadow-sm);
}
html[data-bubble="matte"] .msg.user:not(.msg-failed) .bubble {
    box-shadow: var(--kb-inset-user), 0 2px 12px var(--bubble-user-glow);
}

/* ===== 丝绒 ===== */
html[data-bubble="velvet"] {
    --kb-inset: inset 0 2px 3px color-mix(in srgb, var(--text-primary) 9%, transparent),
                inset 0 1px 0 color-mix(in srgb, var(--glass-border, var(--border, rgba(255, 255, 255, 0.3))) 45%, transparent);
    --kb-inset-user: inset 0 2px 3px color-mix(in srgb, var(--text-primary) 8%, transparent),
                     inset 0 1px 0 color-mix(in srgb, var(--glass-border, var(--border, rgba(255, 255, 255, 0.3))) 45%, transparent);
}
html[data-bubble="velvet"] .msg.assistant .bubble,
html[data-bubble="velvet"] .msg.user:not(.msg-failed) .bubble {
    background-image: linear-gradient(145deg,
        color-mix(in srgb, var(--text-primary) 7%, transparent),
        transparent 42%,
        color-mix(in srgb, var(--text-primary) 3%, transparent));
}
html[data-bubble="velvet"] .msg.assistant .bubble {
    box-shadow: var(--kb-inset), var(--shadow-sm);
}
html[data-bubble="velvet"] .msg.user:not(.msg-failed) .bubble {
    box-shadow: var(--kb-inset-user), 0 2px 12px var(--bubble-user-glow);
}

/* ===== 描金细线 ===== */
html[data-bubble="goldline"] {
    --kb-inset: inset 0 0 0 1px color-mix(in srgb, var(--accent, var(--rose, #c8a87c)) 24%, transparent),
                inset 0 1px 0 color-mix(in srgb, var(--glass-border, var(--border, rgba(255, 255, 255, 0.3))) 65%, transparent);
}
html[data-bubble="goldline"] .msg.assistant .bubble,
html[data-bubble="goldline"] .msg.user:not(.msg-failed) .bubble {
    border-color: var(--accent, var(--rose, #c8a87c));
}
html[data-bubble="goldline"] .msg.assistant .bubble {
    box-shadow: var(--kb-inset), var(--shadow-sm);
}
html[data-bubble="goldline"] .msg.user:not(.msg-failed) .bubble {
    box-shadow: var(--kb-inset), 0 2px 12px var(--bubble-user-glow);
}

/* ===== 透明描边 ===== */
html[data-bubble="outline"] {
    --kb-inset: inset 0 0 0 1px color-mix(in srgb, var(--border) 55%, transparent);
    --kb-inset-user: var(--kb-inset);
}
html[data-bubble="outline"] .msg.assistant .bubble,
html[data-bubble="outline"] .msg.user:not(.msg-failed) .bubble {
    background-color: transparent;
    background-image: none;
    border-color: var(--glass-border, var(--border, rgba(255, 255, 255, 0.3)));
    box-shadow: var(--kb-inset);
}
html[data-bubble="outline"] .msg.user:not(.msg-failed) .bubble {
    border-color: var(--bubble-user-glow);
}

/* ===== 悬停：保留该档自己的内阴影，只加抬起的投影 ===== */
html[data-bubble]:not([data-bubble="plain"]) .msg.assistant .bubble:hover {
    box-shadow: var(--kb-inset), var(--shadow-md);
}
html[data-bubble]:not([data-bubble="plain"]) .msg.user:not(.msg-failed) .bubble:hover {
    box-shadow: var(--kb-inset-user, var(--kb-inset)), 0 4px 18px var(--bubble-user-glow);
}
