/* 后台有自定义样式颜色值等的修改，每个变量已经规定，否则不能再后台修改、只定义一次，无重复。此注释永久保留。 */

/* ============================================================
 * 顶部导航栏样式（从 style.css 迁移）
 * ============================================================ */

.app-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: color-mix(in srgb, var(--color-bg-header) 90%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--color-border);
}
.app-header-inner {
    display: flex;
    align-items: center;
    /* 间距分区：LOGO↔顶部菜单 之间刻意留得比菜单内部更宽，
       否则「图标+站名」这组和后面的菜单项挤成一片，视觉上分不清主次。
       gap 32 + .app-logo 的 margin-right 10 = LOGO 到首个菜单项 42px，
       是菜单项之间间距（.app-topnav 的 gap: 4px，见下）的 10 倍，分区足够明确。 */
    gap: 32px;
    height: 68px;
    max-width: 1600px;
    margin: 0 auto;
    padding: 0 24px;
    transition: height .3s ease, gap .3s ease;
}
.app-header,
html.pre-anim .app-header * { transition: none !important; }
.app-header-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}
.app-header-divider {
    width: 1px;
    height: 22px;
    background: var(--color-border-mid);
    margin: 0 2px;
    flex-shrink: 0;
}
.app-header-mobile {
    display: none;
    position: sticky;
    top: 0;
    z-index: 1030;
    background: var(--color-bg-header);
    border-bottom: 1px solid var(--color-border);
    padding: 10px 16px;
    align-items: center;
    gap: 12px;
}
.app-header-mobile-actions { margin-left: auto; display: flex; gap: 8px; }
.app-header.shrunk { box-shadow: 0 4px 16px color-mix(in srgb, var(--color-bg-header) 18%, transparent); }
/* 收起态（滚动后）：整体压扁，但 LOGO↔菜单的分区仍保留（gap 32→22，logo margin 10→12）。 */
.app-header.shrunk .app-header-inner { height: 50px; gap: 22px; }
.app-header.shrunk .app-logo { font-size: 15px; gap: 10px; margin-right: 12px; }
.app-header.shrunk .app-logo-mark { width: 30px; height: 30px; font-size: 15px; border-radius: 8px; }
/* 图片版 LOGO 在 shrunk 态只缩尺寸：圆角/底色由 .app-logo-img 清零，
   微光随尺寸收敛（小图上再放满半径光晕会糊成一团，故只留贴身+内层+外层三层）。
   ⚠️ 容器要再释放一次 —— 上面 `.app-header.shrunk .app-logo-mark`（0,2,0）
   特异性高于基础 `.app-logo-img`（0,1,0），否则收起态又被压回 30px 宽。 */
