/* ============================================================
   基础样式 - 布局与组件结构
   主题颜色由主题文件（theme-*.css）通过 CSS 变量覆盖
   ============================================================ */

html {
    /* 阻止 Safari 自动放大字号（默认会放大 input/textarea 周围文字） */
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: linear-gradient(135deg, var(--bg-body-from) 0%, var(--bg-body-to) 100%);
    min-height: 100vh;
    min-height: -webkit-fill-available;  /* iOS Safari 13~16.3:精确等于可见区域（不含 URL 栏） */
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    overflow: hidden;
    overscroll-behavior: none;            /* iOS 橡皮筋禁用,防止页面跳动 */
    -webkit-text-size-adjust: 100%;      /* 阻止 Safari 自动放大字号 */
    transition: background 0.3s ease;
}

.box {
    display: flex;
    /* 四层兜底链（从老到新，后写后赢）：
       - 100vh                 老浏览器 / Android 4
       - -webkit-fill-available iOS Safari 13~16.3:精确等于可见区域（不含 URL 栏）
       - 100svh                iOS Safari 16.4+ / Chrome 108+:URL 栏显示时的保守最小高度
       - 100dvh                Chrome 108+ / iOS 16.4+:动态视口（包含 URL 栏变化）
       JS 接管后通过 .visual-viewport-active + !important 强制覆盖为精确值。 */
    height: 100vh;
    height: -webkit-fill-available;
    height: 100svh;
    height: 100dvh;
    /* iPhone 灵动岛 / 状态栏 / 底部 home indicator 留白
       需要 viewport-fit=cover 才生效,默认回退到 0（无留白,行为不变） */
    padding-top: env(safe-area-inset-top, 0);
    padding-bottom: env(safe-area-inset-bottom, 0);
}

/* JS 在 bindVirtualViewport 中持续更新 --visual-viewport-height，
   并给 .box 加 visual-viewport-active 类，让 .box 高度跟随真实可视区域。
   这一步解决了 vh / dvh 在 iOS Safari 滑入滑出工具栏时的偏差。 */
.box.visual-viewport-active {
    height: var(--visual-viewport-height, 100svh) !important;
}

#sidebar {
    width: 320px;
    min-width: 280px;
    max-width: 450px;
    background: linear-gradient(180deg, var(--sidebar-bg-from) 0%, var(--sidebar-bg-to) 100%);
    color: var(--sidebar-text);
    padding: 20px;
    box-shadow: 0 0 30px var(--shadow-primary);
    display: flex;
    flex-direction: column;
    position: relative;
    transition: all 0.3s ease;
    height: 100vh;
    overflow-y: auto;
    overflow-x: hidden;
    border-right: 3px solid var(--sidebar-border);
    backdrop-filter: blur(10px);
}

#chat-container {
    flex: 1;
    margin: 20px;
    border-radius: 20px;
    background-color: var(--bg-content);
    box-shadow: 0 10px 30px var(--shadow-black);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: transform 0.3s ease;
}

#chat-container:hover {
    transform: translateY(-5px);
}

#messages {
    flex-grow: 1;
    overflow-y: auto;
    padding: 25px;
    background-color: var(--bg-messages);
}

.message {
    margin-bottom: 20px;
    padding: 20px 28px;
    border-radius: 15px;
    box-shadow: 0 2px 10px var(--shadow-black-light);
    position: relative;
    max-width: 85%;
    animation: fadeInUp 0.3s ease-out forwards;
    border: 1px solid var(--border-light);
    font-size: 18px;
    line-height: 1.7;
}

.message.user-message {
    background-color: var(--bg-user-msg);
    color: var(--text-link);
    margin-left: auto;
    border-bottom-right-radius: 5px;
    border-left: 4px solid var(--accent-color);
}

.message.system-message {
    background-color: var(--bg-system-msg);
    color: var(--text-primary);
    margin-right: auto;
    border-bottom-left-radius: 5px;
    border-right: 4px solid var(--primary-color);
}

.message span {
    font-weight: 600;
    display: block;
    margin-bottom: 8px;
    font-size: 1.1rem;
}

.message.user-message span {
    color: var(--text-link);
    text-align: right;
}

.message.system-message span {
    color: var(--text-link);
}

#input-container {
    display: flex;
    flex-wrap: nowrap;           /* 显式：输入框与发送按钮永远保持同一行 */
    align-items: center;         /* 输入框与发送按钮在垂直方向居中对齐 */
    padding: 20px;
    background-color: var(--bg-input-area);
    gap: 15px;
    border-top: 1px solid var(--border-medium);
}

#message-input {
    flex-grow: 1;
    border-radius: 22px;
    padding: 12px 20px;
    border: 2px solid var(--border-input);
    background-color: var(--bg-input-field);
    color: var(--text-primary);
    transition: all 0.3s ease;
    box-shadow: 0 2px 10px var(--shadow-black-softer);
    font-size: 16px;
    /* textarea 自适应撑高：JS 控制 height，CSS 兜底。
       min-height = 52px 精确匹配 #send-button 实际高度
       (24 content + 24 padding + 4 border),让两者任何状态下都等高,
       align-items: center 居中时不会有 4px 错位 */
    min-height: 52px;
    max-height: 160px;
    resize: none;
    line-height: 1.5;
    overflow-y: auto;
    font-family: inherit;
    /* box-sizing 与 input 保持一致，避免 padding 影响宽度计算 */
    box-sizing: border-box;
    /* 显式 align-self: center,确保在某些浏览器(老 Safari/移动 WebView)
       即使容器 align-items: center 失效也能保持居中 */
    align-self: center;
    /* 移动端隐藏 textarea 滚动条:触摸滑动已足够,显示滚动条反而让 UI 显得粗糙
       桌面端也隐藏(滚动条宽度影响 textarea 内容宽度,容易导致文本抖动) */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