.app-header.shrunk .app-logo-img {
    width: auto;
    height: auto;
}
.app-header.shrunk .app-logo-img img {
    height: 30px;
    width: auto;
    filter:
        drop-shadow(0 0 calc(var(--logo-glow-blur) * .22 * var(--logo-glow-boost))
            color-mix(in srgb, var(--logo-glow-color) calc(var(--logo-glow-alpha) * 95% * var(--logo-glow-boost)), transparent))
        drop-shadow(0 0 calc(var(--logo-glow-blur) * .55 * var(--logo-glow-boost))
            color-mix(in srgb, var(--logo-glow-color) calc(var(--logo-glow-alpha) * 60% * var(--logo-glow-boost)), transparent))
        drop-shadow(0 0 calc(var(--logo-glow-blur) * 1.2 * var(--logo-glow-boost))
            color-mix(in srgb, var(--logo-glow-color) calc(var(--logo-glow-alpha) * 30% * var(--logo-glow-boost)), transparent))
        drop-shadow(0 1px 2px color-mix(in srgb, #000 14%, transparent));
}
.app-header.shrunk .app-topnav-link { padding: 5px 16px; font-size: 13px; }
.app-header.shrunk .app-search { padding: 4px 10px; min-width: 320px; }
.app-header.shrunk .app-search input { font-size: 12.5px; }
.app-header.shrunk .app-icon-btn { width: 32px; height: 32px; }
.app-header.shrunk .app-header-actions { gap: 8px; }
.app-header.shrunk .app-header-divider { height: 18px; }
.app-topnav {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 1;
}
.app-topnav-link {
    position: relative;
    padding: 8px 18px;
    border-radius: 8px;
    color: var(--color-nav-link);
    font-size: 14px;
    font-weight: 500;
    transition: color .2s ease, background .2s ease;
    text-decoration: none;
    /* 中文标签没有空格，缺了这一行时 flex 项被挤压就会「逐字换行」（每个字一行）。
       nowrap 后 min-content = 整个标签宽度，导航不再被压成单字宽。 */
    white-space: nowrap;
}
.app-topnav-link:hover {
    color: var(--color-nav-link-hover);
    background: var(--color-accent-soft);
}
.app-topnav-link.active {
    color: var(--color-nav-link-active);
    background: var(--color-accent-soft);
    font-weight: 500;
}
/* 顶部导航「名人堂」：金色微光呼吸（只作用于文字，不加 box-shadow 以免出现矩形边框感） */
.app-topnav-fame {
    animation: appTopnavFameGlow 3s ease-in-out infinite;
}
@keyframes appTopnavFameGlow {
    0%, 100% { text-shadow: 0 0 5px rgba(232,196,106,.5); }
    50%      { text-shadow: 0 0 12px rgba(232,196,106,.95); }
}
@media (prefers-reduced-motion: reduce) {
    .app-topnav-fame { animation: none; text-shadow: 0 0 7px rgba(232,196,106,.6); }
}
.app-topnav-dropdown {
    position: relative;
}
.app-topnav-dropdown .app-topnav-caret {
    position: absolute;
    right: 7px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 10px;
    opacity: .7;
    pointer-events: none;
}
/* 下拉项锚定在链接本体（inline-block 使其成为绝对定位包含块）：
   top:100%+8px 相对链接底边，8px 偏移不会被链接 padding 抵消。
   显示触发仍是容器 hover（.app-topnav-dropdown）——子菜单是容器后代，
   悬停子菜单本身不会断链，比「链接 hover + 相邻兄弟」更稳。 */
.app-topnav-dropdown .app-topnav-link {
    position: relative;
    display: inline-block;
}
.app-topnav-sub {
    position: absolute;
    top: calc(100% + 8px);   /* 下拉窗口比导航项底边低 8px，与鼠标之间留出呼吸感 */
    left: 0;
    min-width: 170px;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: var(--main-shadow);
    padding: 6px;
    display: none;
    z-index: 120;
    transform-origin: top center;
    animation: topnavSubIn .18s ease;
}
/* 透明桥：填住导航项与下拉窗口之间的 8px 间隙，鼠标下移时悬停不丢失。
   挂在容器上（而非链接）——宽度与容器对齐，覆盖间隙水平全宽。 */
.app-topnav-dropdown::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: calc(8px + 6px);   /* 间隙 8px + 子菜单 padding-top 6px，覆盖到第一行条目上沿 */
    z-index: 130;
}
/* 下拉窗口入场：淡入 + 轻微下坠滑入 */
@keyframes topnavSubIn {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.app-topnav-dropdown:hover .app-topnav-sub,
.app-topnav-dropdown:focus-within .app-topnav-sub {
    display: block;
}
.app-topnav-sub-link {
    display: block;
    padding: 8px 12px;
    border-radius: 6px;
    color: var(--color-nav-link);
    font-size: 13px;
    text-decoration: none;
    transition: color .2s ease, background .2s ease;
}
.app-topnav-sub-link:hover {
    background: var(--color-accent-soft);
    color: var(--color-nav-link-hover);
}
.app-topnav-sub-link.active {
    color: var(--color-nav-link-active);
    font-weight: 500;
    background: var(--color-accent-soft);
}




/* ---------- LOGO ---------- */
/* 无 LOGO 时的兜底：主色渐变方块 + 闪电字形（.app-logo-mark.flash）。
   配了 LOGO 图时容器另挂 .app-logo-img，需清掉这里的底色与投影（见下）。 */
.app-logo {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: var(--color-text-title);
    font-weight: 800;
    font-size: 17px;
    letter-spacing: 0.3px;
    flex-shrink: 0;
    /* LOGO 区与顶部菜单之间的额外留白（叠在 .app-header-inner 的 gap 之上，
       使 LOGO↔菜单的间距明显大于菜单项之间的间距，形成清晰的主次分区） */
    margin-right: 10px;
    transition: transform .2s ease;
}
.app-logo:hover { transform: scale(1.02); }
.app-logo-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--color-accent-gradient);
    color: var(--color-text-title);
    font-size: 18px;
    box-shadow: 0 4px 12px color-mix(in srgb, var(--color-accent) 40%, transparent);
}
/* 图片版 LOGO（透明 PNG）：
   - ⚠️ 容器标签同时挂着 .app-logo-mark，那条规则把尺寸写死成 36×36；必须在本类里
     显式释放宽高，否则 img 作为 flex 子项被压回 36px 宽，object-fit 再把图缩成一条
     —— 表现为「尺寸数值越调越大、实际越显示越小」（2026-10-03 踩过，别删这两行）。
   - 高度定档、宽度跟随源图固有比例（height 定值 + width:auto，容器随内容收缩）：
     1:1 源图显示 1:1、2:1 源图显示 2:1，任何比例都完整显示、不变形不裁切，
     也无需 object-fit（有固定盒子时 contain 会在非 2:1 源图两侧留白、看起来偏小）。
     档位：桌面 36px、收起 30px、移动 28px（responsive.css）。
   - 清掉兜底款的渐变底/圆角/投影，否则透明 PNG 后会露色块；
   - 微光用 filter: drop-shadow（按 alpha 通道生成，贴合轮廓），不用 box-shadow。
     「四周都发」= 多层**径向**叠加：每层 offset-x/y 全为 0，只靠 blur 由小到大堆出扩散感。
     ⚠️ 绝不能写 drop-shadow 的第 4 个参数 spread（本项目实测 Chromium 直接把整条声明判为
        无效 → computed filter 变 none → 微光完全消失，2026-10-04 踩过）。只用 blur 表达扩散。 */