#message-input::-webkit-scrollbar {
    display: none;
}

#message-input:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 15px var(--shadow-primary);
    outline: none;
}

#send-button {
    background: linear-gradient(45deg, var(--primary-color), var(--primary-light));
    color: var(--text-on-primary);
    border: 2px solid var(--accent-color);
    padding: 12px 24px;
    border-radius: 30px;
    transition: all 0.3s ease;
    box-shadow: 0 4px 15px var(--shadow-primary);
    font-weight: 600;
    font-size: 16px;
    line-height: 1.5;             /* 显式 line-height 与 #message-input 对齐,确保内容高度一致 */
    white-space: nowrap;          /* 文字不被拆成两行 ("发送"、"撤销" 各占一行) */
    min-width: 72px;              /* 防止被挤压到完全变形 */
    flex-shrink: 0;               /* input flex-grow 时不让按钮被挤消失 */
    display: inline-flex;         /* 容器用 inline-flex,内部 <i> 图标 + 文字永远水平排 */
    align-items: center;          /* 内部垂直居中(撤销态带图标时不再 baseline 对齐错位) */
    justify-content: center;      /* 内部水平居中 */
    box-sizing: border-box;       /* 显式 border-box,确保 padding/border 不让按钮撑高 */
    align-self: center;           /* 显式覆盖容器 align-items,确保与 #message-input 垂直居中 */
    margin: 0;                    /* 覆盖 .btn-primary 全局 margin-bottom: 12px,
                                    那个 margin 是给侧栏"快捷操作"按钮用的,不该影响输入区发送按钮 */
}

#send-button:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px var(--shadow-primary-strong);
    background: linear-gradient(45deg, var(--primary-light), var(--accent-color));
    border-color: var(--accent-light);
}

#send-button:disabled {
    background: linear-gradient(45deg, #999, #777);
    border-color: #666;
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
    opacity: 0.6;
}

/* 撤销态：点击后按钮变红，提示可中止 */
#send-button.undo-state {
    background: linear-gradient(45deg, #d9534f, #c9302c);
    color: var(--text-on-primary);
    border: 2px solid #d43f3a;
    box-shadow: 0 4px 15px rgba(217, 83, 79, 0.4);
}

#send-button.undo-state:hover {
    background: linear-gradient(45deg, #c9302c, #d9534f);
    box-shadow: 0 6px 20px rgba(217, 83, 79, 0.6);
}

#send-button.undo-state:disabled {
    background: linear-gradient(45deg, #999, #777);
    border-color: #666;
    box-shadow: none;
    opacity: 0.6;
}

.btn-primary {
    background: linear-gradient(135deg, var(--primary-color), var(--primary-light));
    border: 2px solid var(--shadow-primary);
    padding: 12px 20px;
    border-radius: 12px;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    margin-bottom: 12px;
    font-weight: 600;
    font-size: 0.9rem;
    box-shadow: 0 4px 15px var(--shadow-primary);
    color: var(--text-on-primary);
    text-align: center;
    position: relative;
    overflow: hidden;
}

/* 侧栏快捷按钮双 label 切换:
   桌面端默认显示完整文字(.btn-text-desktop),隐藏短名(.btn-text-mobile);
   移动端媒体查询内反过来。文字放 span 里避免影响按钮图标和 aria 语义。 */
.btn-text-mobile {
    display: none;
}

.btn-primary::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, var(--shine), transparent);
    transition: left 0.5s;
}

.btn-primary:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 25px var(--shadow-primary-strong);
    background: linear-gradient(135deg, var(--primary-hover-1), var(--primary-hover-2));
    border-color: var(--shadow-primary-strong);
}

.btn-primary:hover::before {
    left: 100%;
}

.btn-primary:active {
    transform: translateY(-1px);
}

.history-item {
    cursor: pointer;
    padding: 16px 18px;
    margin-bottom: 10px;
    border-radius: 15px;
    background: linear-gradient(135deg, var(--bg-item-from) 0%, var(--bg-item-to) 100%);
    color: var(--text-primary);
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: 0 3px 12px var(--shadow-black-light);
    position: relative;
    padding-right: 50px;
    border: 1px solid var(--shadow-primary-soft);
    font-size: 0.9rem;
    line-height: 1.4;
}

.history-item:hover {
    background: linear-gradient(135deg, var(--bg-hover-light-from) 0%, var(--bg-hover-light-to) 100%);
    transform: translateX(8px) translateY(-2px);
    box-shadow: 0 6px 20px var(--shadow-primary-light);
    border-color: var(--shadow-primary);
}

.history-item.active {
    background: linear-gradient(135deg, var(--bg-active-from) 0%, var(--bg-active-to) 100%);
    border-left: 4px solid var(--primary-color);
    transform: translateX(8px);
    box-shadow: 0 4px 16px var(--shadow-primary);
    color: var(--text-link);
    font-weight: 500;
}

.history-item::after {
    content: '›';
    position: absolute;
    right: 15px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1.5rem;
    color: var(--primary-color);
    opacity: 0.7;
    transition: all 0.3s ease;
}

.history-item:hover::after {
    right: 10px;
    opacity: 1;
}

.delete-history-btn {
    position: absolute;
    right: 40px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--color-error);
    background: none;
    border: none;
    font-size: 1rem;
    cursor: pointer;
    opacity: 0.5;
    transition: all 0.3s ease;
    z-index: 5;
}

.delete-history-btn:hover {
    opacity: 1;
    transform: translateY(-50%) scale(1.2);
}

h5 {
    color: var(--primary-color);
    font-weight: 600;
    margin-top: 25px;
    margin-bottom: 15px;
    position: relative;
    padding-bottom: 8px;
}

h5::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    width: 50px;
    height: 3px;
    background: linear-gradient(45deg, var(--primary-color), var(--accent-color));
    border-radius: 3px;
}

/* 滚动条样式 - Webkit浏览器 */
::-webkit-scrollbar {
    width: 8px;
}

::-webkit-scrollbar-track {
    background: var(--scrollbar-track);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb {
    background: var(--scrollbar-thumb);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--primary-color);
}

/* Firefox 滚动条样式回退 */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
}

/* 侧边栏滚动条样式：更细 + 透明 track,只保留细 thumb 增加质感 */
#sidebar {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb-sidebar) transparent;
}

#sidebar::-webkit-scrollbar {
    width: 4px;
}

#sidebar::-webkit-scrollbar-track {
    background: transparent;
}

#sidebar::-webkit-scrollbar-thumb {
    background: var(--scrollbar-thumb-sidebar);
    border-radius: 2px;
    opacity: 0.6;
}

#sidebar::-webkit-scrollbar-thumb:hover {
    background: var(--primary-color);
    opacity: 1;
}

/* 历史记录列表的样式 */
#history-list {
    margin-bottom: 30px;
}

.sidebar-header,
.model-info,
.chat-info,
.history-info {
    padding-right: 15px;
}

/* 聊天页面的头部 */
.chat-header {
    background-color: var(--bg-chat-header);
    border-bottom: 1px solid var(--border-medium);
    padding: 20px 25px !important;
    position: relative;
}

.chat-header h5 {
    color: var(--primary-color);
    margin: 0;
    padding: 0;
    font-weight: 600;
}

.chat-header h5::after {
    display: none;
}

/* 版本号徽标：紧跟标题，圆角渐变（复用原 .model-badge 视觉） */
.app-version-inline {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 12px;
    background: linear-gradient(45deg, var(--accent-color), var(--accent-light));
    color: var(--primary-color);
    font-size: 0.7em;
    font-weight: 600;
    margin-left: 8px;
    vertical-align: middle;
    box-shadow: 0 2px 5px var(--shadow-accent);
    letter-spacing: 0.5px;
}

/* 移动端汉堡菜单按钮：默认隐藏在 chat-header 内，≤768px 才显示 */
#sidebar-toggle {
    display: none;
    background: none;
    border: none;
    color: var(--primary-color);
    font-size: 1.2rem;
    padding: 4px 8px;
    margin-right: 8px;
    cursor: pointer;
    border-radius: 6px;
    transition: background 0.2s ease;
    vertical-align: middle;
}

#sidebar-toggle:hover {
    background: var(--bg-hover-light-from);
}

#sidebar-toggle:active {
    transform: scale(0.95);
}

/* 侧栏抽屉遮罩：默认隐藏 */
#sidebar-backdrop {
    display: none;
}