.app-logo-img {
    width: auto;
    height: auto;
    background: none;
    box-shadow: none;
    border-radius: 0;
}
.app-logo-img img {
    height: 36px;
    width: auto;
    display: block;
    filter:
        /* ① 贴身实光：blur 极小，勾出轮廓 */
        drop-shadow(0 0 calc(var(--logo-glow-blur) * .22 * var(--logo-glow-boost))
            color-mix(in srgb, var(--logo-glow-color) calc(var(--logo-glow-alpha) * 100% * var(--logo-glow-boost)), transparent))
        /* ② 内层光晕：主要观感来源 */
        drop-shadow(0 0 calc(var(--logo-glow-blur) * .55 * var(--logo-glow-boost))
            color-mix(in srgb, var(--logo-glow-color) calc(var(--logo-glow-alpha) * 68% * var(--logo-glow-boost)), transparent))
        /* ③ 外层扩散：光发到轮廓外 */
        drop-shadow(0 0 calc(var(--logo-glow-blur) * var(--logo-glow-boost))
            color-mix(in srgb, var(--logo-glow-color) calc(var(--logo-glow-alpha) * 40% * var(--logo-glow-boost)), transparent))
        /* ④ 远层柔光：填满四周空气，避免只有一圈硬边 */
        drop-shadow(0 0 calc(var(--logo-glow-blur) * 1.9 * var(--logo-glow-boost))
            color-mix(in srgb, var(--logo-glow-color) calc(var(--logo-glow-alpha) * 20% * var(--logo-glow-boost)), transparent))
        /* ⑤ 极淡落影，仅把 LOGO 从顶栏底色上拔起（不是发光层，别加强、也不吃 boost） */
        drop-shadow(0 1px 2px color-mix(in srgb, #000 14%, transparent));
}
/* 微光的「呼吸」：容器上跑一条相位动画，把 --logo-glow-breath 在 0↔1 之间推，
   再由下面的 calc 把 base→peak 插值成实时的 blur/alpha。
   - 挂在容器（.app-logo-img / .auth-logo-img）而不是 img：自定义属性在**声明它的那一层**
     就完成 var() 替换，img 继承到的是已解析结果，所以派生必须写在容器上；
   - 周期 4.6s + ease-in-out：接近静息呼吸的节奏，快了会像霓虹灯在闪；
   - ⛔ 原来这里的 `transition: filter .25s ease` 必须删掉 —— filter 每帧都在变，
     transition 会把每一帧都当成新目标重新缓动，表现为「呼吸被抹平 + 明显滞后」。
     hover 改过渡 --logo-glow-boost（一个 number），互不打架。 */
.app-logo-img,
.auth-logo-img {
    --logo-glow-blur: calc(var(--logo-glow-blur-base)
        + (var(--logo-glow-blur-peak) - var(--logo-glow-blur-base)) * var(--logo-glow-breath));
    --logo-glow-alpha: calc(var(--logo-glow-alpha-base)
        + (var(--logo-glow-alpha-peak) - var(--logo-glow-alpha-base)) * var(--logo-glow-breath));
    --logo-glow-boost: 1;
    animation: logoGlowBreath 4.6s cubic-bezier(.45, 0, .55, 1) infinite;
    transition: --logo-glow-boost .25s ease;
}
@keyframes logoGlowBreath {
    0%, 100% { --logo-glow-breath: 0; }
    50%      { --logo-glow-breath: 1; }
}
/* hover：只把亮度/半径整体抬高 25%，靠 boost 过渡；
   （旧写法是另写一整条 5 层 filter，但那样呼吸在 hover 期间会被整条替换掉、动画中断） */
.app-logo:hover .app-logo-img,
.app-logo:hover .auth-logo-img { --logo-glow-boost: 1.25; }
/* 减少动效偏好：停掉呼吸，保留静态微光（此刻相位 0 = 原设计观感）。 */
@media (prefers-reduced-motion: reduce) {
    .app-logo-img,
    .auth-logo-img { animation: none; }
}
.app-logo-mobile { font-size: 15px; }
.app-logo-text { font-size: 17px; font-weight: 800; color: var(--color-text-title); white-space: nowrap; }

.app-search {
    display: flex;
    align-items: center;
    background: var(--color-bg-page-soft);
    border: 1px solid var(--color-border);
    border-radius: 20px;
    padding: 6px 12px;
    min-width: 380px;
    transition: all .2s ease;
}
.app-search:focus-within {
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-soft);
}
.app-search input {
    flex: 1;
    border: none;
    background: transparent;
    outline: none;
    font-size: 13px;
    color: var(--color-text-primary);
}
.app-search input::placeholder { color: var(--color-text-dim); }
/* 放大镜提交按钮：与 documents 页 `.res-search-submit` **同款交互**——
   默认透明底 + 强调色图标，hover 实心强调底 + 反白图标（2026-10-01 用户要求顶栏与搜索页同步）。
   顶栏是 pill 容器，按钮保持圆形以贴合 20px 圆角。 */
.app-search button {
    border: none;
    background: transparent;
    color: var(--color-accent);
    cursor: pointer;
    padding: 4px;
    border-radius: 50%;
    transition: background .2s, color .2s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.app-search button:hover { background: var(--color-accent); color: var(--color-text-invert); }


.app-notif { position: relative; }
.app-notif-btn { position: relative; }
.app-notif-badge {
    position: absolute;
    top: -4px; right: -4px;
    min-width: 16px; height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--color-danger);
    color: var(--color-text-invert);
    font-size: 10px; font-weight: 700;
    line-height: 16px; text-align: center;
    display: none;
}
.app-notif-badge.show { display: block; }
.app-notif-panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: 300px;
    max-height: 380px;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card);
    box-shadow: var(--main-shadow);
    z-index: 1000;
    display: none;
}
.app-notif-panel.show { display: block; }
.app-notif-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 10px 14px;
    font-size: 13px; font-weight: 700;
    color: var(--color-text-title);
    border-bottom: 1px solid var(--color-border);
}
.app-notif-clear { font-size: 12px; font-weight: 400; color: var(--color-accent-dark); cursor: pointer; }
.app-notif-clear:hover { color: var(--color-accent); }
.app-notif-body { max-height: 300px; overflow-y: auto; padding: 6px; }
.app-notif-item {
    display: block;
    padding: 8px 10px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--color-text-primary);
}
.app-notif-item:hover { background: var(--color-accent-soft); }
.app-notif-item:hover .app-notif-title { color: var(--color-accent); }
.app-notif-title { display: block; font-size: 13px; color: var(--color-text-primary); }
.app-notif-time { display: block; font-size: 11px; color: var(--color-text-dim); margin-top: 2px; }
/* 通知正文摘要（版本更新显示新版本号，留言回复显示正文片段）：标题下的一行小字 */
.app-notif-desc {
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--color-text-secondary);
    /* 摘要最多两行，超出省略（line-clamp 需要 -webkit-box 这个 display 值） */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/* 未读站内信条目统一强调（左侧竖条）：版本更新、留言回复同源，外观必须一致 */