/* 分子图骨架屏（hydrate 期间） */
.molecule-img.img-loading {
    opacity: 0.4;
    animation: imgPulse 1.2s ease-in-out infinite;
    background: linear-gradient(90deg, #f0f0f0 0%, #e0e0e0 50%, #f0f0f0 100%);
    background-size: 200% 100%;
}

@keyframes imgPulse {
    0%   { opacity: 0.4; }
    50%  { opacity: 0.7; }
    100% { opacity: 0.4; }
}

/* 移动端主题切换行：桌面端默认隐藏（移动端在下面的 @media 块内显示） */
.theme-row {
    display: none;
}

/* ============================================================
   移动端适配（方案 A：抽屉式响应式，≤768px 生效）
   桌面端样式不受影响
   ============================================================ */
@media (max-width: 768px) {
    /* 移动端：彻底隐藏 sidebar 滚动条（仅触屏滚动,无视觉干扰） */
    #sidebar::-webkit-scrollbar {
        display: none;
    }
    #sidebar {
        scrollbar-width: none;       /* Firefox */
        -ms-overflow-style: none;    /* IE/Edge 旧版 */
    }

    /* 移动端关键布局：sidebar 整体不滚,只让 #history-list 自身滚动
       这样 .theme-row 永远钉在视觉底部,内容多时也不会被滚走 */
    #sidebar {
        overflow: hidden;            /* 覆盖桌面端 overflow-y: auto */
    }
    #history-list {
        flex: 1;                     /* 占满 sidebar 剩余空间 */
        min-height: 0;               /* flex 子项允许收缩到内容以下 */
        overflow-y: auto;            /* 历史记录多时只滚这里 */
        margin-bottom: 12px;         /* 减小底部留白(原 30px,与 theme-row 间距更紧凑) */
        -webkit-overflow-scrolling: touch;  /* iOS 顺滑滚动 */
    }
    #history-list::-webkit-scrollbar {
        display: none;
    }

    /* 侧栏：固定定位的抽屉，默认隐藏在屏幕左侧 */
    #sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        width: 280px;
        max-width: 85vw;
        z-index: 1000;
        transform: translateX(-100%);
        transition: transform 0.3s ease;
        box-shadow: 4px 0 20px rgba(0, 0, 0, 0.3);
        /* 高度兜底链：避免 iOS Safari 把 sidebar 撑到 URL 栏后面,
           导致底部 theme-row 被 home indicator 完全遮挡 */
        height: 100vh;
        height: -webkit-fill-available;  /* iOS Safari 13~16.3 */
        height: 100dvh;                  /* iOS Safari 16.4+ / Chrome 108+ */
        /* 底部 padding 加上 safe-area-inset,让 theme-row 在 home indicator / 手势导航条上方 */
        padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
    }

    #sidebar.sidebar-open {
        transform: translateX(0);
    }

    /* 抽屉遮罩：移动端才显示，未展开时透明且不阻挡点击 */
    #sidebar-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.5);
        z-index: 999;
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.3s ease;
    }

    #sidebar-backdrop.open {
        opacity: 1;
        pointer-events: auto;
    }

    /* 显示汉堡菜单按钮 */
    #sidebar-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* 移动端把 hamburger 浮在 sidebar 抽屉之上(z-index 1000)：
       sidebar 打开时它仍是"关闭"按钮,不会被抽屉覆盖导致死锁;
       fixed 定位相对视口,sidebar 抽屉的 position:fixed;left:0 不会盖住它 */
    #sidebar-toggle {
        position: fixed;
        top: 12px;
        left: 12px;
        z-index: 1001;
        background: var(--bg-content, transparent);
        border-radius: 6px;
        padding: 6px 10px;
    }

    /* 聊天区全屏化：高度跟随 .box 的 svh/dvh/visual-viewport 策略 */
    #chat-container {
        margin: 0;
        border-radius: 0;
        box-shadow: none;
        height: 100vh;            /* 老浏览器兜底 */
        height: -webkit-fill-available;  /* iOS Safari 13~16.3 */
        height: 100svh;           /* 移动端保守：URL 栏显示时也撑不满 */
        height: 100dvh;           /* 现代浏览器动态视口 */
    }

    #chat-container:hover {
        transform: none;
    }

    /* 消息气泡：更宽、更紧凑、字号略小避免 iOS 自动放大 */
    .message {
        max-width: 95%;
        padding: 12px 16px;
        font-size: 16px;
        line-height: 1.6;
        margin-bottom: 12px;
    }

    .message span {
        font-size: 1rem;
        margin-bottom: 6px;
    }

    /* 输入区：紧凑布局 */
    #input-container {
        padding: 10px 12px;
        gap: 8px;
    }

    #send-button {
        padding: 10px 18px;
        font-size: 14px;
    }

    /* 侧栏快捷操作按钮：两行布局，第一行 2 个（新建对话 + 使用帮助），
       第二行 1 个（退出登录）。用 grid 替代桌面端的 flex 横排。 */
    .nav-buttons-container {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;
    }

    /* 移动端显示两字短名,隐藏桌面端完整文字 */
    .btn-text-desktop {
        display: none;
    }
    .btn-text-mobile {
        display: inline;
    }

    .nav-buttons-container .btn {
        /* 覆盖桌面端的 flex: 1,grid 容器下 .btn 是 grid item,
           flex 无效但显式置 none 避免任何兼容性边界 */
        flex: none;
        width: auto;
    }

    /* 第三个按钮（退出登录）单独占第二行整行 */
    .nav-buttons-container .btn:nth-child(3) {
        grid-column: 1 / -1;
    }

    /* 聊天头部：减小 padding 给汉堡按钮让位 */
    .chat-header {
        padding: 12px 16px !important;
    }

    .chat-header h5 {
        font-size: 1.05rem;
        display: flex;
        align-items: center;
        /* 左侧让出 fixed hamburger 按钮的位置(hamburger 12+40+约 6px 间隙) */
        padding-left: 56px;
        min-height: 36px;
    }

    .app-version-inline {
        font-size: 0.7em;
        margin-left: 4px;
    }

    /* 主题切换器：移动端隐藏（已搬到侧栏抽屉底部 theme-row） */
    .theme-switcher {
        display: none !important;
    }

    /* 消息区：减小 padding */
    #messages {
        padding: 12px;
    }

    /* 分子图：移动端自适应单列 */
    .markdown-content .molecule-img {
        max-width: 100%;
        width: auto;
    }

    /* 工具调用事件：移动端字号略小,padding 紧凑 */
    .tool-call-event {
        padding: 6px 10px;
        font-size: 0.85rem;
        gap: 6px;
    }
    .tool-call-event .tool-name,
    .tool-call-event .tool-status {
        font-size: 0.8rem;
    }

    /* 状态面板：允许换行，纵向堆叠避免挤爆 */
    .status-panels {
        flex-wrap: wrap !important;
        gap: 8px;
    }

    .status-panel {
        max-width: 100%;
        flex: 1 1 100%;
    }

    /* 状态通知：避免被 sidebar-toggle 遮挡 */
    .status-notification {
        top: 60px;
        right: 12px;
        left: 12px;
        text-align: center;
    }

    /* 服务器状态：移动端完全隐藏（信息已在侧栏顶部 status-panels） */
    #server-status {
        display: none !important;
    }

    /* auth-modal：占满大部分屏幕 */
    .auth-modal {
        width: 90vw;
        max-width: 360px;
        padding: 24px 20px;
    }

    .auth-title {
        font-size: 1.2rem;
    }

    /* lightbox：图片占满 */
    .lightbox-overlay .lightbox-image {
        max-width: 95vw;
        max-height: 85vh;
    }

    /* 历史记录：紧凑 */
    .history-item {
        padding: 12px 14px;
        padding-right: 40px;
        font-size: 0.85rem;
    }

    /* 帮助链接区（chat-header 内的 p 描述） */
    .chat-header p {
        font-size: 0.8rem !important;
    }

    /* 移动端主题切换行：侧栏抽屉底部一排颜色点
       改用 flex margin-top: auto 让 #sidebar 把它推到抽屉底部,
       不再用 sticky —— sticky 只在父容器滚动时有效,sidebar 自身
       不滚时无法生效,内容少时 theme-row 会在中间留空白 */
    .theme-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        margin-top: auto;              /* 关键：flex 自动撑到底部 */
        flex-shrink: 0;                /* flex 不压缩,保持高度 */
        /* 跨满 sidebar 宽度,抵消 sidebar 的 padding:20px */
        margin-left: -20px;
        margin-right: -20px;
        padding: 12px 20px;
        /* 额外留出 safe-area-inset(已被 sidebar padding-bottom 覆盖,这里作为双保险) */
        padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
        border-top: 1px solid var(--border-light);
        /* 不透明背景,遮住下方的滚动内容 */
        background: linear-gradient(0deg, var(--sidebar-bg-to) 0%, var(--sidebar-bg-from) 100%);
        z-index: 1;
    }

    .theme-row-label {
        color: var(--primary-color);
        font-weight: 600;
        font-size: 0.9rem;
    }

    .theme-row-options {
        display: flex;
        gap: 10px;
    }

    .theme-dot {
        width: 32px;
        height: 32px;
        border-radius: 50%;
        border: 2px solid var(--border-light);
        cursor: pointer;
        padding: 0;
        transition: transform 0.2s ease, box-shadow 0.2s ease;
        box-shadow: 0 1px 3px var(--shadow-black-light);
    }

    .theme-dot:hover {
        transform: scale(1.1);
    }

    .theme-dot.active {
        border-color: var(--primary-color);
        box-shadow: 0 0 0 2px var(--bg-content), 0 0 0 4px var(--primary-color);
    }
}

/* 移动端主题切换行：默认隐藏在上方基础样式；移动端媒体查询内的 display:flex 覆盖 */

/* 超窄屏（≤380px）微调 */
@media (max-width: 380px) {
    #sidebar {
        width: 260px;
    }

    .message {
        padding: 10px 12px;
        font-size: 15px;
    }

    #send-button {
        padding: 8px 14px;
        font-size: 13px;
    }
}

/* 打字机效果指示器 */
.typing-indicator {
    display: inline-flex;
    align-items: center;
}

.typing-indicator span {
    height: 6px;
    width: 6px;
    background: var(--primary-color);
    border-radius: 50%;
    margin: 0 3px;
    display: inline-block;
    animation: typingBounce 1.4s infinite ease-in-out both;
}

.typing-indicator span:nth-child(1) {
    animation-delay: -0.32s;
}

.typing-indicator span:nth-child(2) {
    animation-delay: -0.16s;
}

@keyframes typingBounce {
    0%, 80%, 100% { transform: scale(0); }
    40% { transform: scale(1); }
}

/* 消息进入动画 */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(15px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* 状态通知样式 */
.status-notification {
    position: fixed;
    top: 20px;
    right: 20px;
    padding: 10px 20px;
    border-radius: 50px;
    color: var(--text-on-primary);
    font-weight: 500;
    z-index: 1000;
    box-shadow: 0 4px 15px var(--shadow-black-strong);
    transition: all 0.3s ease;
    opacity: 0;
    transform: translateY(-20px);
}

.status-notification.success {
    background: linear-gradient(45deg, var(--color-success), var(--color-success-light));
}

.status-notification.error {
    background: linear-gradient(45deg, var(--color-error), var(--color-error-light));
}

.status-notification.warning {
    background: linear-gradient(45deg, var(--color-warning), var(--color-warning-light));
}

.status-notification.info {
    background: linear-gradient(45deg, var(--color-info), var(--color-info-light));
}

.status-notification.show {
    opacity: 1;
    transform: translateY(0);
}

/* 服务器状态指示器：原右下角浮窗，现合并到 chat-header 标题旁，改成行内流式元素 */
#server-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: 12px;
    padding: 2px 10px;
    border-radius: 12px;
    font-size: 0.7em;
    font-weight: 500;
    color: var(--text-on-primary);
    vertical-align: middle;
    transition: all 0.3s ease;
}

/* 导航按钮容器样式 */
.nav-buttons-container {
    display: flex;
    gap: 10px;
    margin-bottom: 15px;
}

.nav-buttons-container .btn {
    flex: 1;
    min-width: 0;
    padding: 8px 4px;
    font-size: 0.78rem;
    font-weight: 600;
    text-align: center;
    border-radius: 10px;
    transition: all 0.3s ease;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.nav-buttons-container .btn i {
    margin-right: 3px;
    font-size: 0.85em;
}

/* 历史记录标题容器样式 */
.history-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 25px;
    margin-bottom: 15px;
}

.history-header h5 {
    margin: 0;
    color: var(--primary-color);
    font-weight: 600;
    position: relative;
    padding-bottom: 8px;
}

.history-header h5::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    width: 50px;
    height: 3px;
    background: linear-gradient(45deg, var(--primary-color), var(--accent-color));
    border-radius: 3px;
}