.app-notif-item--notice { border-left: 2px solid var(--color-accent); }
.app-notif-empty { padding: 24px 12px; text-align: center; font-size: 13px; color: var(--color-text-dim); }
.app-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    color: var(--color-text-secondary);
    text-decoration: none;
    transition: all .2s;
    font-size: 16px;
    background: transparent;
    border: none;
    cursor: pointer;
}
.app-icon-btn:hover { color: var(--color-accent); }

.user-avatar-btn { padding: 4px; border-radius: 50%; background: transparent; border: none; }
.user-avatar-empty {
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--color-bg-page-soft);
    color: var(--color-text-dim);
    font-size: 16px;
}
.user-avatar-empty:hover { color: var(--color-accent); }
.user-dropdown { position: relative; }
.user-dropdown-trigger {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0;
    border-radius: 50%;
    background: transparent;
    border: none;
    cursor: pointer;
    transition: all .2s;
}
.user-dropdown-trigger:hover { border-color: transparent; }
.user-dropdown-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--color-accent-gradient);
    color: var(--color-text-title);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
    overflow: hidden;   /* 上传头像按圆形裁切 */
}
.user-dropdown-avatar img {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
.user-dropdown-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 180px;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card);
    box-shadow: var(--main-shadow);
    padding: 8px;
    z-index: 1000;
    display: none;
}
.user-dropdown:hover .user-dropdown-menu { display: block; }
/* 点击展开后常驻显示：鼠标移向中文输入法候选窗时不再收起 */
.user-dropdown.open .user-dropdown-menu { display: block; }
.user-dropdown::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: 8px;
    z-index: 999;
}
.user-dropdown-item {
    display: block;
    padding: 8px 12px;
    border-radius: 8px;
    color: var(--color-text-primary);
    font-size: 13px;
    text-decoration: none;
    transition: all .15s;
}
.user-dropdown-item:hover { background: var(--color-accent-soft); color: var(--color-accent); }
.user-dropdown-divider { height: 1px; background: var(--color-border); margin: 6px 0; }
.quick-login-panel { width: 250px; padding: 16px; }
.quick-login-title { font-size: 15px; font-weight: 700; color: var(--color-text-title); margin-bottom: 12px; }
.quick-login-form { display: flex; flex-direction: column; gap: 10px; }
.quick-login-input {
    width: 100%; box-sizing: border-box;
    padding: 9px 12px; border-radius: 10px;
    border: 1px solid var(--color-border);
    background: var(--color-bg-page-soft);
    color: var(--color-text-primary); font-size: 13px; outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.quick-login-input:focus { border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-soft); }
.quick-login-btn {
    width: 100%; padding: 9px 0; border: none; border-radius: 10px;
    background: var(--color-accent-gradient); color: var(--color-text-title);
    font-size: 14px; font-weight: 700; cursor: pointer;
    transition: filter .15s;
}
.quick-login-btn:hover { filter: brightness(1.05); }
.quick-login-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 12px; font-size: 12px; }
.quick-login-foot a { color: var(--color-accent-dark); text-decoration: none; }
.quick-login-foot a:hover { color: var(--color-accent); text-decoration: underline; }


/* 侧边栏折叠时，header 恢复全屏 */
html.sidebar-collapsed .app-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: color-mix(in srgb, var(--color-bg-header) 90%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--color-border);
}

/* 桌面端窄视口（992–1199px）的顶部导航收紧已于 2026-10-03 迁至 responsive.css ⑰ 段。
   迁因：该段需晚于 .app-search / .app-header.shrunk 规则才能覆盖（同特异性靠顺序），
   而 responsive.css 在 base.html 的加载顺序本就晚于 header.css，迁过去顺序更稳。 */

/* ============================================================
 * 前台公告滚动条（后台「系统设置 → 公告设置」，由 layout/base.html 渲染）
 * 单份滚动：整条公告从右侧屏外进入、向左穿过整屏后从左侧移出，再循环 ——
 * 一条公告只显示一次，不会出现多份重复。
 * ============================================================ */