/* 清空历史按钮优化样式 */
#clear-history-button {
    background: linear-gradient(135deg, var(--color-error), var(--color-error-dark));
    color: var(--text-on-primary);
    border: none;
    padding: 6px 12px;
    border-radius: 15px;
    font-size: 0.75rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 0 2px 8px var(--shadow-error);
    display: flex;
    align-items: center;
    gap: 4px;
}

#clear-history-button:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px var(--shadow-error);
    background: linear-gradient(135deg, var(--color-error-dark), var(--color-error-darker));
}

#clear-history-button i {
    font-size: 0.7rem;
}

#server-status.online {
    background-color: var(--color-success);
}

#server-status.offline {
    background-color: var(--color-error, #e74c3c);
}

#server-status .status-indicator {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--text-on-primary);
}

/* Markdown 样式 */
.markdown-content {
    line-height: 1.6;
}

/* SSE 流式期间:用 textContent 显示原始 markdown 文本,白空间保留 */
.markdown-content.streaming {
    white-space: pre-wrap;
    word-break: break-word;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

/* 已渲染的 markdown HTML:恢复 normal white-space,让 marked 的 <p>/<br> 正常生效
   (覆盖 .markdown-content.streaming 的 pre-wrap) */
.markdown-content .rendered-md {
    white-space: normal;
    font-family: inherit;
}

/* 当前轮累积的纯文本(llm_chunk 期间):继承 .markdown-content.streaming 的 pre-wrap,
   此处不重复声明 */

/* 工具调用事件行:显示在对话流中,标识工具开始/结束。
   A8 优化:加粗左边框 + 加深背景 + 加阴影,让工具行与 LLM 正文有清晰视觉区分。*/
.tool-call-event {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px 10px 16px;
    margin: 10px 0;
    border-radius: 8px;
    background: var(--bg-input, #f5f5f7);
    border-left: 4px solid var(--primary-color, #0066cc);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
    font-size: 0.9rem;
    color: var(--text-secondary, #666);
    flex-wrap: wrap;
    transition: border-left-color 0.2s, background-color 0.2s, max-height 0.2s ease;
    /* 默认收起:单行高度 + 隐藏溢出;点击展开 */
    cursor: pointer;
    user-select: none;
    max-height: 48px;
    overflow: hidden;
    position: relative;
}

.tool-call-event.tool-expanded {
    max-height: 600px;
    overflow: auto;
    cursor: default;
}

/* 折叠态下 status 文字过长用省略号 */
.tool-call-event.tool-collapsed .tool-status {
    max-width: 60%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tool-call-event.tool-active {
    border-left-color: var(--accent-color, #3772b3);
    background-color: rgba(55, 114, 179, 0.06);
}

.tool-call-event.tool-done {
    border-left-color: #4caf50;
    background-color: rgba(76, 175, 80, 0.05);
    color: var(--text-primary, #333);
}

.tool-call-event.tool-done .tool-icon { color: #4caf50; }

/* 失败态：红色边框 + 浅红背景 */
.tool-call-event.tool-error {
    border-left-color: #e53935;
    background-color: rgba(229, 57, 53, 0.06);
    color: var(--text-primary, #333);
}

.tool-call-event.tool-error .tool-icon { color: #e53935; }

/* 取消态：灰色 + 删除线 */
.tool-call-event.tool-cancelled {
    border-left-color: #9e9e9e;
    background-color: rgba(158, 158, 158, 0.05);
    color: var(--text-secondary, #888);
}

.tool-call-event.tool-cancelled .tool-icon { color: #9e9e9e; }

.tool-call-event .tool-icon {
    font-weight: bold;
    color: #4caf50;
    font-size: 1.05rem;
    width: 16px;
    text-align: center;
}

.tool-call-event .tool-name {
    font-family: 'SF Mono', Consolas, Monaco, 'Courier New', monospace;
    font-size: 0.85rem;
    color: var(--text-primary, #333);
    font-weight: 500;
}

.tool-call-event .tool-status {
    color: var(--text-secondary, #888);
    font-size: 0.82rem;
    margin-left: auto;
}

/* 工具卡展开后的完整 output 区域（含下载链接） */
.tool-output-detail {
    flex-basis: 100%;
    margin: 8px 0 0 0;
    padding: 10px 12px;
    background: rgba(0, 0, 0, 0.04);
    border-radius: 6px;
    font-family: 'SF Mono', Consolas, Monaco, 'Courier New', monospace;
    font-size: 0.82rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--text-primary, #333);
    max-height: 360px;
    overflow: auto;
    cursor: text;
    user-select: text;
}

/* 工具内嵌图片容器(A7 修复后,img 节点从这里挂在工具卡里)
   工具卡统一不再嵌缩略图,隐藏此容器(旧消息兼容) */
.tool-output-images {
    display: none;
}

/* 旋转 spinner:工具调用中动画 */
.tool-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid var(--bg-input, #f5f5f7);
    border-top-color: var(--primary-color, #0066cc);
    border-radius: 50%;
    animation: tool-spin 0.8s linear infinite;
    flex-shrink: 0;
}

@keyframes tool-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* ============================================================
   下载链接按钮（A5 优化）
   LLM 在工具总结里给出的 /api/download/* 链接默认是普通 markdown 链接,
   容易和正文链接混淆错过;通过 renderMarkdown 后处理给它们加 .download-link
   类,这里做成蓝色按钮样式 + 下载图标。
   ============================================================ */

a.download-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    margin: 4px 2px;
    border-radius: 6px;
    background: var(--primary-color, #0066cc);
    color: #ffffff !important;
    text-decoration: none;
    font-size: 0.88rem;
    font-weight: 500;
    transition: background-color 0.15s, transform 0.1s;
    border: none;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

a.download-link:hover {
    background: var(--accent-color, #3772b3);
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12);
}

a.download-link:active {
    transform: translateY(0);
}

a.download-link i {
    font-size: 0.85em;
}

/* ============================================================
   错误块样式（V2：SSE error 事件带 error_type + traceback）
   替代旧版仅在 toast + 气泡里显示一行 str(exc)；
   现在 <pre> 块渲染完整堆栈 + 一键复制按钮,
   方便用户出问题时直接把错误粘贴给开发者。
   ============================================================ */

.error-block {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 8px 0;
    padding: 14px 16px;
    border-radius: 10px;
    border: 1px solid var(--color-error, #e74c3c);
    border-left: 4px solid var(--color-error, #e74c3c);
    background-color: var(--color-error-bg, rgba(231, 76, 60, 0.08));
    font-size: 0.9rem;
    line-height: 1.5;
    /* 防止内容溢出：长 traceback 在容器内换行而不是撑出气泡 */
    word-break: break-word;
    overflow-wrap: anywhere;
}

.error-block .error-header {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    color: var(--color-error, #e74c3c);
    font-weight: 600;
    font-size: 0.95rem;
}

.error-block .error-header .error-icon {
    flex-shrink: 0;
    font-size: 1.1rem;
    line-height: 1.3;
}

.error-block .error-header .error-message {
    flex: 1;
    word-break: break-word;
}

.error-block .error-traceback {
    margin: 0;
    padding: 12px 14px;
    background-color: var(--bg-elevated, rgba(0, 0, 0, 0.04));
    border: 1px solid var(--border-light, rgba(0, 0, 0, 0.08));
    border-radius: 6px;
    color: var(--text-primary, #2c3e50);
    font-family: 'SF Mono', 'Monaco', 'Cascadia Code', 'Courier New', monospace;
    font-size: 0.82rem;
    line-height: 1.5;
    max-height: 320px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-break: break-all;
    /* 代码块在容器内正常换行,长路径不会撑出 */
    user-select: text;
}

.error-block .error-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.error-block .error-copy-btn {
    background-color: var(--color-error, #e74c3c);
    color: #ffffff;
    border: none;
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 0.82rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s ease;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.error-block .error-copy-btn:hover {
    opacity: 0.9;
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(231, 76, 60, 0.25);
}

.error-block .error-copy-btn:active {
    transform: translateY(0);
}

.error-block .error-copy-btn.is-copied {
    background-color: var(--color-success, #28a745);
}

/* 移动端：错误块允许更大高度，traceback 滚动更自然 */
@media (max-width: 768px) {
    .error-block .error-traceback {
        max-height: 240px;
        font-size: 0.78rem;
    }
}

.markdown-content h1,
.markdown-content h2,
.markdown-content h3,
.markdown-content h4,
.markdown-content h5,
.markdown-content h6 {
    margin-top: 20px;
    margin-bottom: 10px;
    font-weight: 600;
    color: var(--text-link);
}

.markdown-content h1 { font-size: 1.5em; }
.markdown-content h2 { font-size: 1.4em; }
.markdown-content h3 { font-size: 1.3em; }
.markdown-content h4 { font-size: 1.2em; }
.markdown-content h5 { font-size: 1.1em; }
.markdown-content h6 { font-size: 1em; }

.markdown-content p {
    margin-bottom: 10px;
}

.markdown-content ul,
.markdown-content ol {
    margin-left: 20px;
    margin-bottom: 10px;
}

.markdown-content li {
    margin-bottom: 5px;
}

.markdown-content pre {
    background-color: var(--code-bg);
    border: 1px solid var(--border-strong);
    border-radius: 4px;
    padding: 10px;
    margin: 10px 0;
    overflow-x: auto;
    font-family: 'Courier New', monospace;
}

.markdown-content code {
    background-color: var(--code-bg-inline);
    border-radius: 3px;
    padding: 2px 4px;
    font-family: 'Courier New', monospace;
    font-size: 0.9em;
}

.markdown-content pre code {
    background-color: transparent;
    padding: 0;
}

.markdown-content blockquote {
    border-left: 4px solid var(--primary-color);
    margin-left: 0;
    padding-left: 15px;
    color: var(--text-secondary);
    font-style: italic;
}

.markdown-content table {
    border-collapse: collapse;
    width: 100%;
    margin: 10px 0;
}

.markdown-content th,
.markdown-content td {
    border: 1px solid var(--border-strong);
    padding: 8px;
    text-align: left;
}

.markdown-content th {
    background-color: var(--code-bg);
    font-weight: 600;
}

.markdown-content a {
    color: var(--text-link);
    text-decoration: none;
}

.markdown-content a:hover {
    text-decoration: underline;
}

.markdown-content strong {
    font-weight: 600;
}

.markdown-content em {
    font-style: italic;
}

/* ============================================================
   分子结构图(inline 缩略图 + Lightbox 全屏放大)
   draw_2d_tool 返回的 <img class="molecule-img" data-src="..."> 走这个样式
   ============================================================ */
.markdown-content .molecule-img {
    display: block;
    max-width: 300px;
    width: 300px;
    height: auto;
    margin: 8px 0 12px 0;
    padding: 6px;
    background-color: #ffffff;
    border: 1px solid var(--border-strong);
    border-radius: 6px;
    cursor: zoom-in;
    box-shadow: 0 2px 6px var(--shadow-black-light);
}

.markdown-content .molecule-img:hover {
    box-shadow: 0 4px 12px var(--shadow-primary-light);
}

/* Lightbox 全屏放大(由 App.ui.openLightbox 创建) */
.lightbox-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    cursor: zoom-out;
    animation: lightboxFadeIn 0.2s ease;
    /* 移动端触摸：禁止浏览器默认手势，由 JS 处理滑动关闭 */
    touch-action: none;
}

.lightbox-overlay .lightbox-image {
    max-width: 90vw;
    max-height: 90vh;
    cursor: default;
    background-color: #ffffff;
    border-radius: 4px;
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5);
    /* 允许原生双指缩放查看分子图细节 */
    touch-action: pinch-zoom;
}

@keyframes lightboxFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ============================================================
   主题切换按钮 + 下拉菜单
   ============================================================ */
.theme-switcher {
    position: absolute;
    top: 18px;
    right: 20px;
    z-index: 100;
}

.theme-switcher-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 20px;
    background: linear-gradient(45deg, var(--accent-color), var(--accent-light));
    color: var(--primary-color);
    border: none;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 2px 6px var(--shadow-accent);
    transition: all 0.3s ease;
}

.theme-switcher-toggle:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px var(--shadow-primary-light);
}

.theme-switcher-toggle i {
    font-size: 0.9rem;
}

.theme-switcher-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 160px;
    background: var(--bg-content);
    border-radius: 12px;
    box-shadow: 0 8px 24px var(--shadow-black-strong);
    padding: 6px 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: all 0.2s ease;
    border: 1px solid var(--border-light);
}

.theme-switcher.open .theme-switcher-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.theme-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    cursor: pointer;
    color: var(--text-primary);
    font-size: 0.9rem;
    transition: background 0.2s ease;
    border: none;
    background: none;
    width: 100%;
    text-align: left;
}

.theme-option:hover {
    background: var(--bg-hover-light-from);
}

.theme-option.active {
    color: var(--primary-color);
    font-weight: 600;
}

.theme-option .theme-color-dot {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px var(--bg-content), 0 0 0 3px var(--border-light);
}

.theme-option.active .theme-color-dot {
    box-shadow: 0 0 0 2px var(--bg-content), 0 0 0 3px var(--primary-color);
}

.theme-option .theme-check {
    margin-left: auto;
    color: var(--primary-color);
}

/* ============================================================
   登录鉴权弹窗
   ============================================================ */

.auth-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(6px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    animation: fadeIn 0.2s ease-out;
}

.auth-modal {
    background-color: var(--bg-content);
    color: var(--text-primary);
    border: 1px solid var(--border-medium);
    border-radius: 18px;
    padding: 36px 40px;
    width: 360px;
    max-width: 90vw;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.auth-title {
    margin: 0;
    color: var(--primary-color);
    font-weight: 700;
    font-size: 1.4rem;
    text-align: center;
}

.auth-hint {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
    text-align: center;
    line-height: 1.5;
}

.auth-input {
    border: 2px solid var(--border-input);
    background-color: var(--bg-input-field);
    color: var(--text-primary);
    border-radius: 12px;
    padding: 12px 18px;
    font-size: 1rem;
    outline: none;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.auth-input:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px var(--shadow-primary-soft);
}

.auth-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.auth-submit-btn {
    background: linear-gradient(45deg, var(--primary-color), var(--primary-light));
    color: var(--text-on-primary);
    border: 2px solid var(--accent-color);
    border-radius: 12px;
    padding: 12px 20px;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.2s ease;
    box-shadow: 0 4px 12px var(--shadow-primary);
}

.auth-submit-btn:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 6px 18px var(--shadow-primary-strong);
}

.auth-submit-btn:disabled {
    opacity: 0.7;
    cursor: not-allowed;
}

.auth-error {
    min-height: 1.2em;
    color: var(--color-error);
    font-size: 0.88rem;
    text-align: center;
    line-height: 1.4;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* 侧栏当前用户徽标（登录后展示） */
.user-badge {
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.85rem;
    padding: 8px 12px;
    margin: 4px 0 12px 0;
    background: var(--bg-input-field, #f5f7fa);
    border: 1px solid var(--border-medium, #e1e4e8);
    border-radius: 10px;
    user-select: none;
}

/* 侧栏顶部状态面板：当前在线人数 + 工具运行状态（左右分布，紧凑） */
.status-panels {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    gap: 6px;
    margin-bottom: 16px;
}
.status-panel {
    flex: 1 1 0 !important;
    min-width: 0;
    max-width: 50%;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    background: var(--card-bg, rgba(255, 255, 255, 0.05));
    border: 1px solid var(--card-border, rgba(255, 255, 255, 0.08));
    border-radius: 8px;
    transition: background 0.3s ease;
    box-sizing: border-box;
}
.status-icon {
    font-size: 0.95rem;
    color: var(--primary-color);
    width: 16px;
    height: 16px;
    line-height: 16px;
    text-align: center;
    flex-shrink: 0;
}
.status-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
}
.status-label {
    font-size: 0.68rem;
    color: var(--text-secondary);
    margin-bottom: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.2;
}
.status-value {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-primary, #fff);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.2;
}
/* 工具计算中：图标染色 + 旋转 */
#status-tool-icon.is-busy {
    color: #ffc107;
    animation: statusSpin 2s linear infinite;
}
@keyframes statusSpin {
    from { transform: rotate(0); }
    to   { transform: rotate(360deg); }
}