.app-notice {
    position: relative;
    background: var(--color-accent-soft);
    border-bottom: 1px solid var(--color-border);
}
.app-notice-inner {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 40px;
    /* 与 .app-shell 同宽(1800)同居中；左内边距让出固定定位的左侧栏(.app-side 固定 260/240px)，
       使小喇叭图标对齐主内容区左缘，不被侧栏遮挡。宽度分级见下方媒体查询。 */
    max-width: 1800px;
    margin: 0 auto;
    padding: 0 32px 0 calc(260px + 32px);
}
@media (min-width: 1200px) and (max-width: 1660px) {
    /* 该区间侧栏为 240px（见 responsive.css），左内边距同步收窄 */
    .app-notice-inner { padding-left: calc(240px + 32px); }
}
.app-notice-icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    color: var(--color-accent);
    font-size: 18px;
}
.app-notice-viewport {
    flex: 1 1 auto;
    position: relative;
    overflow: hidden;
    height: 100%;
    /* 左右边缘淡出，内容进出更自然（仅视觉遮罩，不影响文字） */
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
}
.app-notice-track {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    display: flex;
    align-items: center;
    width: max-content;
    animation: appNoticeScroll var(--notice-dur, 20s) linear infinite;
    will-change: left, transform;
}
/* 悬停暂停，方便阅读长公告 */
.app-notice-viewport:hover .app-notice-track { animation-play-state: paused; }
.app-notice-seg { display: flex; flex: none; }
.app-notice-item {
    flex: none;
    position: relative;
    /* 左内边距给前面的红点留位；右侧间距用于分隔相邻公告 */
    padding: 0 32px 0 18px;
    white-space: nowrap;
    font-size: 13px;
    color: var(--color-text-primary);
}
/* 每条公告前方的红色小圆点 */
.app-notice-item::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -3px;
    border-radius: 50%;
    background: var(--color-danger);
}
.app-notice-close {
    flex: none;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--color-text-dim);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    transition: background .15s, color .15s;
}
.app-notice-close:hover { background: var(--color-accent-soft); color: var(--color-accent); }
/* 整条公告从右侧屏外进入 → 穿过整屏 → 从左侧移出，再循环（一条只显示一次）
   left 的百分比相对视口宽度；transform 的百分比相对公告自身宽度，两者叠加正好走完全程 */
@keyframes appNoticeScroll {
    from { left: 100%; transform: translateX(0); }
    to   { left: 0;    transform: translateX(-100%); }
}
/* 用户偏好减少动效时，停止滚动（公告仍静态可见，可手动关闭） */
@media (prefers-reduced-motion: reduce) {
    .app-notice-track { animation: none; }
}
@media (max-width: 991px) {
    .app-notice-inner { height: 36px; padding: 0 12px; gap: 8px; }
    .app-notice-item { padding: 0 22px 0 16px; font-size: 12.5px; }
}