        /* 主题和设计令牌 */
        :root {
            --primary-color: #1B8EEC;
            --secondary-color: #0078A8;
            --danger-color: #E74C3C;
            --success-color: #2ECC71;
            --warning-color: #F39C12;

            /* 暗色主题（默认） */
            --dark-bg: #0a0e1a;
            --panel-bg: rgba(20, 25, 35, 0.95);
            --panel-border: rgba(255, 255, 255, 0.1);
            --text-primary: #e0e0e0;
            --text-secondary: #aaa;
            --text-tertiary: #777;
            --text-light: #fff;
            --border-color: #2a2e3a;
            --hover-bg: rgba(255, 255, 255, 0.05);
            --input-bg: rgba(255, 255, 255, 0.08);
            --input-bg-locked: rgba(255, 255, 255, 0.14);
            --input-border-locked: rgba(255, 255, 255, 0.2);
            --shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
            --shadow-lg: 0 4px 20px rgba(0, 0, 0, 0.7);
            --transition: all 0.4s ease;

            /* 间距 */
            --spacing-xs: 4px;
            --spacing-sm: 8px;
            --spacing-md: 16px;
            --spacing-lg: 24px;
            --spacing-xl: 32px;

            /* Z-index 层级 */
            --z-map: 1;
            --z-panel: 100;
            --z-menu: 200;
            --z-modal: 300;

            /* 顶栏高度：唯一真源。想再调顶栏高矮只改这一处。 */
            --topbar-h: 42px;
            /* 顶栏下方所有锚定控件的基准线。顶栏收起(display:none)时归零，
               锚定控件自动上移顶栏让出的高度；各控件自带的间隙不随之变化。 */
            --topbar-anchor-h: var(--topbar-h);

            /* 右侧四颗圆钮（雷达/卫星/测站/定位）的几何真源。
               它们都是 body 级 fixed、没有共同父节点，靠这三个变量保持对齐：
               想整体左右挪只改 --layer-col-right，想调上下疏密只改 --layer-col-step。
               --layer-col-top 是首颗的起点，顶栏收起时要整体下移，故在
               body.topbar-collapsed 里覆盖（见该处注释）。 */
            --layer-col-right: 12px;
            --layer-col-top: calc(var(--topbar-anchor-h) + 24px);
            --layer-col-step: 44px;

            /* 右侧四个呼出把手（数据面板 / Watch / 集合点 / 案例库）的几何真源。
               与 --layer-col-* 同一思路：四颗尺寸一致，纵向位置由首颗基准 + 档距推出，
               想调疏密只改 --trigger-step。
               基准从 calc(50% - 8px) 下移到 calc(50% + 16px)（整体下移 24px）：
               原先四颗的中线基本压在视口正中，与地图右缘的图层圆钮列读起来是一整条，
               下移后与那列的层次分开，也不再压住视口中心那一片。 */
            --trigger-w: 32px;
            --trigger-h: 44px;
            --trigger-top: calc(50% + 16px);
            --trigger-step: 48px;

            /* 左下角品牌字样（#sat-engine-label）与右下角 LOGO（#sat-geos-logo）
               各自从角上让开多少，免得被角上的钮压住。
               两侧角上的钮同为 12px 偏移 + 30×30（左下 #immersive-btn 是 left:12px，
               右下 #right-strip-collapse / -pill 是 right:12px）：
               12（偏移）+ 30（按钮宽）+ 12（间隙）= 54px。
               日后改按钮尺寸只需改这一行。
               2026-09-15：左下角那颗钮换了一茬（原先的 #bottom-bar-collapse-pill 随左下栏
               退场，现在是沉浸全屏钮），但**算式一个字没变** —— 新钮与旧钮同为
               12px 偏移 + 30×30，让开量自然照旧。 */
            --corner-brand-clear: 54px;
        }

        /* 亮色主题 */
        body.light-theme {
            --dark-bg: #f5f5f5;
            --panel-bg: rgba(255, 255, 255, 0.95);
            --panel-border: rgba(0, 0, 0, 0.1);
            --text-primary: #333;
            --text-secondary: #666;
            --text-tertiary: #999;
            --text-light: #fff;
            --border-color: #ddd;
            --hover-bg: rgba(0, 0, 0, 0.05);
            --input-bg: #fff;
            --input-bg-locked: #f2f2f2;
            --input-border-locked: #cfcfcf;
            --shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
            --shadow-lg: 0 4px 20px rgba(0, 0, 0, 0.25);
        }

        /* 重置样式 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body, html {
            width: 100%;
            height: 100%;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB",
                         "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
            overflow: hidden;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            background-color: var(--dark-bg);
            color: var(--text-primary);
        }

        /* 页面布局 */

        /* 全屏地图容器 */
        #map-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: var(--z-map);
        }

        #map-container.alt-cursor {
            cursor: default;
        }

        /* 3D 地球激活时 2D 地图只保留几何、不再绘制/合成。
           不能用 display:none：T.Map 的尺寸取自容器，量到 0×0 后天地图没有
           invalidateSize 可补救（实测不存在该方法），切回 2D 会整块错位。
           visibility:hidden 保留布局，渲染面已由 core/render-mode.ts 挂起。 */
        body.globe-active #map-container {
            visibility: hidden;
        }

        /* 3D 地球下 CesiumGlobeManager 在 #cesium-container 内复刻同款浮层
           （#laser-crosshair 挂在 #map-container 外、被 z-index:2 的 3D 容器盖住），
           共用 .laser-crosshair 类样式；2D 侧 #laser-crosshair 无该类、不受影响。
           3D 的十字线本体是贴椭球面的 Cesium 折线实体（屏幕行/列与球面的交线，
           弧线/地平线断开都由实体自然表达），DOM 浮层只剩刻度点/读数标签，
           没有 .laser-line 子节点 —— 故下面 .laser-line 的定位默认值只挂
           #laser-crosshair，类侧无规则。 */
        #laser-crosshair,
        .laser-crosshair {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 5;
            display: none;
        }

        #laser-crosshair.active,
        .laser-crosshair.active {
            display: block;
        }

        /* 卫星云图 AB 产品对比：划像分割线 + 抓手 + 两侧「产品名 · 时次」标签。
           z-index:6 —— 高于 --z-map(1)、低于 --z-panel(100)，与 #laser-crosshair 同级
           （两者不会同时交互）。--sat-wipe-x（px）由 SatelliteCompareController._applyClip 写入，
           分割线/抓手/两个标签都挂在同一条线上，拖拽时只有一个变量在动。 */
        #sat-wipe {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 6;
            display: none;
            --sat-wipe-x: 50%;
        }

        #sat-wipe.active {
            display: block;
        }

        #sat-wipe .sat-wipe-line {
            position: absolute;
            top: 0;
            bottom: 0;
            left: var(--sat-wipe-x);
            width: 2px;
            margin-left: -1px;
            background: rgba(255, 255, 255, 0.92);
            box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35), 0 0 10px rgba(0, 0, 0, 0.45);
        }

        #sat-wipe .sat-wipe-grip {
            position: absolute;
            top: 50%;
            left: var(--sat-wipe-x);
            transform: translate(-50%, -50%);
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0;
            border: none;
            border-radius: 50%;
            background: rgba(20, 22, 26, 0.78);
            color: #fff;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
            cursor: ew-resize;
            touch-action: none;      /* 触摸拖动时不带动页面滚动 */
            pointer-events: auto;    /* 覆盖层里唯一可交互的元素 */
        }

        #sat-wipe .sat-wipe-grip:hover,
        #sat-wipe .sat-wipe-grip.dragging {
            background: var(--primary-color);
        }

        #sat-wipe .sat-wipe-label {
            position: absolute;
            top: calc(50% + 30px);
            max-width: 44vw;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-size: 11px;
            font-weight: 600;
            color: #fff;
            text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75);
        }

        #sat-wipe .sat-wipe-label:empty {
            display: none;
        }

        #sat-wipe-label-a {
            left: var(--sat-wipe-x);
            transform: translateX(calc(-100% - 10px));
            text-align: right;
        }

        #sat-wipe-label-b {
            left: var(--sat-wipe-x);
            transform: translateX(10px);
        }

        #laser-crosshair .laser-line {
            position: absolute;
            background: rgba(255, 59, 48, 0.85);
            box-shadow: 0 0 6px rgba(255, 59, 48, 0.55);
        }

        #laser-crosshair .laser-line.horizontal {
            height: 2px;
            width: 100%;
            left: 0;
            top: var(--laser-y, 50%);
        }

        #laser-crosshair .laser-line.vertical {
            width: 2px;
            height: 100%;
            top: 0;
            left: var(--laser-x, 50%);
        }


        #laser-crosshair .laser-scale-layer,
        .laser-crosshair .laser-scale-layer {
            position: absolute;
            inset: 0;
            pointer-events: none;
        }

        #laser-crosshair .laser-scale-tick,
        .laser-crosshair .laser-scale-tick {
            position: absolute;
            background: rgba(255, 255, 255, 0.92);
            box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45);
            border-radius: 999px;
        }

        #laser-crosshair .laser-scale-tick.horizontal,
        .laser-crosshair .laser-scale-tick.horizontal {
            width: 3px;
            height: 3px;
            top: calc(var(--laser-y, 50%) - 1.5px);
            left: var(--tick-x);
            transform: translateX(-50%);
        }

        #laser-crosshair .laser-scale-tick.vertical,
        .laser-crosshair .laser-scale-tick.vertical {
            width: 3px;
            height: 3px;
            left: calc(var(--laser-x, 50%) - 1.5px);
            top: var(--tick-y);
            transform: translateY(-50%);
        }

        #laser-crosshair .laser-scale-label,
        .laser-crosshair .laser-scale-label {
            position: absolute;
            padding: 2px 6px;
            border-radius: 999px;
            background: rgba(0, 0, 0, 0.72);
            color: #fff;
            font-size: 10px;
            line-height: 1.2;
            white-space: nowrap;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.22);
            transform: translate(-50%, -50%);
        }

        #laser-crosshair .laser-scale-label.horizontal,
        .laser-crosshair .laser-scale-label.horizontal {
            left: var(--tick-x);
            top: calc(var(--laser-y, 50%) - 16px);
        }

        #laser-crosshair .laser-scale-label.vertical,
        .laser-crosshair .laser-scale-label.vertical {
            left: calc(var(--laser-x, 50%) + 16px);
            top: var(--tick-y);
            transform: translateY(-50%);
        }

        /* Alt 采样十字光标：按住 Alt 时显示并跟随鼠标，中心为瓦片源像素采样点（UIManager.initCrosshairSampler 驱动） */
        #sampler-crosshair {
            position: fixed;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 90;   /* 高于地图容器(z1)内的所有瓦片画布，低于面板/弹层 */
            display: none;
        }
        #sampler-crosshair.show {
            display: block;
        }
        #sampler-crosshair .sampler-line {
            position: absolute;
            background: rgba(255, 255, 255, 0.95);
            box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6);
        }
        #sampler-crosshair .sampler-line.v {
            left: var(--sx, 0px);
            top: 0;
            width: 1px;
            height: 100%;
            transform: translateX(-0.5px);
        }
        #sampler-crosshair .sampler-line.h {
            top: var(--sy, 0px);
            left: 0;
            height: 1px;
            width: 100%;
            transform: translateY(-0.5px);
        }
        #sampler-crosshair .sampler-dot {
            position: absolute;
            left: var(--sx, 0px);
            top: var(--sy, 0px);
            width: 9px;
            height: 9px;
            margin: -4.5px 0 0 -4.5px;
            border: 1.5px solid #fff;
            border-radius: 50%;
            background: rgba(0, 0, 0, 0.35);
            box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6);
        }

        /* 采样信息气泡：半透明深底，钉在屏幕右上角；JS 仅负责 top/right 定位与显隐 */
        #sampler-info {
            position: fixed;
            top: 14px;
            right: 14px;
            left: auto;
            display: none;
            pointer-events: none;
            z-index: 90;
            max-width: 280px;
            background: rgba(12, 16, 26, 0.5);   /* 半透明 */
            border: 1px solid rgba(255, 255, 255, 0.18);
            color: #f2f2f2;
            font: 11px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, "PingFang SC", "Microsoft YaHei", monospace;
            padding: 5px 8px;
            border-radius: 6px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
            white-space: pre;
        }
        #sampler-info.show {
            display: block;
        }

        /* 顶部导航栏 */
        #top-bar {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            height: var(--topbar-h);
            background: var(--panel-bg);
            box-shadow: var(--shadow);
            display: flex;
            align-items: center;
            padding: 0 12px;
            z-index: var(--z-panel);
            backdrop-filter: blur(10px);
        }

        /* 顶栏收起/展开：策略与左下栏完全一致（display 切换 + 胶囊钮 + localStorage 记忆） */
        body.topbar-collapsed #top-bar {
            display: none;
        }

        body.topbar-collapsed {
            --topbar-anchor-h: 0px;
        }

        /* ===== 四颗收起/呼出钮的几何基准（唯一真源，30×30 只写这一处）=====
           两条收起钮：顶栏 ↑ / 右栏 →   面板被推走的方向
           两个呼出钮：顶栏 ↓ / 右栏 ←   面板回来的方向
           方向符号是内联 SVG 折角（自绘，理由见下方「方向符号用内联 SVG 自绘」）。
           语义是「动作式」—— 箭头 = 按下后那块面板的移动方向：收起钮指向面板被推走的
           方向，呼出钮指向面板回来的方向。所以成对的两颗方向正好相反 ——
           点完收起之后，剩下的那颗箭头自动回答「怎么把面板拿回来」，符合交互逻辑。
           四颗的朝向都写死在标记里，没有运行时翻转：成对的收起/呼出里同时只会显示
           一颗（右栏那对更是原地互换），所以不需要 JS 去改朝向。
           这里刻意不写 display —— 两个呼出钮默认要隐藏、由各自的状态规则管，
           而 #id 选择器（1,0,0）能压过本组的类级权重，避免顺序依赖。

           「外壳」（底 / 边 / 模糊 / 投影）2026-09-12 起不再一律，改按按钮**落在
           什么表面上**分派（各自见下方那条规则）：
             · 脚下是裸地图的三颗 → 自带壳，自成一块。没壳在卫星云图上几乎看不见。
             · 常驻面板**里面**的那颗（顶栏收起钮）→ 不画壳，让面板的材质直接透上来。
               给它画壳等于在栏上贴了一块异物，而「看着就是栏的一部分」正是它要的效果。
           2026-09-15：左栏（#bottom-bar）整条退场，它那两颗钮随之消失 ——
           原先的第三派「面板还在时挂在面板边缘的那颗」（#bottom-bar-collapse，材质抄面板、
           做面板的边缘延伸）也整派消失，于是三派收成两派，六颗收成四颗。
           本组只留几何与交互 —— 四颗在这件事上仍然完全一致；壳由下面两条路各自给。
           gate_unify 的 G1d 会给这两派做配平：每颗必须属于且只属于一派。 */
        #top-bar-collapse,
        #right-strip-collapse,
        #top-bar-collapse-pill,
        #right-strip-collapse-pill {
            width: 30px;
            height: 30px;
            padding: 0;
            align-items: center;
            justify-content: center;
            border: none;              /* 壳由下面两组各自给，别在本组里画 */
            border-radius: 6px;        /* 无壳时看不见；留给有壳的四颗，与顶栏那颗的 hover 蒙版 */
            background: transparent;
            box-shadow: none;
            color: var(--text-primary);   /* SVG 的 stroke="currentColor" 取的就是它 */
            line-height: 1;
            cursor: pointer;
            z-index: var(--z-panel);
            -webkit-tap-highlight-color: transparent;
            transition: var(--transition);
        }

        /* 浮在裸地图上的三颗：自带底与边。没壳在卫星云图上几乎看不见。
           两颗呼出钮（#right-strip-collapse-pill / #top-bar-collapse-pill）在列：
           它们出现时脚下那面板已经没了，没有材质可依附。
           #right-strip-collapse 在列：它是原地互换的那一颗 —— 栏收起时它留在原地
           变成呼出钮，脚下确实是裸地图。
           不在列的只有 #top-bar-collapse：它常驻顶栏内，见它自己的规则。 */
        #right-strip-collapse,
        #top-bar-collapse-pill,
        #right-strip-collapse-pill {
            border: 1px solid var(--border-color);
            background: color-mix(in srgb, var(--panel-bg) 73.7%, transparent);
            backdrop-filter: blur(10px);
            box-shadow: var(--shadow);
        }

        /* 有底那几颗的 hover：把底提亮一档（73.7% → 90%）。
           顶栏内那颗不在此列 —— 它没有底，hover 见它自己的规则。 */
        #right-strip-collapse:hover,
        #top-bar-collapse-pill:hover,
        #right-strip-collapse-pill:hover {
            background: color-mix(in srgb, var(--panel-bg) 90%, transparent);
        }

        /* 方向符号用内联 SVG 自绘，不用字体字符。
           起因是 ◫（U+25EB）在部分机器上显示为豆腐块 —— 字形落在 Geometric Shapes
           区靠后的稀疏段，覆盖不可控；换任何字体字符都只是换个赌注。自绘则跨平台一致。
           沿库内先例 #locate-me-btn（同样单色、同样 currentColor）而非另三颗图层钮：
           雷达/云图/测站走 canvas 是因为它们是多色插画图标、颜色可由代码自由指定；
           本符号是单色且要跟着主题与 hover 变色，canvas 没有 currentColor，照抄就得
           在主题切换和 hover 时重画。SVG 让形状自绘、颜色仍归 CSS，且天然矢量，
           不必像 canvas 那样自己处理 devicePixelRatio（本项目有 HiDPI 开关）。
           三个朝向各写一条 polyline，不做 CSS 旋转：省掉一层 span 与 transform。
           三条折线是同一个形状的精确旋转（朝上 = 朝右转 90°，朝左 = 转 180°），
           所以「统一」是几何意义上的统一，不是三个各画各的。
           stroke-width 2.2 @ 17px（viewBox 24）= 有效 1.56px，与 #locate-me-btn 的
           2 @ 19px（有效 1.58px）同一量级，十颗符号粗细一致。

           2026-09-14 补记：时次指示器右侧的两颗下拉箭头（#radar-/satellite-settings-arrow）
           与播放设置那颗（#product-range-btn）原先也是字体字符 ▾（U+25BE）—— 与 ◫ 同属
           Geometric Shapes 区，同样在部分机型上显示成豆腐块，一并换成同一套自绘 SVG。
           形状仍是实心三角（与原 ▾ 一致）：fill 走 currentColor 保持单色，
           另叠一圈同色极细 stroke + round join，把填充三角形的尖角磨圆，与折线符号同一手感。 */
        #top-bar-collapse svg,
        #right-strip-collapse svg,
        #top-bar-collapse-pill svg,
        #right-strip-collapse-pill svg,
        .panel-trigger .trigger-close svg,
        .time-chip-arrow svg,
        .product-settings-toggle svg {
            display: block;   /* 消掉 inline SVG 的基线间隙，交给外层 flex 居中 */
        }

        /* 顶栏内收起钮（符号朝上）。绝对定位到顶栏水平正中：脱离 flex 流。
           #top-bar 是 position:fixed，可直接作包含块；top/left 都写死，不依赖
           「绝对定位 flex 子项」的静态位置（各浏览器不一致）。

           外观上它**不是贴在栏上的一枚按钮，而是顶栏自己的一个把手**：不画底、不画边、
           不投影，栏的材质（--panel-bg + blur + shadow）直接透上来，只剩一枚折角符号。
           hover 也只叠一层极淡的文字色蒙版，**不换底、不长边** —— 一 hover 就冒出边框
           或实底色，等于当场承认「我其实是枚按钮」，前功尽弃。
           常态用 --text-secondary 压暗一档：它是家具，不该和栏里的标题、头像抢注意力。 */
        #top-bar-collapse {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            display: flex;
            border: none;
            background: transparent;
            box-shadow: none;
            backdrop-filter: none;
            color: var(--text-secondary);
        }

        #top-bar-collapse:hover {
            color: var(--text-primary);
            background: color-mix(in srgb, var(--text-primary) 10%, transparent);
        }

        /* 顶栏收起后左上角的再展开钮 ‹（转 90° 朝上，与栏内那颗成对）。
           原先贴右上角，2026-09-12 移到左上角：右上角要同时容纳 Toast 与通知面板
           （两者都锚右缘、都从 --topbar-anchor-h 起算，收起时归零后正好撞进这个角落），
           而左栏的呼出钮本就在 left:12px —— 移过来后两颗上下一条竖线，右上一并清空，
           原先为避让加的 #toast-container / .notification-panel / --layer-col-top
           三处「收起态下移」补丁全部作废，已删。 */
        #top-bar-collapse-pill {
            display: none;
            position: fixed;
            left: 12px;
            top: 8px;
        }

        body.topbar-collapsed #top-bar-collapse-pill {
            display: flex;
        }

        #menu-toggle {
            width: 32px;
            height: 32px;
            border: none;
            background: transparent;
            cursor: pointer;
            display: flex;
            flex-direction: column;
            justify-content: center;
            gap: 5px;
            padding: 6px;
            border-radius: 4px;
            transition: var(--transition);
        }

        #menu-toggle:hover {
            background: var(--hover-bg);
        }

        #menu-toggle span {
            display: block;
            width: 20px;
            height: 2px;
            background: var(--text-primary);
            transition: var(--transition);
        }

        /* 展开成 ✕ 的位移 = (gap + 条高) / √2 = (5 + 2) / 1.414 ≈ 5px */
        #menu-toggle.active span:nth-child(1) {
            transform: rotate(45deg) translate(5px, 5px);
        }

        #menu-toggle.active span:nth-child(2) {
            opacity: 0;
        }

        #menu-toggle.active span:nth-child(3) {
            transform: rotate(-45deg) translate(5px, -5px);
        }

        #app-title {
            flex: 1;
            font-size: 15px;
            font-weight: 600;
            color: var(--text-primary);
            text-align: left;
            margin-left: 4px;
        }

        /* 服务器状态灯：跟着 StormTRACER 字样的那颗小圆点。
           绿 = 站点实时刷新正常，红 = 最近一次刷新失败（下一次成功自动回绿）。
           只由 TrackerShell 按 ui.stationFeedOk 切 .is-fail，不承载点击。 */
        #station-status-dot {
            display: inline-block;
            width: 7px;
            height: 7px;
            margin-left: 7px;
            border-radius: 50%;
            background: var(--success-color);
            box-shadow: 0 0 5px color-mix(in srgb, var(--success-color) 60%, transparent);
            vertical-align: 1px;
            transition:
                background-color 0.2s ease,
                box-shadow 0.2s ease;
        }

        #station-status-dot.is-fail {
            background: var(--danger-color);
            box-shadow: 0 0 5px color-mix(in srgb, var(--danger-color) 60%, transparent);
        }

        #user-info {
            display: flex;
            align-items: center;
            gap: var(--spacing-sm);
            cursor: pointer;
        }

        #user-avatar {
            width: 26px;
            height: 26px;
            border-radius: 50%;
            background: var(--primary-color);
            color: var(--text-light);
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: 600;
            font-size: 12px;
        }

        /* 左侧滑入菜单 */
        #side-menu {
            position: fixed;
            top: 0;
            left: -300px;
            width: 300px;
            height: 100%;
            background: var(--panel-bg);
            box-shadow: var(--shadow-lg);
            z-index: var(--z-menu);
            transition: left 0.3s ease;
            overflow-y: auto;
        }

        #side-menu.active {
            left: 0;
        }

        #menu-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: calc(var(--z-menu) - 1);
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease;
        }

        #menu-overlay.active {
            opacity: 1;
            pointer-events: auto;
        }

        .menu-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 10px;
            padding: var(--spacing-lg);
            border-bottom: 1px solid var(--border-color);
        }
        .menu-header h3 {
            margin: 0;
            font-size: 15px;
            font-weight: 600;
            color: var(--text-primary);
        }
        .theme-toggle-circle {
            width: 28px;
            height: 28px;
            border-radius: 50%;
            border: 1px solid var(--border-color);
            padding: 0;
            cursor: pointer;
            flex-shrink: 0;
            overflow: hidden;
            background: linear-gradient(90deg, #1a1a1f 0 50%, #f5f5f3 50% 100%);
            box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.3);
            transition: border-color .2s, box-shadow .2s;
        }
        .theme-toggle-circle:hover {
            border-color: var(--primary-color);
            box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.3), 0 0 0 2px color-mix(in srgb, var(--primary-color) 30%, transparent);
        }

        .menu-section {
            padding: var(--spacing-md) 0;
            border-bottom: 1px solid var(--border-color);
        }

        .menu-section-title {
            padding: var(--spacing-sm) var(--spacing-md);
            font-size: 12px;
            font-weight: 600;
            color: var(--text-secondary);
            text-transform: uppercase;
        }

        .menu-item {
            display: flex;
            align-items: center;
            padding: var(--spacing-md);
            cursor: pointer;
            transition: var(--transition);
            color: var(--text-primary);
            text-decoration: none;
        }

        .menu-item:hover {
            background: var(--hover-bg);
        }

        .menu-item.disabled {
            opacity: 0.4;
            cursor: not-allowed;
            position: relative;
        }

        .menu-item .icon {
            width: 24px;
            margin-right: var(--spacing-md);
            text-align: center;
        }

        .menu-item .label {
            flex: 1;
        }

        .menu-item .badge {
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            background: var(--warning-color);
            color: var(--text-light);
        }

        .menu-item .lock-icon {
            font-size: 12px;
            color: var(--text-secondary);
        }

        /* Token 输入区域 */
        .token-input-area {
            padding: var(--spacing-md);
            background: rgba(0, 0, 0, 0.03);
            border-radius: 8px;
            margin: var(--spacing-sm) var(--spacing-md);
            display: none;
            transition: all 0.3s ease;
        }

        .token-input-area.active {
            display: block;
        }

        .token-input-group {
            margin-bottom: var(--spacing-sm);
        }

        .token-input-group label {
            display: block;
            font-size: 12px;
            color: var(--text-secondary);
            margin-bottom: 4px;
            font-weight: 500;
        }

        .token-input-wrapper {
            display: flex;
            gap: var(--spacing-sm);
        }

        .token-input-wrapper input {
            flex: 1;
            padding: 8px 12px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            font-size: 13px;
            font-family: 'Courier New', monospace;
            background: white;
            transition: var(--transition);
        }

        .token-input-wrapper input:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
        }

        .token-input-wrapper button {
            padding: 8px 12px;
            border: none;
            border-radius: 6px;
            font-size: 12px;
            cursor: pointer;
            transition: all 0.2s ease;
            font-weight: 500;
        }


        .token-status {
            font-size: 11px;
            margin-top: 6px;
            padding: 4px 8px;
            border-radius: 4px;
            display: inline-block;
        }

        .token-status.valid {
            background: color-mix(in srgb, var(--success-color) 10%, transparent);
            color: var(--success-color);
        }

        .token-status.invalid {
            background: color-mix(in srgb, var(--danger-color) 10%, transparent);
            color: var(--danger-color);
        }

        .token-status.empty {
            background: rgba(149, 165, 166, 0.1);
            color: var(--text-secondary);
        }

        .token-info {
            font-size: 11px;
            color: var(--text-secondary);
            margin-top: 6px;
            line-height: 1.4;
        }

        /* 沉浸全屏按钮：左下角，与右下角那颗收起钮同一套角上偏移（12px / 30×30）。
           2026-09-15 变迁：它原先由 JS 现算 bottom（读 #bottom-bar 的 offsetHeight ——
           那条栏的高度随「当前选择」的文字变），左下栏退场后角上再没有别的东西，
           于是位置落成死数 left:12px / bottom:12px，JS 里那套测量整条删掉。
           当天它一度被挪去右下角与轮盘呼出钮做伴，随后按用户要求搬回左下角 ——
           于是它**不归任何收起钮管**：左栏已经没了，本就没有可依附的收起态，
           它是常驻的（沉浸态则收缩成那颗唯一的出口钮，见下）。
           它**不进**上方的「浮在裸地图上的三颗」：那组是收起/呼出钮的几何基准，
           材质是跟着主题走的半透明磨砂（73.7%）；本钮用**不透明**面板底 +
           常态 0.8 透明度 —— 动作钮要读起来「可点」，收起钮要读起来「是块玻璃」。 */
        #immersive-btn {
            position: fixed;
            left: 12px;
            bottom: 12px;
            width: 30px;
            height: 30px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            background: var(--panel-bg);
            color: var(--text-primary);
            line-height: 1;
            cursor: pointer;
            box-shadow: var(--shadow);
            backdrop-filter: blur(10px);
            z-index: var(--z-panel);
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0.8;   /* 压在地图内容上，不该抢戏 */
            transition: transform 0.15s, opacity 0.15s, left 0.2s, bottom 0.2s;
            -webkit-tap-highlight-color: transparent;
        }

        #immersive-btn:hover {
            opacity: 1;
            transform: scale(1.08);   /* 只顶一下，不动位置 */
        }

        /* 轮盘呼出钮：右下角，右侧栏收起钮（#right-strip-collapse）的正上方 8px。
           这一摞自下而上是：收起钮（角上 12px）→ 轮盘呼出钮，
           bottom = 12 + 30 + 8 = 50px，死数，一个都不用算。
           材质与沉浸钮同源（不透明面板底 + 常态 0.8 透明度），但两钮已分处两个角，
           不再共用一条规则 —— 合写的唯一理由（省掉一份重复）已经不如「各在各的角上、
           各读各的注释」值钱。 */
        #wheel-trigger-btn {
            position: fixed;
            right: 12px;
            bottom: 50px;
            width: 30px;
            height: 30px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            background: var(--panel-bg);
            color: var(--text-primary);
            line-height: 1;
            cursor: pointer;
            box-shadow: var(--shadow);
            backdrop-filter: blur(10px);
            z-index: var(--z-panel);
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0.8;
            transition: transform 0.15s, opacity 0.15s;
            -webkit-tap-highlight-color: transparent;
        }

        #wheel-trigger-btn:hover {
            opacity: 1;
            transform: scale(1.08);
        }

        /* 3D 地球切换钮：左下角、沉浸钮的正上方 8px（bottom = 12 + 30 + 8 = 50px，
           与右下角轮盘呼出钮同一条算式）。材质与沉浸钮/轮盘钮同源。
           .is-active（3D 开启中）高亮描边；.is-loading（Cesium chunk 动态加载中）
           用四角呼吸圆点 spinner 顶替「3D」字样 —— 早期版本曾直接旋转字样本身，
           30×30 的钮里一圈文字甩起来观感很差（button:disabled 的灰化会误伤
           正在加载的观感，故防抖只做在事件侧、不禁用按钮）。 */
        #globe-toggle-btn {
            position: fixed;
            left: 12px;
            bottom: 50px;
            width: 30px;
            height: 30px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            background: var(--panel-bg);
            color: var(--text-primary);
            line-height: 1;
            cursor: pointer;
            box-shadow: var(--shadow);
            backdrop-filter: blur(10px);
            z-index: var(--z-panel);
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0.8;
            transition: transform 0.15s, opacity 0.15s;
            -webkit-tap-highlight-color: transparent;
        }

        #globe-toggle-btn:hover {
            opacity: 1;
            transform: scale(1.08);
        }

        #globe-toggle-btn.is-active {
            color: var(--primary-color);
            border-color: var(--primary-color);
            opacity: 1;
        }

        #globe-toggle-btn .globe-toggle-label {
            display: inline-block;
            font: 700 13px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
            letter-spacing: -0.04em;
            transform-origin: center;
        }

        #globe-toggle-btn.is-loading .globe-toggle-label {
            display: none;
        }

        /* 3D 回家钮：3D 切换钮正上方 8px（bottom = 12 + 30 + 8 + 30 + 8 = 88px），
           只在 3D 开启（body.globe-active）时出现。材质与 3D 钮同源，图标是内联
           SVG（不用字体字符，避免缺字变豆腐块）。 */
        #globe-home-btn {
            position: fixed;
            left: 12px;
            bottom: 88px;
            width: 30px;
            height: 30px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            background: var(--panel-bg);
            color: var(--text-primary);
            line-height: 1;
            cursor: pointer;
            box-shadow: var(--shadow);
            backdrop-filter: blur(10px);
            z-index: var(--z-panel);
            display: none;
            align-items: center;
            justify-content: center;
            opacity: 0.8;
            transition: transform 0.15s, opacity 0.15s;
            -webkit-tap-highlight-color: transparent;
        }

        body.globe-active #globe-home-btn {
            display: flex;
        }

        #globe-home-btn:hover {
            opacity: 1;
            transform: scale(1.08);
        }

        /* 加载态 spinner：CSS 绘制的四点环（currentColor，激活态描边同色），
           伪元素代替旋转字样；尺寸 14px 与 30×30 钮协调。 */
        #globe-toggle-btn.is-loading::after {
            content: '';
            position: absolute;
            width: 14px;
            height: 14px;
            border-radius: 50%;
            border: 2px solid transparent;
            border-top-color: currentColor;
            animation: globe-spin 0.9s linear infinite;
        }

        @keyframes globe-spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }

        /* 3D 帧率读数：回家钮正上方 8px（bottom = 88 + 30 + 8 = 126px）。
           left 取 12 + 30/2 = 27px，再用 translateX(-50%) 让自身中心对齐钮中心，
           读数变宽时不会往右跑。默认隐藏，显隐与文本由 TrackerShell 按
           ui.globeActive / ui.globeFps 命令式同步（v-pre 壳内没有插值）。 */
        #globe-fps {
            position: fixed;
            left: 27px;
            bottom: 126px;
            transform: translateX(-50%);
            padding: 2px 5px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            background: var(--panel-bg);
            color: var(--text-primary);
            font: 600 10px/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
            letter-spacing: 0.02em;
            white-space: nowrap;
            pointer-events: none; /* 纯读数，不吃地图拖拽/点击 */
            box-shadow: var(--shadow);
            backdrop-filter: blur(10px);
            z-index: var(--z-panel);
            display: none;
            opacity: 0.8;
        }

        /* Cesium 3D 地球容器：盖住整个地图区，与 #map-container 同位铺满。
           z-index 用 --z-panel 之下的地图层（--z-map=1 之上即可压住 2D 底图，
           又压不住顶栏/面板那批 --z-panel 及以上的 UI，切换后界面控件照常可用）。
           由 CesiumGlobeManager 创建/销毁，不进壳模板（壳是 v-pre 静态区）。 */
        #cesium-container {
            position: fixed;
            inset: 0;
            z-index: 2;
            background: #000;   /* 瓦片未就位时不露白 */
        }

        /* 3D 下 Alt 激光笔：容器里的复刻浮层用同一套 .laser-crosshair 样式（见上方）。 */
        #cesium-container.alt-cursor canvas {
            cursor: default;
        }

        /* Cesium 版权条（左下角的 Cesium logo + 底图 credit 容器）整颗隐藏：
           与 3D 切换钮/沉浸钮冲突，且与右下角的 GEOS 品牌位抢视觉。
           底图 credit 不另行展示（2D 天地图控件的版权信息已随处可见，
           3D 只是同一服务的另一视图）。 */
        #cesium-container .cesium-viewer-bottom {
            display: none;
        }

        /* 两枚自绘符号（进入的四个折角 / 退出的叉）同写在标记里，按态切换显隐 ——
           照 .panel-trigger 的 .trigger-open / .trigger-close 那套先例。
           用 SVG 而非 ⛶(U+26F6) / ✕(U+2715)：这两个字符与当年翻车的 ◫(U+25EB)、
           ▾(U+25BE) 同属那几段字体覆盖不可推断的稀疏区（见上方「方向符号用内联
           SVG 自绘」）。换掉之后 font-size 对符号不再起作用，故那两行已删。 */
        #immersive-btn .ic-exit {
            display: none;
        }

        #immersive-btn.is-exit .ic-enter {
            display: none;
        }

        #immersive-btn.is-exit .ic-exit {
            display: block;
        }

        /* 沉浸态：收缩到角上、更小更淡（它是「出口」不是「控件」）。 */
        body.immersive #immersive-btn {
            bottom: 10px;
            left: 10px;
            width: 24px;
            height: 24px;
            border-radius: 5px;
            opacity: 0.55;
        }

        body.immersive #immersive-btn:hover {
            opacity: 1;
        }

        /* 右侧栏收起时，那颗轮盘呼出钮一并隐藏 —— 它挂在收起钮的正上方，
           收起后那个位置站的是呼出胶囊钮，叠在一起会打架。
           （沉浸钮不在此列：它在左下角，与这条栏无关，且沉浸态还另有大隐藏列表管它。） */
        body.right-strip-collapsed #wheel-trigger-btn {
            display: none;
        }

        /* 沉浸 / 录制模式隐藏顶栏与右侧竖列的再展开胶囊钮：
           被收起的那些元素本身已在下面两个大隐藏列表里，但两个胶囊钮是 body 级元素，
           不受顶栏/竖列自己的 display 影响，必须单列一遍，否则会在干净视图上残留。 */
        body.immersive #top-bar-collapse-pill,
        body.immersive #right-strip-collapse-pill,
        body.recording-mode #top-bar-collapse-pill,
        body.recording-mode #right-strip-collapse-pill,
        body.recording-mode #right-strip-collapse {
            display: none !important;
        }

        /* 沉浸模式数据时间（mmDD HHMM）：位于左下角恢复钮上方，替代引擎「POWER BY」字样
           （沉浸态那行字样本身被隐藏，见下）。
           bottom:40px 的算式：10（恢复钮偏移）+ 24（沉浸态钮高）+ 6（间隙）。
           2026-09-15：恢复钮一度被挪去右下角，它随之降到 12px；随后恢复钮按用户要求
           搬回左下角，于是它跟着回到 40px —— 这两个数是一对，动一个必须动另一个。 */
        #immersive-datetime {
            display: none;
            position: fixed;
            left: 12px;
            bottom: 40px;
            z-index: calc(var(--z-panel) + 1);
            color: #fff;
            font: 600 12px -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;
            text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
            letter-spacing: 0.5px;
            pointer-events: none;
            white-space: nowrap;
        }

        body.immersive #immersive-datetime {
            display: block;
        }

        /* 沉浸模式：隐藏左下角引擎品牌「POWER BY …」字样 */
        body.immersive #sat-engine-label {
            display: none !important;
        }

        /* 沉浸模式：隐藏全部界面与标题栏，仅保留地图与左下角恢复按钮 */
        body.immersive #top-bar,
        body.immersive #side-menu,
        body.immersive #menu-overlay,
        body.immersive #data-panel,
        body.immersive .panel-trigger,
        body.immersive #panel-trigger,
        body.immersive #watch-panel-trigger,
        body.immersive #rally-panel-trigger,
        body.immersive #case-panel-trigger,
        body.immersive #right-strip-collapse,
        body.immersive #wheel-trigger-btn,
        body.immersive .map-layer-btn,
        body.immersive #product-controls,
        body.immersive .time-displays,
        body.immersive #playback-panel,
        body.immersive #playback-recording-overlay,
        body.immersive #auth-modal,
        body.immersive #station-info-popup,
        body.immersive #typhoon-panel,
        body.immersive #user-settings-panel,
        body.immersive #preferences-panel,
        body.immersive #stations-panel,
        body.immersive .common-modal,
        body.immersive .leaflet-control-zoom,
        body.immersive .leaflet-control-attribution {
            display: none !important;
        }

        /* 右侧数据面板 */
        #data-panel {
            --panel-width: 350px;
            position: fixed;
            top: var(--topbar-anchor-h);
            right: calc(-1 * var(--panel-width));
            width: var(--panel-width);
            height: calc(100% - var(--topbar-anchor-h));
            background: var(--panel-bg);
            box-shadow: var(--shadow-lg);
            z-index: var(--z-panel);
            transition: right 0.3s ease;
            overflow-y: auto;
        }

        #data-panel.active {
            right: 0;
        }

        /* PC 端拖拽调整大小手柄 */
        .panel-resize-handle {
            position: absolute;
            left: 0;
            top: 0;
            width: 8px;
            height: 100%;
            cursor: ew-resize;
            background: transparent;
            z-index: 10;
            transition: background 0.2s;
        }

        .panel-resize-handle:hover,
        .panel-resize-handle.resizing {
            background: rgba(66, 153, 225, 0.3);
        }

        .panel-resize-handle::before {
            content: '';
            position: absolute;
            left: 2px;
            top: 50%;
            transform: translateY(-50%);
            width: 4px;
            height: 40px;
            background: var(--border-color);
            border-radius: 2px;
            opacity: 0;
            transition: opacity 0.2s;
        }

        .panel-resize-handle:hover::before,
        .panel-resize-handle.resizing::before {
            opacity: 1;
        }

        /* 数据面板呼出按钮（小、弱化：半透明低对比、无投影、无 hover 变宽） */
        /* 右侧四个呼出把手：贴右缘伸出的竖向把手（right:0、单边圆角）。
           四颗**样式与大小完全一致**：原先「数据面板」那颗是 34×60、另三颗 32×44
           （靠 .panel-trigger-watch 覆盖），并排看大小不一；现统一取较小那档 32×44，
           也才收得下更紧的档距（--trigger-step 48px → 相邻间隙 4px，原为 6px）。
           毛玻璃取自浮钮那套（见「浮在裸地图上的三颗」）：73.7% 面板底 + blur(10px) + var(--shadow)。
           原先背景是 55% 且 box-shadow:none，贴在地图上偏「实」，与浮钮不是一套语言。
           （那套材质最初是从左下栏 #bottom-bar 上抄下来的，2026-09-15 栏退场，
           这个出处随之消失 —— 但数值一个没动，仍是同一种毛玻璃。）
           纵向位置全部由 --trigger-* 四个变量推出（见 :root），四颗不再各写各的 top。 */
        .panel-trigger {
            position: fixed;
            top: var(--trigger-top);
            right: 0;
            transform: translateY(-50%);
            width: var(--trigger-w);
            height: var(--trigger-h);
            background: color-mix(in srgb, var(--panel-bg) 73.7%, transparent);
            backdrop-filter: blur(10px);
            border: 1px solid var(--border-color);
            border-right: none;
            border-radius: 7px 0 0 7px;
            box-shadow: var(--shadow);
            cursor: pointer;
            z-index: calc(var(--z-panel) - 1);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            color: var(--text-tertiary);
            transition: color 0.2s ease;
        }

        /* 控制按钮内容显示：关闭位是自绘的朝右折角（同六颗收起钮那套，见文件上方）。
           语义一致（指向式）：面板从右缘滑出，关闭位指向右。
           开关位一多一少不冲突 —— .trigger-open 是产品标识（▦▱⚑☆），本身不带方向。 */
        .panel-trigger .trigger-close {
            display: none;
            align-items: center;
            justify-content: center;
        }

        .panel-trigger.active {
            z-index: calc(var(--z-panel) + 1);  /* 面板打开时，按钮层级提高 */
            color: var(--text-secondary);
        }

        .panel-trigger.active .trigger-open {
            display: none;
        }

        .panel-trigger.active .trigger-close {
            display: flex;   /* 不是 block：SVG 要在 32×44 的把手内居中 */
        }

        .panel-trigger:hover,
        .panel-trigger.active:hover {
            color: var(--primary-color);
        }

        .panel-trigger:active {
            color: var(--primary-color);
        }

        /* 第 2/3/4 颗（首颗 #panel-trigger 直接吃 .panel-trigger 的基准 top）。
           原先后三颗靠 .panel-trigger-watch 给 top、后两颗再各挂一条内联 top；
           内联样式优先级高于任何选择器，改档距时极易漏改，故全部收回 CSS。 */
        #watch-panel-trigger {
            top: calc(var(--trigger-top) + var(--trigger-step));
        }

        #rally-panel-trigger {
            top: calc(var(--trigger-top) + var(--trigger-step) * 2);
        }

        #case-panel-trigger {
            top: calc(var(--trigger-top) + var(--trigger-step) * 3);
        }

        /* ===== 右侧整条竖列（4 颗圆钮 + 4 个右缘呼出把手）整体收起 =====
           这 8 个元素都是 body 级 position:fixed，没有共同父节点，只能逐条列 id。
           #locate-me-btn 2026-09-12 从地图左缘移入本列，故在此一并收起；
           它虽然也带 .map-layer-btn，但四颗圆钮现已同属右列，逐条列 id 是为了让
           这份名单始终等于「右列的实际组成」，日后增删一眼能对。 */
        /* 右侧竖列的收起钮 ›：右下角。原本挂在竖列末端（50%+200px），但左下角当初已被
           #bottom-bar（left:0 起 250px 宽）与沉浸钮占满，故落在右下角这片空白区。
           （2026-09-15 左下栏退场，它便独占了这个角的最下一格。）
           往上 8px 是轮盘呼出钮（#wheel-trigger-btn）—— 那颗跟着本钮走：本钮收起时它一并隐藏。
           注意**不是**沉浸全屏钮：那颗 2026-09-15 当天来回一趟，最终停在**左下角**，与本钮无关。
           仅定位，外观见文件上方的「四颗收起/呼出钮的几何基准」与「浮在裸地图上的三颗」
           （这颗落在裸地图上，属后者）。 */
        #right-strip-collapse {
            position: fixed;
            right: 12px;
            bottom: 12px;
            display: flex;
        }

        body.right-strip-collapsed #radar-toggle-btn,
        body.right-strip-collapsed #satellite-toggle-btn,
        body.right-strip-collapsed #station-toggle-btn,
        body.right-strip-collapsed #locate-me-btn,
        body.right-strip-collapsed #panel-trigger,
        body.right-strip-collapsed #watch-panel-trigger,
        body.right-strip-collapsed #rally-panel-trigger,
        body.right-strip-collapsed #case-panel-trigger,
        body.right-strip-collapsed #right-strip-collapse {
            display: none !important;
        }

        /* 右侧竖列收起后的再展开钮（符号 ›，与收起钮同符号、同指向）。
           位置与几何和 #right-strip-collapse 完全一致（右下角 12px / 30×30），
           两者是同一处原地互换：收起时消失、展开时出现，视线不用移动，也不会跳位。
           它是 Watch / 集合点 / 案例库三个管理面板收起后唯一的入口，必须常驻可点。 */
        #right-strip-collapse-pill {
            display: none;
            position: fixed;
            right: 12px;
            bottom: 12px;
        }

        body.right-strip-collapsed #right-strip-collapse-pill {
            display: flex;
        }

        .panel-section {
            display: none;
        }

        .panel-section.active {
            display: block;
        }

        .panel-section-header {
            font-size: 14px;
            font-weight: 600;
            color: var(--text-primary);
            margin-bottom: var(--spacing-md);
            display: flex;
            align-items: center;
            gap: var(--spacing-sm);
        }

        .panel-header {
            padding: var(--spacing-md);
            border-bottom: 1px solid var(--border-color);
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: var(--spacing-sm);
        }

        .panel-title {
            font-size: 16px;
            font-weight: 600;
            color: var(--text-primary);
            flex: 1;
            min-width: 0;
        }

        .panel-header .btn {
            flex-shrink: 0;
            padding: 6px 12px;
        }

        .panel-content {
            padding: var(--spacing-md);
        }

        /* 图表容器 */
        #chart-container {
            position: relative;
            height: 250px;
            margin-bottom: var(--spacing-md);
        }

        /* 按钮统一样式 */
        .btn,
        .btn-primary,
        .btn-secondary,
        .btn-cancel,
        .btn-confirm,
        .btn-delete,
        .btn-view,
        .btn-reject,
        .btn-accept,
        .btn-play,
        .btn-urgent-confirm,
        .btn-admin,
        .btn-warning,
        .case-action-btn {
            padding: 8px 16px;
            border: none;
            border-radius: 6px;
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s ease;
            text-align: center;
            display: inline-block;
            white-space: nowrap;
            line-height: 1.4;
        }

        /* 主色（蓝色） */
        .btn-primary,
        .btn-confirm,
        .btn-play,
        .btn-accept,
        .btn-urgent-confirm,
        .btn-admin,
        .case-action-btn {
            background: var(--primary-color);
            color: var(--text-light);
        }

        /* 贡献者Premium（饱和富金） */
        .btn-premium {
            background: #b8860b;
            color: #ffffff;
            font-weight: 600;
        }

        .btn-premium:hover {
            background: #c9962e;
            color: #ffffff;
        }

        /* 角色显示：贡献者Premium 黄色字样 */
        .role-premium {
            color: #ffd700;
            font-weight: 600;
        }

        /* 贡献者Premium 对比表 */
        .premium-compare {
            width: 100%;
            border-collapse: collapse;
            font-size: 13px;
            line-height: 1.5;
        }

        .premium-compare th,
        .premium-compare td {
            padding: 8px 10px;
            border-bottom: 1px solid var(--border-color);
            text-align: center;
        }

        .premium-compare th:first-child,
        .premium-compare td:first-child {
            text-align: left;
            color: var(--text-secondary);
        }

        .premium-compare thead th {
            font-size: 13px;
            color: var(--primary-color);
        }

        .premium-compare .highlight {
            background: rgba(184, 134, 11, 0.08);
            color: #a0781f;
            font-weight: 600;
        }

        .premium-compare thead th.highlight {
            color: #b8860b;
        }

        .premium-price {
            margin: var(--spacing-md) 0 0 0;
            font-size: 15px;
            line-height: 1.7;
            color: var(--text-secondary);
        }

        .premium-plan-body p.premium-price strong {
            color: var(--text-primary);
            font-size: 18px;
        }

        /* 贡献者Premium 长文案弹窗排版 */
        .premium-plan-body p {
            margin: 0 0 var(--spacing-sm) 0;
            font-size: 14px;
            line-height: 1.8;
            color: var(--text-secondary);
        }

        .premium-plan-body p strong {
            color: var(--primary-color);
        }

        .premium-plan-body .plan-tagline {
            font-size: 15px;
            line-height: 1.6;
            color: var(--primary-color);
            font-weight: 600;
            margin-bottom: var(--spacing-md);
        }

        .premium-plan-body .plan-needs {
            margin: 0 0 var(--spacing-md) 0;
            padding-left: 22px;
            line-height: 1.9;
            font-size: 14px;
        }

        .premium-plan-body .plan-features-intro {
            margin: 0 0 var(--spacing-sm) 0;
        }
        .premium-plan-body .plan-features {
            margin: 0 0 var(--spacing-md) 0;
            padding-left: 22px;
            line-height: 1.9;
            font-size: 14px;
            color: var(--text-secondary);
        }
        .premium-plan-body .plan-features li {
            margin-bottom: 4px;
        }
        .premium-plan-body .plan-features li strong {
            color: var(--primary-color);
        }

        .premium-plan-body .plan-cta-intro {
            font-weight: 600;
            color: var(--primary-color);
        }

        .premium-plan-body .plan-footer-note {
            margin-bottom: 0;
        }

        /* 套餐选择（月付/年付） */
        .plan-billing-options {
            display: flex;
            gap: 12px;
            margin: var(--spacing-sm) 0 var(--spacing-md) 0;
        }
        .plan-option {
            flex: 1;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 4px;
            padding: 12px 10px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            background: transparent;
            cursor: pointer;
            transition: border-color 0.2s, background 0.2s;
            font: inherit;
            text-align: center;
        }
        .plan-option:hover {
            border-color: #cfcfcf;
        }
        .plan-option.active {
            border-color: #cfcfcf;
            background: rgba(210, 210, 210, 0.12);
            box-shadow: inset 0 0 0 1px #cfcfcf;
        }
        .plan-option-name {
            font-size: 14px;
            font-weight: 600;
            color: var(--text-primary);
        }
        .plan-option-price {
            font-size: 16px;
            font-weight: 700;
            color: var(--text-primary);
        }
        .plan-option-desc {
            font-size: 12px;
            color: var(--text-secondary);
        }
        .plan-option-badge {
            font-size: 12px;
            font-weight: 600;
            color: #cfcfcf;
            background: rgba(210, 210, 210, 0.12);
            border-radius: 4px;
            padding: 1px 6px;
        }

        /* 贡献者入口：左侧提示文本 + 右侧加入按钮 */
        #contributor-section .upgrade-exam-actions {
            justify-content: space-between;
            align-items: center;
        }
        .contributor-section-hint {
            font-size: 13px;
            color: var(--text-secondary);
        }

        .btn-primary:hover,
        .btn-confirm:hover,
        .btn-play:hover,
        .btn-accept:hover,
        .btn-urgent-confirm:hover,
        .btn-admin:hover,
        .case-action-btn:hover {
            background: color-mix(in srgb, var(--primary-color) 82%, black);
        }

        /* 次要（灰色描边） */
        .btn-secondary,
        .btn-cancel,
        .btn-view {
            background: var(--input-bg);
            color: var(--text-primary);
            border: 1px solid var(--border-color);
        }

        .btn-secondary:hover,
        .btn-cancel:hover,
        .btn-view:hover {
            background: var(--hover-bg);
        }

        /* 危险（红色） */
        .btn-danger,
        .btn-delete,
        .btn-reject {
            background: var(--danger-color);
            color: var(--text-light);
        }

        .btn-danger:hover,
        .btn-delete:hover,
        .btn-reject:hover {
            background: var(--danger-color);
        }

        /* 成功（绿色） */
        .btn-success {
            background: var(--success-color);
            color: var(--text-light);
        }

        .btn-success:hover {
            background: var(--success-color);
        }

        /* 警告（橙色） */
        .btn-warning {
            background: var(--warning-color);
            color: var(--text-light);
        }

        .btn-warning:hover {
            background: var(--warning-color);
        }

        /* 禁用态 */
        .btn:disabled,
        .btn-primary:disabled,
        .btn-secondary:disabled,
        .btn-danger:disabled,
        .btn-success:disabled,
        .btn-warning:disabled,
        .btn-confirm:disabled {
            opacity: 0.6;
            cursor: not-allowed;
        }

        #showTrackBtn,
        #hideTrackBtn {
            display: block !important;
            position: relative;
            overflow: visible;
        }

        #showTrackBtn span,
        #hideTrackBtn span {
            display: inline;
            position: relative;
            z-index: 2;
            color: inherit;
        }

        #showTrackBtn .btn-text,
        #showTrackBtn .btn-loading {
            pointer-events: none;
        }

        /* 登录/注册模态框 */
        #auth-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            z-index: var(--z-modal);
            display: none;
            align-items: center;
            justify-content: center;
        }

        #auth-modal.active {
            display: flex;
        }

        .auth-container {
            position: relative;
            background: var(--panel-bg);
            border-radius: 12px;
            padding: var(--spacing-xl);
            max-width: 400px;
            width: 90%;
            box-shadow: var(--shadow-lg);
            border: 1px solid var(--border-color);
        }

        .auth-close-btn {
            position: absolute;
            top: 8px;
            right: 8px;
            width: 28px;
            height: 28px;
            line-height: 1;
            border: none;
            background: transparent;
            color: var(--text-secondary, #888);
            font-size: 22px;
            cursor: pointer;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: var(--transition);
        }

        .auth-close-btn:hover {
            background: var(--border-color);
            color: var(--text-primary, #333);
        }

        .auth-tabs {
            display: flex;
            gap: var(--spacing-md);
            margin-bottom: var(--spacing-lg);
            border-bottom: 2px solid var(--border-color);
        }

        .auth-tab {
            flex: 1;
            padding: var(--spacing-md);
            text-align: center;
            cursor: pointer;
            border-bottom: 2px solid transparent;
            margin-bottom: -2px;
            transition: var(--transition);
        }

        .auth-tab.active {
            border-bottom-color: var(--primary-color);
            color: var(--primary-color);
            font-weight: 600;
        }

        .form-group {
            margin-bottom: var(--spacing-md);
        }

        .form-label {
            display: block;
            margin-bottom: var(--spacing-xs);
            font-size: 14px;
            color: var(--text-secondary);
        }

        .datetime-split {
            display: flex;
            gap: 8px;
            align-items: center;
        }

        .datetime-split .form-input {
            flex: 1;
            min-width: 0;
        }

        .form-input {
            width: 100%;
            padding: 12px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            font-size: 14px;
            transition: var(--transition);
            background: var(--input-bg);
            color: var(--text-primary);
        }

        .form-input:focus {
            outline: none;
            border-color: var(--primary-color);
            background: rgba(255, 255, 255, 0.12);
        }

        /* 验证码输入组 */
        .verification-code-group {
            display: flex;
            gap: 8px;
        }

        .verification-code-group .form-input {
            flex: 1;
        }

        .verification-code-group .btn {
            min-width: 100px;
            flex-shrink: 0;
            padding: 12px 16px;
        }

        .form-hint {
            font-size: 12px;
            color: var(--text-tertiary);
            margin-top: 4px;
        }

        .form-hint.success {
            color: var(--success-color);
        }

        .form-hint.error {
            color: var(--danger-color);
        }

        /* 站点详情悬浮栏 */
        #station-info-popup {
            position: fixed;
            top: var(--topbar-anchor-h);
            left: 50%;
            transform: translateX(-50%) translateY(-150%);
            background: var(--panel-bg);
            border-radius: 0 0 8px 8px;
            box-shadow: var(--shadow-lg);
            z-index: var(--z-panel);
            padding: 6px 12px;
            max-width: 95%;
            width: 900px;
            transition: transform 0.5s ease, opacity 0.5s ease;
            border: 1px solid var(--border-color);
            border-top: none;
            backdrop-filter: blur(10px);
            opacity: 0;
            visibility: hidden;
        }

        #station-info-popup.show {
            transform: translateX(-50%) translateY(0);
            opacity: 1;
            visibility: visible;
        }

        #station-info-popup .popup-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 4px;
            padding-bottom: 4px;
            border-bottom: 1px solid var(--border-color);
        }

        #station-info-popup .popup-title {
            font-size: 13px;
            font-weight: 600;
            color: var(--text-primary);
        }

        #station-info-popup .popup-close {
            background: none;
            border: none;
            font-size: 16px;
            cursor: pointer;
            color: var(--text-secondary);
            padding: 0;
            width: 18px;
            height: 18px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: var(--transition);
        }

        #station-info-popup .popup-close:hover {
            color: var(--text-primary);
            background: var(--hover-bg);
            border-radius: 3px;
        }

        #station-info-popup .info-grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 2px 8px;
        }

        #station-info-popup .info-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 2px 4px;
            font-size: 12px;
        }

        #station-info-popup .info-label {
            color: var(--text-secondary);
            font-size: 11px;
        }

        #station-info-popup .info-value {
            color: var(--text-primary);
            font-weight: 500;
            text-align: right;
        }

        @media (max-width: 768px) {
            #station-info-popup {
                width: 95%;
            }

            #station-info-popup .info-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        /* 回放控制面板 */
        #playback-panel {
            position: fixed;
            bottom: 120px;
            left: 0;
            transform: none;
            background: var(--panel-bg);
            border-radius: 12px 12px 0 0;
            box-shadow: var(--shadow-lg);
            padding: 0;
            z-index: var(--z-panel);
            max-width: 95%;
            width: 680px;
            display: none;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .playback-core-controls {
            padding: var(--spacing-sm) var(--spacing-md);
            padding-bottom: 0;
        }

        .playback-drag-handle {
            width: 100%;
            padding: 8px 0;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 12px 12px 0 0;
            position: relative;
            user-select: none;
            -webkit-tap-highlight-color: transparent;
        }

        .playback-drag-handle:active {
            background: rgba(255, 255, 255, 0.1);
        }

        .playback-drag-handle::before {
            content: '';
            width: 40px;
            height: 4px;
            background: var(--text-secondary);
            border-radius: 2px;
            opacity: 0.5;
        }

        .playback-content {
            padding: 0 var(--spacing-md) var(--spacing-sm);
        }

        .playback-advanced-controls {
            transition: max-height 0.3s ease, opacity 0.3s ease;
            max-height: 500px;
            opacity: 1;
            overflow: hidden;
        }

        #playback-panel.collapsed .playback-advanced-controls {
            max-height: 0;
            opacity: 0;
        }

        #playback-panel.active {
            display: block;
        }

        .playback-recording-section {
            margin-top: 10px;
            padding-top: 10px;
            border-top: 1px solid var(--border-color);
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .playback-recording-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
            flex-wrap: wrap;
        }

        .playback-recording-row label {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 11px;
            color: var(--text-secondary);
        }

        .playback-recording-row input[type="checkbox"] {
            margin: 0;
        }

        .playback-recording-hint {
            font-size: 10px;
            color: var(--text-tertiary);
            line-height: 1.5;
        }

        .playback-recording-status {
            font-size: 11px;
            color: var(--text-secondary);
            min-height: 16px;
        }

        #playback-recording-overlay {
            position: fixed;
            top: 18px;
            right: 18px;
            display: none;
            z-index: calc(var(--z-panel) + 20);
            min-width: 0;
            padding: 10px 14px;
            border-radius: 12px;
            background: rgba(0, 0, 0, 0.72);
            color: #fff;
            box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
            backdrop-filter: blur(8px);
            text-align: center;
        }

        #playback-recording-overlay .recording-time {
            font-size: 15px;
            font-weight: 600;
            line-height: 1.4;
            white-space: nowrap;
        }

        body.recording-mode #top-bar,
        body.recording-mode #side-menu,
        body.recording-mode #playback-panel,
        body.recording-mode #data-panel,
        body.recording-mode #panel-trigger,
        body.recording-mode #watch-panel-trigger,
        body.recording-mode #rally-panel-trigger,
        body.recording-mode #case-panel-trigger,
        body.recording-mode #wheel-trigger-btn,
        body.recording-mode .map-layer-btn,
        body.recording-mode #product-controls,
        body.recording-mode .time-displays,
        body.recording-mode #user-settings-panel,
        body.recording-mode #preferences-panel,
        body.recording-mode #typhoon-panel,
        body.recording-mode #stations-panel {
            display: none !important;
        }

        body.recording-mode #playback-recording-overlay {
            display: block;
        }

        .playback-close {
            position: absolute;
            top: 4px;
            right: 8px;
            background: none;
            border: none;
            font-size: 18px;
            cursor: pointer;
            color: var(--text-secondary);
            padding: 0;
            width: 28px;
            height: 28px;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10;
            -webkit-tap-highlight-color: transparent;
        }

        .playback-close:active {
            opacity: 0.7;
        }

        /* 紧凑的设置行 */
        .playback-settings-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 12px;
            margin-bottom: 8px;
        }

        .time-settings {
            display: flex;
            align-items: center;
            gap: 6px;
            flex: 1;
            min-width: 0;
        }

        .replay-mode-settings {
            display: flex;
            gap: 8px;
            align-items: center;
            flex-shrink: 0;
        }

        /* 紧凑的 select 样式 */
        .compact-select {
            padding: 4px 28px 4px 8px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            background-color: var(--input-bg);
            color: var(--text-primary);
            font-size: 12px;
            cursor: pointer;
            outline: none;
        }

        .compact-select:focus {
            border-color: var(--primary-color);
        }

        .time-range-select {
            min-width: 80px;
        }

        /* 紧凑的自定义时间输入 */
        .custom-time-inputs-compact {
            display: flex;
            align-items: center;
            gap: 4px;
            flex: 1;
            min-width: 0;
        }

        .compact-datetime {
            padding: 3px 5px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            font-size: 11px;
            background: var(--input-bg);
            color: var(--text-primary);
            flex: 1;
            min-width: 0;
        }

        .time-separator {
            color: var(--text-secondary);
            font-size: 11px;
            flex-shrink: 0;
        }

        /* 紧凑的 radio 按钮 */
        .mode-radio-compact {
            display: flex;
            align-items: center;
            gap: 3px;
            font-size: 12px;
            color: var(--text-primary);
            cursor: pointer;
            user-select: none;
        }

        .mode-radio-compact input[type="radio"] {
            margin: 0;
            cursor: pointer;
        }

        .mode-radio-compact span {
            white-space: nowrap;
        }

        .playback-controls {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 10px;
        }

        .playback-btn {
            background: var(--primary-color);
            color: var(--text-light);
            border: none;
            padding: 6px 8px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 18px;
            display: flex;
            align-items: center;
            justify-content: center;
            min-width: 38px;
            height: 38px;
            transition: all 0.2s ease;
        }

        .playback-btn:hover {
            opacity: 0.9;
        }

        .playback-btn.secondary {
            background: var(--text-secondary);
        }

        .playback-btn.icon-only {
            min-width: 30px;
            width: 30px;
            height: 30px;
            padding: 0;
            font-size: 15px;
            border-radius: 999px;
            margin-left: 2px;
        }

        /* 关键帧按钮：默认灰底白钻；播放头落在关键帧上时高亮（再点即删除） */
        .playback-btn.keyframe-btn {
            color: var(--text-light);
        }

        .playback-btn.keyframe-btn.is-active {
            background: var(--primary-color);
        }

        .playback-speed {
            display: flex;
            align-items: center;
            gap: var(--spacing-xs);
            margin-left: auto;
        }

        .playback-speed select {
            padding: 4px 8px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            font-size: 12px;
            background: var(--input-bg);
            color: var(--text-primary);
        }

        input[type="number"] {
            background: var(--input-bg);
            color: var(--text-primary);
            border: 1px solid var(--border-color);
        }

        input[type="number"]:focus {
            outline: none;
            border-color: var(--primary-color);
        }

        /* 时间轴滑块 */
        .timeline-container {
            margin-bottom: 14px;
        }

        .timeline-labels {
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 10px;
            color: var(--text-secondary);
            margin-bottom: 6px;
        }

        .timeline-labels #timeline-current-time {
            font-size: 11px;
            font-weight: 600;
            color: var(--primary-color);
        }

        .timeline-slider-wrapper {
            position: relative;
            width: 100%;
            height: 6px;
        }

        /* 关键帧刻度：挂在滑块下方 6px 的空档里，不接管指针事件。
           z-index 必须高于 .timeline-slider（2）：滑块背景是进度渐变，会盖住标记。 */
        .timeline-keyframe-markers {
            position: absolute;
            inset: 0;
            pointer-events: none;
            z-index: 3;
        }

        .timeline-keyframe-marker {
            position: absolute;
            top: 8px;
            width: 5px;
            height: 5px;
            margin-left: -2.5px;
            background: var(--danger-color);
            border-radius: 1px;
            transform: rotate(45deg);
            opacity: 1;
        }

        .timeline-slider {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 6px;
            -webkit-appearance: none;
            appearance: none;
            background: transparent;
            border-radius: 3px;
            outline: none;
            z-index: 2;
        }

        .timeline-slider::-webkit-slider-runnable-track {
            width: 100%;
            height: 6px;
            background: rgba(128, 128, 128, 0.15);
            border-radius: 3px;
            cursor: pointer;
            border: none;
        }

        .timeline-slider::-moz-range-track {
            width: 100%;
            height: 6px;
            background: rgba(128, 128, 128, 0.15);
            border-radius: 3px;
            cursor: pointer;
            border: none;
        }

        .timeline-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 18px;
            height: 18px;
            background: var(--primary-color);
            border-radius: 50%;
            cursor: pointer;
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
            margin-top: -6px;
        }

        .timeline-slider::-moz-range-thumb {
            width: 18px;
            height: 18px;
            background: var(--primary-color);
            border-radius: 50%;
            cursor: pointer;
            border: none;
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }

        .timeline-current-time {
            text-align: center;
            font-size: 14px;
            font-weight: 500;
            color: var(--text-primary);
            margin-top: var(--spacing-xs);
        }

        /* 流畅模式/精确模式切换 */
        .playback-mode-switch {
            margin-top: var(--spacing-md);
            padding-top: var(--spacing-md);
            border-top: 1px solid var(--border-color);
        }

        .mode-radio {
            display: flex;
            align-items: center;
            gap: 6px;
            cursor: pointer;
            padding: 6px 10px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            background: var(--input-bg);
            transition: all 0.2s ease;
            font-size: 12px;
            color: var(--text-primary);
        }

        .mode-radio:hover {
            border-color: var(--primary-color);
            background: rgba(var(--primary-color-rgb, 52, 152, 219), 0.1);
        }

        .mode-radio input[type="radio"] {
            margin: 0;
            cursor: pointer;
        }

        .mode-radio input[type="radio"]:checked + span {
            font-weight: 600;
            color: var(--primary-color);
        }

        #smooth-mode-settings {
            background: rgba(var(--primary-color-rgb, 52, 152, 219), 0.05);
            border: 1px solid rgba(var(--primary-color-rgb, 52, 152, 219), 0.2);
            border-radius: 6px;
            padding: 8px;
        }

        #cache-stats {
            padding: 6px;
            background: var(--hover-bg);
            border-radius: 4px;
        }

        /* 雷达和回放时间显示 */
        .time-displays {
            position: fixed;
            top: calc(var(--topbar-anchor-h) + 14px);
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            flex-direction: column;
            gap: var(--spacing-xs);
            z-index: var(--z-panel);
            pointer-events: none;
        }

        .time-display {
            background: rgb(0, 0, 0);
            color: var(--text-light);
            padding: 6px 12px;
            border-radius: 6px;
            font-size: 13px;
            font-weight: 500;
            text-align: center;
            display: none;
            border: 1px solid rgba(255, 255, 255, 0.1);
        }

        .time-display.active {
            display: block;
        }

        /* 最新帧高亮显示（绿色） */
        .time-display.latest-frame {
            background: var(--success-color);
            border-color: rgba(39, 174, 96, 0.5);
            box-shadow: 0 0 15px rgba(39, 174, 96, 0.3);
        }

        /* 雷达加载中（黄色） */
        .time-display.radar-loading {
            background: var(--warning-color);
            border-color: color-mix(in srgb, var(--warning-color) 50%, transparent);
            box-shadow: 0 0 15px color-mix(in srgb, var(--warning-color) 30%, transparent);
        }

        /* 雷达已加载非最新帧（蓝色） */
        .time-display.radar-loaded {
            background: var(--primary-color);
            border-color: rgba(41, 128, 185, 0.5);
            box-shadow: 0 0 15px rgba(41, 128, 185, 0.3);
        }

        /* 顶部时间芯片：时间显示 + 右侧设置下拉箭头。.time-displays 容器 pointer-events:none，
           芯片单独放行点击（含其内箭头/下拉），不挡地图交互。 */
        .time-chip {
            position: relative;
            pointer-events: auto;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: transform 0.18s ease;   /* 松手后芯片平滑 settle 到新槽位 */
        }

        /* 拖行图层顺序手柄时禁用过渡，芯片完全跟手（不滞后） */
        .time-chip.drag-live {
            transition: none;
        }

        /* 箭头默认隐藏：产品未开启时时间显示无 active、芯片零宽，不露出游离按钮；
           仅当芯片内时间显示 active（产品开启）才显示箭头。 */
        .time-chip-arrow {
            position: absolute;
            right: -27px;
            top: 50%;
            transform: translateY(-50%);
            width: 22px;
            height: 22px;
            padding: 0;
            display: none;
            align-items: center;
            justify-content: center;
            /* 底色**跟随左侧的时次指示器**：它自己是不透明 rgb(0,0,0)（状态时绿/黄/蓝），
               而这里原本写 rgba(0,0,0,0.6)—— 半透明叠在云图上比指示器浅一档，并排看是两块。
               改成一个局部变量，常态取与 .time-display 同款的不透明黑，
               下面三条 :has() 按指示器的状态类覆写它，两者永远同色。 */
            --chip-bg: rgb(0, 0, 0);
            --chip-bd: rgba(255, 255, 255, 0.1);
            background: var(--chip-bg);
            color: var(--text-light);
            border: 1px solid var(--chip-bd);
            border-radius: 6px;
            cursor: pointer;
            transition: var(--transition);
        }

        .time-chip:has(.time-display.active) .time-chip-arrow {
            display: flex;
        }

        /* 指示器四态 → 箭头同色。边框比照各自 .time-display 状态规则的写法
           （绿/蓝用固定 rgba，黄用 color-mix），不另立一套色值。 */
        .time-chip:has(.time-display.latest-frame) .time-chip-arrow {
            --chip-bg: var(--success-color);
            --chip-bd: rgba(39, 174, 96, 0.5);
        }

        .time-chip:has(.time-display.radar-loading) .time-chip-arrow {
            --chip-bg: var(--warning-color);
            --chip-bd: color-mix(in srgb, var(--warning-color) 50%, transparent);
        }

        .time-chip:has(.time-display.radar-loaded) .time-chip-arrow {
            --chip-bg: var(--primary-color);
            --chip-bd: rgba(41, 128, 185, 0.5);
        }

        /* hover 不再换底：底色已携带状态信息，换掉等于把它抹了。
           改成在**自身底色**上混 12% 白提亮一档，四态通用一条规则。
           （--text-light 两个主题都是 #fff，混白在深浅主题下都成立。） */
        .time-chip-arrow:hover {
            background: color-mix(in srgb, var(--chip-bg) 88%, var(--text-light));
            color: var(--text-light);
        }

        /* 展开态：三角翻过来朝上（原来是 JS 把 textContent 在 ▾/▴ 之间改写，
           换成自绘 SVG 后改切这个 class —— 见 UIManager.initProductControls）。 */
        .time-chip-arrow svg {
            transition: transform 0.18s ease;   /* 与芯片 settle 同一时长 */
        }

        .time-chip-arrow.open svg {
            transform: rotate(180deg);
        }

        /* 图层顺序手柄：与右侧下拉箭头相对，位于时次显示浮动窗左侧。默认隐藏，
           仅当双产品开启（.time-displays.has-multi）且本产品开启时显示。 */
        .time-chip-order {
            position: absolute;
            left: -27px;
            top: 50%;
            transform: translateY(-50%);
            width: 22px;
            height: 22px;
            padding: 0;
            display: none;
            align-items: center;
            justify-content: center;
            background: rgba(0, 0, 0, 0.6);
            color: var(--text-light);
            border: 1px solid rgba(255, 255, 255, 0.1);
            border-radius: 6px;
            font-size: 13px;
            font-weight: 700;
            line-height: 1;
            cursor: grab;
            user-select: none;
            -webkit-user-select: none;
            touch-action: none;
            transition: var(--transition);
        }

        .time-displays.has-multi .time-chip:has(.time-display.active) .time-chip-order {
            display: flex;
        }

        .time-chip-order:hover {
            background: var(--hover-bg);
            color: var(--text-primary);
        }

        .time-chip-order.dragging {
            cursor: grabbing;
        }

        .time-chip-settings {
            position: absolute;
            top: calc(100% + 6px);
            right: 0;
            z-index: calc(var(--z-panel) + 1);
            width: 230px;
            background: var(--panel-bg);
            border: 1px solid var(--border-color);
            border-radius: 10px;
            padding: 8px;
            box-shadow: var(--shadow-lg);
            display: flex;
            flex-direction: column;
            gap: 6px;
        }

        .time-chip-settings[hidden] {
            display: none;
        }

        /* 右侧四颗圆钮（雷达/卫星/测站/定位）的公共几何。
           right 取 12px：一是让出边距，二是与正上方的「⌄」胶囊钮（right:12px）
           左缘对齐——两者在同一竖线上，错开反而显乱。
           四颗的纵向位置全部由 --layer-col-* 三个变量推出（见 :root），
           本类只管首颗 #radar-toggle-btn（它没有自己的 top 覆盖）。 */
        .map-layer-btn {
            position: fixed;
            top: var(--layer-col-top);
            right: var(--layer-col-right);
            width: 40px;
            height: 40px;
            background: var(--panel-bg);
            border: 1px solid var(--border-color);
            border-radius: 50%;
            box-shadow: var(--shadow);
            cursor: pointer;
            font-size: 17px;
            z-index: var(--z-panel);
            display: flex;
            align-items: center;
            justify-content: center;
            transition: var(--transition);
            color: var(--text-primary);
        }

        .map-layer-btn:hover {
            transform: scale(1.05);
        }

        .map-layer-btn.active {
            background: var(--primary-color);
            color: var(--text-light);
        }

        /* 卫星云图层按钮（首颗 + 1 档） */
        #satellite-toggle-btn {
            top: calc(var(--layer-col-top) + var(--layer-col-step));
        }

        /* 在线测站图层按钮（首颗 + 2 档） */
        #station-toggle-btn {
            top: calc(var(--layer-col-top) + var(--layer-col-step) * 2);
        }

        /* 在线测站按钮内的 canvas 图标（比按钮内圈略小，避免被 1px 边框裁切） */
        #station-toggle-icon {
            width: 36px;
            height: 36px;
        }

        /* 定位到我的位置按钮：右侧竖列第 4 颗（首颗 + 3 档），与三颗图层钮同列。
           纯本地 HTML5 定位：只把地图中心移到头顶并打红色十字，不上传，所有等级可用。
           left:auto 是必需的——它带 .map-layer-btn 类，早期版本置于左缘时靠
           left:16px 定位；如今改挂右缘，必须显式清掉 left，否则两个方向同时生效
           会把 40px 的宽拉伸到整条视口。 */
        #locate-me-btn {
            top: calc(var(--layer-col-top) + var(--layer-col-step) * 3);
            right: var(--layer-col-right);
            left: auto;
        }

        /* 定位请求进行中：按钮轻微压暗 + 红晕脉冲（表示正在等浏览器定位） */
        #locate-me-btn.locating {
            opacity: .75;
            animation: locate-pulse 1.1s ease-in-out infinite;
        }

        @keyframes locate-pulse {
            0%, 100% {
                box-shadow: var(--shadow), 0 0 0 0 rgba(229, 57, 53, .35);
            }
            50% {
                box-shadow: var(--shadow), 0 0 0 7px rgba(229, 57, 53, 0);
            }
        }

        /* 雷达浏览控制按钮组 */
        #product-controls {
            position: fixed;
            bottom: 110px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            flex-direction: column;
            align-items: stretch;
            gap: 4px;
            width: 340px;
            z-index: var(--z-panel);
            background: var(--panel-bg);
            padding: 8px;
            border-radius: 12px;
            box-shadow: var(--shadow-lg);
            border: 1px solid var(--border-color);
            user-select: none;
            -webkit-user-select: none;
            -moz-user-select: none;
            -webkit-touch-callout: none;   /* iOS 长按不弹菜单/不选中 */
        }

        /* 实时/播放 模式切换（面板顶部一行）：播放模式显示时间轴 + 上/下一帧 + GIF；
         * 实时模式只保留 切换 + 手动刷新(↻) + JPG，面板收缩成迷你条。刷新按钮刻意留在实时态：
         * 用户看到缺片/想立刻拉新帧时在迷你条里就能按（统一更新策略的「强制拉新 + 缺片自愈」入口） */
        .product-mode-row {
            display: flex;
            align-items: center;
            gap: 4px;
            width: 100%;
            margin-bottom: 2px;
            position: relative;   /* 播放设置下拉以整行为定位基准 → 可与 #product-controls 同宽 */
        }
        .product-mode-toggle {
            display: inline-flex;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            overflow: hidden;
            background: var(--input-bg);
        }
        .mode-seg {
            border: none;
            background: transparent;
            color: var(--text-secondary);
            font-size: 11px;
            font-weight: 600;
            padding: 0 14px;
            height: 24px;   /* 与播放控制按钮（.radar-control-btn）等高 */
            cursor: pointer;
            transition: var(--transition);
            line-height: 1;
        }
        .mode-seg:hover {
            background: var(--hover-bg);
        }
        .mode-seg.active {
            background: var(--primary-color);
            color: var(--text-light);
        }

        /* 实时模式：隐藏时间轴（刻度尺/两端标签）与播放控制（自动播放），
         * 只保留导出图标（点击直接导出 JPG）+ 模式切换；面板收缩成迷你条 */
        #product-controls.realtime {
            width: auto;
            min-width: 150px;
        }
        #product-controls.realtime #product-autoplay-btn,
        #product-controls.realtime .layer-slider-labels,
        #product-controls.realtime #product-ruler-scrub {
            display: none;
        }

        .radar-control-btn {
            width: 32px;
            height: 24px;
            background: var(--input-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: var(--transition);
            color: var(--text-primary);
        }

        .radar-control-btn:hover {
            background: var(--hover-bg);
            transform: translateY(-2px);
        }

        .radar-control-btn:active {
            transform: translateY(0);
        }

        .radar-control-btn.active {
            background: var(--primary-color);
            color: var(--text-light);
            border-color: var(--primary-color);
        }

        /* 导出（已并入播放设置下拉，见 .export-full / .product-export-inline） */
        .export-choice {
            display: flex;
            align-items: center;
            justify-content: flex-start;
            gap: 6px;
            width: 100%;
            background: none;
            border: none;
            border-radius: 6px;
            padding: 7px 10px;
            font-size: 12px;
            color: var(--text-primary);
            cursor: pointer;
            text-align: left;
            transition: var(--transition);
        }
        .export-choice:hover {
            background: var(--hover-bg);
            color: var(--primary-color);
        }

        /* 下拉面板顶部通栏导出按钮 + 内联 JPG/GIF 子选项 */
        .export-full {
            width: 100%;
            text-align: center;
            border: 1px dashed color-mix(in srgb, var(--primary-color) 45%, var(--border-color));
            border-radius: 8px;
            background: color-mix(in srgb, var(--primary-color) 8%, var(--input-bg));
            color: var(--primary-color);
            font-size: 12px;
            font-weight: 600;
            padding: 8px 10px;
            cursor: pointer;
            transition: var(--transition);
        }
        .export-full:hover {
            background: color-mix(in srgb, var(--primary-color) 16%, var(--hover-bg));
            border-color: var(--primary-color);
        }
        .product-export-inline {
            display: flex;
            flex-direction: column;
            gap: 4px;
            margin-top: -2px;
        }
        .product-export-inline[hidden] {
            display: none;
        }
        .product-export-inline .export-choice {
            border: 1px solid var(--border-color);
            background: var(--input-bg);
        }
        .product-export-inline .export-choice:hover {
            border-color: color-mix(in srgb, var(--primary-color) 50%, var(--border-color));
        }

        /* 图层播放条：按钮行 */
        .layer-control-buttons {
            display: flex;
            gap: var(--spacing-sm);
            justify-content: center;
        }

        /* 播放控制器单行顶栏：把手 + 实时/播放 + 设置下拉 + 播放按钮 + 刷新（合并后降低面板高度） */
        .product-mode-row .layer-control-buttons {
            flex: 1;
            justify-content: center;
        }

        /* 播放时间范围选择器：按钮行；下拉面板不挂按钮（静态）而挂整行 → 可与播放控制面板同宽 */
        .product-range-wrap {
            position: static;          /* 不再是面板定位基准（面板改挂 .product-mode-row） */
            flex: 0 0 auto;
            display: flex;
            align-items: center;
        }

        #product-range-panel {
            /* 与 #product-controls 同宽：left/right 负偏移 = 面板 border(1px)+padding(8px)，
             * 使下拉面板外沿与播放控制面板外沿精确对齐；内容自适应，不再写死小宽度 */
            width: auto;
            max-width: calc(100vw - 16px);   /* 极小屏兜底，避免水平越界 */
            top: auto;                 /* 覆盖 .time-chip-settings 的向下弹出 → 向上 */
            bottom: calc(100% + 6px);
            left: -9px;
            right: -9px;
            transform: none;
        }

        /* 收窄后面板放不下两个 datetime 并排时自动换行 */
        #product-range-panel .custom-time-inputs-compact {
            flex-wrap: wrap;
        }
        /* 极窄面板内 设置行（标签+控件）与导出按钮自动换行/缩字，避免横向溢出 */
        #product-range-panel .product-setting-row {
            flex-wrap: wrap;
        }
        #product-range-panel .export-full,
        #product-range-panel .product-export-inline .export-choice {
            font-size: 11px;
            padding: 6px 4px;
            text-align: center;
            white-space: normal;
        }
        #product-range-panel .compact-select {
            padding: 3px 20px 3px 6px;
        }
        /* 播放速度行：数字输入（每帧停留 ms）+ 单位 */
        #product-range-panel .speed-field {
            display: flex;
            align-items: center;
            gap: 4px;
        }
        #product-range-panel .compact-number {
            width: 68px;
            padding: 3px 6px;
            background: var(--input-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            color: var(--text-primary);
            font-size: 11px;
            text-align: center;
        }
        #product-range-panel .speed-unit {
            font-size: 10px;
            color: var(--text-tertiary);
            white-space: nowrap;
        }

        /* 下拉面板内的紧凑开关（偏好面板 50px 开关在 280px 面板内偏大，缩到 34×18） */
        .product-range-wrap .toggle-switch {
            width: 34px;
            height: 18px;
        }
        .product-range-wrap .toggle-slider:before {
            height: 14px;
            width: 14px;
            left: 2px;
            bottom: 2px;
        }
        .product-range-wrap .toggle-switch input:checked + .toggle-slider:before {
            transform: translateX(16px);
        }

        /* 左侧 ⋮⋮ 把手：自由拖动面板位置（只定位，不管图层顺序） */
        .product-panel-handle {
            flex: 0 0 auto;
            cursor: grab;
            color: var(--text-secondary);
            font-size: 13px;
            letter-spacing: 3px;
            padding: 6px 4px;
            line-height: 1;
            user-select: none;
            -webkit-user-select: none;
            touch-action: none;   /* 移动端拖动不滚动页面 */
        }

        .product-panel-handle:hover {
            color: var(--text-primary);
        }

        .product-panel-handle.dragging {
            cursor: grabbing;
        }

        /* 右侧展开产品设置（加大箭头）。三角与那两颗时次箭头同款自绘 SVG
           （原先也是字体字符 ▾，见文件上方「方向符号用内联 SVG 自绘」那段），
           只是这一颗不画底、不画边，颜色走 --text-secondary → hover --text-primary。 */
        .product-settings-toggle {
            flex: 0 0 auto;
            background: none;
            border: none;
            color: var(--text-secondary);
            cursor: pointer;
            padding: 8px 10px;
            transition: var(--transition);
        }

        .product-settings-toggle:hover {
            color: var(--text-primary);
            background: var(--hover-bg);
            border-radius: 8px;
        }

        .product-setting-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
            font-size: 11px;
            color: var(--text-secondary);
        }

        .product-setting-row input[type="range"] {
            flex: 1;
            min-width: 0;
            accent-color: var(--primary-color);
            cursor: pointer;
        }

        /* 调色滑块（gamma / 饱和度）：1.0（原图）位置刻度，吸附中心点 */
        .grade-slider-wrap {
            position: relative;
            flex: 1;
            min-width: 0;
        }
        .grade-slider-wrap input[type="range"] {
            width: 100%;
            display: block;
        }
        .grade-snap-tick {
            position: absolute;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 1px;
            height: 11px;
            background: var(--text-secondary);
            opacity: 0.5;
            pointer-events: none;
        }
        /* 刻度位置 = (中性值 − min) / (max − min)：改滑块的量程就得同步改这里的类 */
        .grade-snap-tick.tick-third { left: 33.333%; }  /* gamma:  (1.0−0.5)/(2−0.5) */
        .grade-snap-tick.tick-half  { left: 50%; }      /* 饱和度: (1.0−0)/(2−0)   */
        .grade-snap-tick span {
            position: absolute;
            left: 50%;
            top: 12px;
            transform: translateX(-50%);
            font-size: 9px;
            line-height: 1;
            color: var(--text-secondary);
            white-space: nowrap;
        }
        .grade-snap-tick.active {
            background: var(--primary-color);
            opacity: 1;
        }
        .grade-snap-tick.active span {
            color: var(--primary-color);
        }

        .product-source-select {
            flex: 1;
            min-width: 0;
            background: var(--input-bg);
            color: var(--text-primary);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            font-size: 11px;
            padding: 2px 4px;
            cursor: pointer;
        }

        /* 「云图产品」行右侧的 AB 对比开关：+ 展开 / − 收起（竖线 opacity 归零即变 −） */
        .product-compare-toggle {
            flex: 0 0 auto;          /* 不参与 flex:1 的分配，select 宽度不受影响 */
            width: 18px;
            height: 18px;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0;
            line-height: 0;
            background: var(--input-bg);
            color: var(--text-secondary);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            cursor: pointer;
        }

        .product-compare-toggle:hover,
        .product-compare-toggle.open {
            color: var(--primary-color);
            border-color: var(--primary-color);
        }

        .product-compare-toggle .ico-plus-v {
            transition: opacity 0.12s ease;
        }

        .product-compare-toggle.open .ico-plus-v {
            opacity: 0;
        }

        /* 图层播放条：时间标签（起/当前/止） */
        .layer-slider-labels {
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 10px;
            color: var(--text-secondary);
            margin: 0 2px;
        }

        .layer-slider-current {
            font-size: 11px;
            font-weight: 600;
            color: var(--primary-color);
        }

        /* 主界面防选中：地图应用，拖拽面板/地图时不应误选文本；
           表单输入、链接、弹窗、toast 保留可复制 */
        body {
            user-select: none;
            -webkit-user-select: none;
            -moz-user-select: none;
        }
        input, textarea, [contenteditable] {
            user-select: text;
            -webkit-user-select: text;
            -moz-user-select: text;
        }
        a {
            user-select: text;
            -webkit-user-select: text;
        }
        #station-info-popup, .mapboxgl-popup-content {
            user-select: text;
            -webkit-user-select: text;
        }

        /* 图层播放条：固定中央指针 + 可拖动时间尺（scrub，windy 风格） */
        .layer-ruler-scrub {
            position: relative;
            height: 38px;
            overflow: hidden;
            border-radius: 8px;
            background: rgba(0, 0, 0, 0.28);
            cursor: grab;
            user-select: none;
            -webkit-user-select: none;
            touch-action: none;   /* 拖动时间尺时不触发页面滚动 */
        }
        .layer-ruler-scrub.dragging {
            cursor: grabbing;
        }

        .layer-ruler-pointer {
            position: absolute;
            left: 50%;
            top: 0;
            bottom: 0;
            width: 2px;
            transform: translateX(-50%);
            background: var(--primary-color);
            box-shadow: 0 0 8px rgba(0, 0, 0, 0.55);
            z-index: 2;
            pointer-events: none;
        }
        .layer-ruler-pointer::before {
            content: '';
            position: absolute;
            top: 0;
            left: 50%;
            transform: translateX(-50%);
            border-left: 6px solid transparent;
            border-right: 6px solid transparent;
            border-top: 9px solid var(--primary-color);
        }

        .layer-ruler-track {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            will-change: transform;
            pointer-events: none;
        }
        .layer-ruler-tick {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 1px;
            background: rgba(255, 255, 255, 0.28);
        }
        .layer-ruler-tick-label {
            position: absolute;
            top: 3px;
            transform: translateX(-50%);
            font-size: 9px;
            line-height: 1;
            color: rgba(255, 255, 255, 0.72);
            white-space: nowrap;
        }

        /* 分级预览：越级卫星源锁定态——隐藏刻度尺/指针/按钮，替换为升级横幅
           （UIManager._syncProductRuler 收敛点加 `locked` 类，横幅按 min_level 写文案） */
        #product-controls.locked .layer-ruler-scrub,
        #product-controls.locked .layer-slider-labels,
        #product-controls.locked .layer-control-buttons {
            display: none;
        }
        #product-locked-banner {
            min-height: 38px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 8px;
            background: linear-gradient(90deg, rgba(255, 170, 40, 0.14), rgba(255, 90, 40, 0.14));
            border: 1px solid rgba(255, 170, 40, 0.45);
            color: #ffc864;
            font-size: 13px;
            font-weight: 600;
            letter-spacing: 0.5px;
            cursor: pointer;
            user-select: none;
            -webkit-user-select: none;
            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
        }
        #product-locked-banner:hover {
            background: linear-gradient(90deg, rgba(255, 170, 40, 0.24), rgba(255, 90, 40, 0.24));
        }

        /* 台风路径面板（图层开启时显示活动台风列表 + 强度图例） */
        #typhoon-panel {
            position: fixed;
            top: calc(var(--topbar-anchor-h) + 64px);
            left: 16px;
            width: 232px;
            max-height: calc(100vh - 260px);
            display: none;
            flex-direction: column;
            background: var(--panel-bg);
            border: 1px solid var(--border-color);
            border-radius: 12px;
            box-shadow: var(--shadow-lg);
            z-index: var(--z-panel);
            overflow: hidden;
        }

        #typhoon-panel.active {
            display: flex;
        }

        .typhoon-panel-header {
            display: flex;
            align-items: center;
            gap: var(--spacing-sm);
            padding: 10px var(--spacing-md);
            border-bottom: 1px solid var(--border-color);
            font-size: 13px;
            font-weight: 600;
            color: var(--text-primary);
        }

        .typhoon-panel-close {
            margin-left: auto;
            background: none;
            border: none;
            color: var(--text-secondary);
            font-size: 16px;
            line-height: 1;
            cursor: pointer;
            padding: 0 2px;
        }

        .typhoon-panel-close:hover {
            color: var(--text-primary);
        }

        #typhoon-list {
            overflow-y: auto;
            padding: var(--spacing-xs) 0;
        }

        .typhoon-empty {
            padding: var(--spacing-md);
            font-size: 12px;
            color: var(--text-tertiary);
            text-align: center;
        }

        .typhoon-item {
            padding: 8px var(--spacing-md);
            cursor: pointer;
            border-bottom: 1px solid var(--border-color);
            transition: background 0.2s ease;
        }

        .typhoon-item:last-child {
            border-bottom: none;
        }

        .typhoon-item:hover {
            background: var(--hover-bg);
        }

        .typhoon-item-title {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 12px;
            color: var(--text-primary);
        }

        .typhoon-dot {
            width: 9px;
            height: 9px;
            border-radius: 50%;
            flex-shrink: 0;
        }

        .typhoon-name {
            font-weight: 600;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .typhoon-strong {
            margin-left: auto;
            font-size: 11px;
            color: var(--text-secondary);
            flex-shrink: 0;
        }

        .typhoon-item-meta {
            margin-top: 3px;
            font-size: 11px;
            color: var(--text-secondary);
        }

        .typhoon-item-desc {
            margin-top: 2px;
            font-size: 11px;
            color: var(--text-tertiary);
            line-height: 1.4;
        }

        .typhoon-panel-options {
            padding: var(--spacing-sm) var(--spacing-md);
            border-top: 1px solid var(--border-color);
            display: flex;
            flex-direction: column;
            gap: 5px;
        }

        .typhoon-option {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 11px;
            color: var(--text-secondary);
            cursor: pointer;
        }

        .typhoon-legend {
            padding: var(--spacing-sm) var(--spacing-md);
            border-top: 1px solid var(--border-color);
            display: flex;
            flex-wrap: wrap;
            gap: 4px 10px;
        }

        .typhoon-legend-item {
            display: flex;
            align-items: center;
            gap: 4px;
            font-size: 10px;
            color: var(--text-secondary);
        }

        .typhoon-legend-swatch {
            width: 8px;
            height: 8px;
            border-radius: 2px;
            flex-shrink: 0;
        }

        /* PC 端禁用过渡（拖拽时） */
        #data-panel.resizing {
            transition: none;
        }

        /* 测站数据表格样式 */
        .station-table-section {
            margin-top: var(--spacing-lg);
        }

        .station-table-section .table-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: var(--spacing-sm);
        }

        .station-table-section h4 {
            margin: 0;
            display: flex;
            align-items: center;
            gap: var(--spacing-sm);
        }

        .count-badge {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            min-width: 20px;
            height: 20px;
            padding: 0 6px;
            background: var(--primary-color);
            color: var(--text-light);
            border-radius: 10px;
            font-size: 11px;
            font-weight: 600;
        }

        .btn-icon {
            width: 32px;
            height: 32px;
            border: none;
            background: transparent;
            cursor: pointer;
            border-radius: 4px;
            transition: var(--transition);
            font-size: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .btn-icon:hover {
            background: var(--hover-bg);
        }

        .btn-icon:active {
            transform: scale(0.95);
        }

        .table-container {
            max-height: 400px;
            overflow-y: auto;
            overflow-x: auto;
            border: 1px solid var(--border-color);
            border-radius: 6px;
        }

        .station-table {
            width: 100%;
            border-collapse: collapse;
            font-size: 13px;
        }

        .station-table thead {
            position: sticky;
            top: 0;
            background: var(--panel-bg);
            z-index: 10;
            box-shadow: 0 1px 0 var(--border-color);
        }

        .station-table th {
            padding: 10px 8px;
            text-align: left;
            font-weight: 600;
            color: var(--text-secondary);
            font-size: 11px;
            text-transform: uppercase;
            border-bottom: 2px solid var(--border-color);
            white-space: nowrap;
        }

        .station-table th.sortable {
            cursor: pointer;
            user-select: none;
            transition: var(--transition);
        }

        .station-table th.sortable:hover {
            background: var(--hover-bg);
            color: var(--text-primary);
        }

        .station-table th.sortable .sort-arrow {
            display: inline-block;
            margin-left: 4px;
            opacity: 0.3;
            font-size: 10px;
        }

        .station-table th.sortable .sort-arrow::after {
            content: '⇅';
        }

        .station-table th.sorted-asc .sort-arrow::after {
            content: '↑';
            opacity: 1;
        }

        .station-table th.sorted-desc .sort-arrow::after {
            content: '↓';
            opacity: 1;
        }

        .station-table tbody tr {
            cursor: pointer;
            transition: var(--transition);
            border-bottom: 1px solid var(--border-color);
        }

        .station-table tbody tr:hover {
            background: var(--hover-bg);
        }

        .station-table tbody tr.selected {
            background: color-mix(in srgb, var(--primary-color) 10%, transparent);
            border-left: 3px solid var(--primary-color);
        }

        .station-table tbody tr.empty-row {
            cursor: default;
        }

        .station-table tbody tr.empty-row:hover {
            background: transparent;
        }

        .station-table td {
            padding: 10px 8px;
            color: var(--text-primary);
        }

        .station-table .station-name {
            font-weight: 500;
            color: var(--primary-color);
        }

        .station-table .status-badge {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 10px;
            font-weight: 600;
        }

        .station-table .status-moving {
            background: color-mix(in srgb, var(--success-color) 20%, transparent);
            color: var(--success-color);
        }

        .station-table .status-stopped {
            background: rgba(149, 165, 166, 0.2);
            color: var(--text-secondary);
        }

        @media (max-width: 768px) {
            .station-table {
                font-size: 12px;
            }

            .station-table th,
            .station-table td {
                padding: 8px 6px;
            }

            .table-container {

            /* 增大複選框宽度 */
            .station-table th:first-child {
                width: 56px !important;
                text-align: center;
            }

            .station-table td:first-child {
                text-align: center;
                vertical-align: middle;
                padding: 10px 6px;
            }

            /* 更大触控目标（移动端） */
            @media (max-width: 768px) {
                .station-table th:first-child { width: 64px !important; }
            }
                max-height: 300px;
            }
        }

        /* 用户设置面板 */
        #user-settings-panel,
        #preferences-panel {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 90%;
            max-width: 700px;
            max-height: 85vh;
            background: var(--panel-bg);
            border: 1px solid var(--panel-border);
            border-radius: 12px;
            box-shadow: var(--shadow-lg);
            z-index: var(--z-modal);
            overflow: hidden;
            display: flex;
            flex-direction: column;
        }

        #user-settings-panel .panel-content,
        #preferences-panel .panel-content {
            display: flex;
            flex-direction: column;
            flex: 1;
            min-height: 0;
            overflow: hidden;
        }

        #user-settings-panel .panel-header,
        #preferences-panel .panel-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: var(--spacing-md);
            border-bottom: 1px solid var(--border-color);
            background: var(--panel-bg);
            flex-shrink: 0;
        }

        #user-settings-panel .panel-header h2,
        #preferences-panel .panel-header h2 {
            margin: 0;
            font-size: 20px;
            color: var(--text-primary);
        }

        #user-settings-panel .panel-close,
        #preferences-panel .panel-close,
        #stations-panel .panel-close {
            width: 32px;
            height: 32px;
            border: none;
            background: transparent;
            color: var(--text-secondary);
            font-size: 24px;
            cursor: pointer;
            border-radius: 4px;
            transition: var(--transition);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0;
            line-height: 1;
        }

        #user-settings-panel .panel-close:hover,
        #preferences-panel .panel-close:hover,
        #stations-panel .panel-close:hover {
            background: var(--hover-bg);
            color: var(--danger-color);
        }

        .settings-container {
            flex: 1;
            overflow-y: auto;
            overflow-x: hidden;
            padding: var(--spacing-md);
            min-height: 0;
        }

        /* 美化滚动条 */
        .settings-container::-webkit-scrollbar {
            width: 8px;
        }

        .settings-container::-webkit-scrollbar-track {
            background: var(--hover-bg);
            border-radius: 4px;
        }

        .settings-container::-webkit-scrollbar-thumb {
            background: var(--border-color);
            border-radius: 4px;
        }

        .settings-container::-webkit-scrollbar-thumb:hover {
            background: var(--text-tertiary);
        }

        .settings-section {
            margin-bottom: var(--spacing-lg);
            padding-bottom: var(--spacing-md);
            border-bottom: 1px solid var(--border-color);
        }

        .settings-section:last-child {
            border-bottom: none;
        }

        .settings-section h3 {
            margin: 0 0 var(--spacing-md) 0;
            font-size: 16px;
            color: var(--primary-color);
        }

        .info-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: var(--spacing-sm);
        }

        .info-item {
            display: flex;
            justify-content: space-between;
            padding: var(--spacing-sm);
            background: var(--input-bg);
            border-radius: 6px;
        }

        .info-label {
            font-weight: 500;
            color: var(--text-secondary);
        }

        .info-value {
            color: var(--text-primary);
            font-weight: 600;
        }

        .permissions-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: var(--spacing-sm);
            margin-bottom: var(--spacing-md);
        }

        .perm-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: var(--spacing-md);
            background: var(--input-bg);
            border-radius: 8px;
            gap: 6px;
        }

        .perm-icon {
            font-size: 24px;
        }

        .perm-label {
            font-size: 12px;
            color: var(--text-secondary);
            text-align: center;
        }

        .perm-status {
            font-size: 14px;
            font-weight: 600;
            padding: 2px 8px;
            border-radius: 12px;
        }

        .perm-status.enabled {
            color: var(--success-color);
            background: color-mix(in srgb, var(--success-color) 10%, transparent);
        }

        .perm-status.disabled {
            color: var(--text-tertiary);
            background: var(--hover-bg);
        }

        .quota-info {
            display: flex;
            justify-content: space-around;
            gap: var(--spacing-md);
            padding: var(--spacing-md);
            background: var(--hover-bg);
            border-radius: 8px;
            flex-wrap: wrap;
        }

        .quota-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 6px;
        }

        .quota-item span:first-child {
            font-size: 12px;
            color: var(--text-secondary);
        }

        .quota-item span:last-child {
            font-size: 18px;
            font-weight: 700;
            color: var(--primary-color);
        }

        .upgrade-exam-card {
            border: 1px solid var(--border-color);
            border-radius: 10px;
            padding: var(--spacing-md);
            background: var(--input-bg);
            display: flex;
            flex-direction: column;
            gap: var(--spacing-sm);
        }

        .upgrade-exam-status {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: var(--spacing-sm);
        }

        .upgrade-exam-label {
            font-size: 12px;
            color: var(--text-secondary);
        }

        .upgrade-exam-value {
            font-size: 14px;
            font-weight: 600;
            color: var(--text-primary);
        }

        .upgrade-exam-hint {
            font-size: 12px;
            color: var(--text-tertiary);
        }

        .upgrade-exam-actions {
            display: flex;
            justify-content: flex-end;
        }

        .upgrade-exam-meta {
            margin-bottom: var(--spacing-sm);
            font-size: 12px;
            color: var(--text-secondary);
        }

        .upgrade-exam-question {
            padding: var(--spacing-sm);
            border: 1px solid var(--border-color);
            border-radius: 8px;
            margin-bottom: var(--spacing-sm);
            background: var(--input-bg);
        }

        .upgrade-exam-title {
            font-weight: 600;
            margin-bottom: 6px;
            color: var(--text-primary);
        }

        .upgrade-exam-options {
            display: flex;
            flex-direction: column;
            gap: 6px;
        }

        .upgrade-exam-option {
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 13px;
            color: var(--text-primary);
        }

        .form-actions {
            display: flex;
            gap: var(--spacing-sm);
            margin-top: var(--spacing-md);
        }

        .form-actions .btn {
            flex: 1;
        }

        /* WebLoc 位置共享 */

        /* 开关按钮 */
        .toggle-switch {
            position: relative;
            display: inline-block;
            width: 50px;
            height: 26px;
        }

        .toggle-switch input[type="checkbox"] {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .toggle-slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: var(--border-color);
            transition: var(--transition);
            border-radius: 26px;
        }

        .toggle-slider:before {
            position: absolute;
            content: "";
            height: 20px;
            width: 20px;
            left: 3px;
            bottom: 3px;
            background-color: var(--text-light);
            transition: var(--transition);
            border-radius: 50%;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        }

        .toggle-switch input:checked + .toggle-slider {
            background-color: var(--success-color);
        }

        .toggle-switch input:focus + .toggle-slider {
            box-shadow: 0 0 0 2px color-mix(in srgb, var(--success-color) 20%, transparent);
        }

        .toggle-switch input:checked + .toggle-slider:before {
            transform: translateX(24px);
        }

        .toggle-switch input:disabled + .toggle-slider {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .webloc-warning {
            font-size: 12px;
            color: var(--warning-color);
            padding: var(--spacing-sm);
            background: color-mix(in srgb, var(--warning-color) 10%, transparent);
            border-radius: 6px;
            border-left: 3px solid var(--warning-color);
        }

        .level-badge {
            display: inline-block;
            padding: 2px 8px;
            font-size: 11px;
            font-weight: 600;
            background: var(--primary-color);
            color: var(--text-light);
            border-radius: 10px;
            margin-left: 8px;
            vertical-align: middle;
        }

        @media (max-width: 768px) {
            #user-settings-panel,
            #preferences-panel {
                width: 95%;
                max-height: 90vh;
            }

            #user-settings-panel .panel-header h2,
            #preferences-panel .panel-header h2 {
                font-size: 18px;
            }

            .settings-container {
                padding: var(--spacing-sm);
            }

            .info-grid {
                grid-template-columns: 1fr;
            }

            .permissions-grid {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        /* 测站管理面板 */
        #stations-panel {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            z-index: var(--z-modal);
            display: flex;
            align-items: center;
            justify-content: center;
            backdrop-filter: blur(4px);
        }

        #stations-panel .panel-content {
            background: var(--panel-bg);
            border-radius: 12px;
            width: 90%;
            max-width: 800px;
            max-height: 85vh;
            display: flex;
            flex-direction: column;
            min-height: 0;
            overflow: hidden;
            box-shadow: var(--shadow-lg);
        }

        #stations-panel .panel-header-actions,
        #preferences-panel .panel-header-actions {
            display: flex;
            align-items: center;
            gap: 8px;
        }
        #pref-preset-select {
            width: auto;
            padding: 5px 8px;
            font-size: 12.5px;
            color: var(--text-primary);
            background: var(--panel-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            cursor: pointer;
            max-width: 130px;
        }
        #pref-preset-select:hover {
            border-color: var(--primary-color);
        }

        #stations-upload-help-btn {
            padding: 5px 10px;
            font-size: 12px;
            line-height: 1.2;
            border-radius: 6px;
        }

        .stations-container {
            flex: 1;
            overflow-y: auto;
            min-height: 0;
            padding: var(--spacing-lg);
        }

        .stations-container::-webkit-scrollbar {
            width: 8px;
        }

        .stations-container::-webkit-scrollbar-track {
            background: rgba(255, 255, 255, 0.05);
            border-radius: 4px;
        }

        .stations-container::-webkit-scrollbar-thumb {
            background: rgba(255, 255, 255, 0.2);
            border-radius: 4px;
        }

        .stations-container::-webkit-scrollbar-thumb:hover {
            background: rgba(255, 255, 255, 0.3);
        }

        .quota-info {
            background: var(--input-bg);
            border-radius: 8px;
            padding: var(--spacing-md);
            margin-bottom: var(--spacing-lg);
        }

        .quota-label {
            font-size: 14px;
            color: var(--text-secondary);
            margin-bottom: var(--spacing-sm);
        }

        .quota-bar-wrapper {
            display: flex;
            align-items: center;
            gap: var(--spacing-md);
        }

        .quota-bar {
            flex: 1;
            height: 8px;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 4px;
            overflow: hidden;
        }

        .quota-bar-fill {
            height: 100%;
            background: var(--success-color);
            transition: width 0.4s ease;
        }

        .quota-bar-fill.full {
            background: var(--danger-color);
        }

        .quota-text {
            font-weight: 700;
            font-size: 16px;
            color: var(--text-primary);
            min-width: 60px;
            text-align: right;
        }

        .quota-hint {
            font-size: 12px;
            color: var(--text-tertiary);
            margin-top: var(--spacing-sm);
        }

        .create-station-section {
            background: var(--input-bg);
            border-radius: 8px;
            padding: var(--spacing-lg);
            margin-bottom: var(--spacing-lg);
        }

        .create-station-section h3 {
            margin-bottom: var(--spacing-md);
            color: var(--text-primary);
            font-size: 16px;
        }

        .form-hint {
            font-size: 12px;
            color: var(--text-tertiary);
            margin-top: 4px;
        }

        .stations-list-section h3 {
            margin-bottom: var(--spacing-md);
            color: var(--text-primary);
            font-size: 16px;
        }

        .stations-list {
            display: grid;
            gap: var(--spacing-md);
        }

        .station-card {
            background: var(--input-bg);
            border: 1px solid var(--border-color);
            border-radius: 8px;
            padding: var(--spacing-md);
            transition: var(--transition);
        }

        .station-card:hover {
            border-color: var(--primary-color);
            box-shadow: 0 2px 8px color-mix(in srgb, var(--primary-color) 20%, transparent);
        }

        .station-card-header {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: var(--spacing-sm);
        }

        .station-card-title {
            display: flex;
            align-items: center;
            gap: var(--spacing-sm);
        }

        .station-card-title h4 {
            font-size: 16px;
            color: var(--text-primary);
            margin: 0;
        }

        .station-status {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 700;
        }

        .station-status.active {
            background: color-mix(in srgb, var(--success-color) 20%, transparent);
            color: var(--success-color);
        }

        .station-status.inactive {
            background: rgba(149, 165, 166, 0.2);
            color: var(--text-tertiary);
        }

        .station-card-actions {
            display: flex;
            gap: var(--spacing-xs);
        }

        .station-card-actions button {
            padding: 4px 8px;
            font-size: 12px;
            border: none;
            background: rgba(255, 255, 255, 0.1);
            color: var(--text-secondary);
            border-radius: 4px;
            cursor: pointer;
            transition: var(--transition);
        }

        .station-card-actions button:hover {
            background: rgba(255, 255, 255, 0.2);
            color: var(--text-primary);
        }

        .station-card-actions .delete-btn {
            background: color-mix(in srgb, var(--danger-color) 15%, transparent);
            color: var(--danger-color);
            font-weight: 600;
            padding: 6px 10px;
        }

        .station-card-actions .delete-btn:hover {
            background: color-mix(in srgb, var(--danger-color) 20%, transparent);
            color: var(--danger-color);
        }

        .station-card-actions .data-manage-btn {
            background: color-mix(in srgb, var(--primary-color) 18%, transparent);
            color: var(--primary-color);
            font-weight: 600;
            padding: 6px 10px;
        }

        .station-card-actions .data-manage-btn:hover {
            background: color-mix(in srgb, var(--primary-color) 30%, transparent);
            color: var(--text-primary);
        }

        .station-card-actions .security-btn {
            background: color-mix(in srgb, var(--warning-color) 18%, transparent);
            color: var(--warning-color);
            font-weight: 600;
            padding: 6px 10px;
        }

        .station-card-actions .security-btn:hover {
            background: color-mix(in srgb, var(--warning-color) 30%, transparent);
            color: var(--text-primary);
        }

        .station-card-actions .reactivate-btn {
            background: color-mix(in srgb, var(--success-color) 15%, transparent);
            color: var(--success-color);
            font-weight: 600;
            padding: 6px 12px;
        }

        .station-card-actions .reactivate-btn:hover {
            background: color-mix(in srgb, var(--success-color) 30%, transparent);
            color: var(--success-color);
        }

        .station-card-meta {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: var(--spacing-sm);
            font-size: 13px;
            color: var(--text-secondary);
        }

        .station-card-meta .meta-item {
            display: flex;
            flex-direction: column;
            gap: 2px;
        }

        .station-card-meta .meta-label {
            font-size: 11px;
            color: var(--text-tertiary);
        }

        .station-card-meta .meta-value {
            color: var(--text-primary);
            font-weight: 500;
        }

        .station-card-meta .quota-usage-display {
            display: inline-flex;
            align-items: center;
            gap: 8px;
        }

        .station-card-meta .station-quota-ring {
            width: 28px;
            height: 28px;
            flex: 0 0 28px;
        }

        .station-card-meta .quota-usage-text {
            font-variant-numeric: tabular-nums;
            letter-spacing: 0.01em;
        }

        .loading-placeholder {
            text-align: center;
            padding: var(--spacing-xl);
            color: var(--text-tertiary);
        }

        .empty-placeholder {
            text-align: center;
            padding: var(--spacing-xl);
            color: var(--text-tertiary);
        }

        .empty-placeholder p {
            margin-bottom: var(--spacing-sm);
        }

        @media (max-width: 768px) {
            #stations-panel .panel-content {
                width: 95%;
                max-height: 90vh;
            }

            .create-station-section,
            .stations-container {
                padding: var(--spacing-md);
            }

            .station-card-meta {
                grid-template-columns: 1fr;
            }
        }

        /* Watch 管理 */

        #watches-panel {
            min-height: 0;
            --watch-scrollbar-track: rgba(0, 0, 0, 0.04);
            --watch-scrollbar-thumb: color-mix(in srgb, var(--primary-color) 35%, transparent);
            --watch-scrollbar-thumb-hover: color-mix(in srgb, var(--primary-color) 60%, transparent);
        }

        .theme-dark #watches-panel {
            --watch-scrollbar-track: rgba(255, 255, 255, 0.06);
            --watch-scrollbar-thumb: rgba(144, 164, 174, 0.45);
            --watch-scrollbar-thumb-hover: rgba(144, 164, 174, 0.75);
        }

        .watches-container {
            flex: 1;
            overflow-y: auto;
            min-height: 0;
            padding: var(--spacing-lg);
        }

        .watches-container::-webkit-scrollbar {
            width: 8px;
        }

        .watches-container::-webkit-scrollbar-track {
            background: rgba(255, 255, 255, 0.05);
            border-radius: 4px;
        }

        .watches-container::-webkit-scrollbar-thumb {
            background: rgba(255, 255, 255, 0.2);
            border-radius: 4px;
        }

        .watches-container::-webkit-scrollbar-thumb:hover {
            background: rgba(255, 255, 255, 0.3);
        }

        .watches-list-section .table-container::-webkit-scrollbar {
            width: 10px;
            height: 10px;
        }

        .watches-list-section .table-container::-webkit-scrollbar-track {
            background: var(--watch-scrollbar-track);
            border-radius: 8px;
        }

        .watches-list-section .table-container::-webkit-scrollbar-thumb {
            background: var(--watch-scrollbar-thumb);
            border-radius: 8px;
            border: 2px solid transparent;
            background-clip: content-box;
        }

        .watches-list-section .table-container::-webkit-scrollbar-thumb:hover {
            background: var(--watch-scrollbar-thumb-hover);
            background-clip: content-box;
        }

        .watches-list-section .table-container {
            scrollbar-color: var(--watch-scrollbar-thumb) var(--watch-scrollbar-track);
            scrollbar-width: thin;
        }

        /* 工具栏选项 */
        .filter-options {
            display: flex;
            align-items: center;
            gap: var(--spacing-sm);
        }

        .watches-table-wrapper {
            background: var(--input-bg);
            border-radius: 8px;
            overflow: hidden;
            border: 1px solid var(--border-color);
        }

        .watches-table tbody tr.expired {
            opacity: 0.6;
        }

        .watches-table .badge {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 700;
        }

        .watches-table .badge.active {
            background: color-mix(in srgb, var(--success-color) 20%, transparent);
            color: var(--success-color);
        }

        .watches-table .badge.expired {
            background: rgba(149, 165, 166, 0.2);
            color: var(--text-tertiary);
        }

        .category-badge {
            display: inline-block;
            padding: 4px 10px;
            border-radius: 4px;
            font-size: 12px;
            font-weight: 600;
        }

        .category-badge.category-ST { background: color-mix(in srgb, var(--warning-color) 20%, transparent); color: var(--warning-color); }
        .category-badge.category-SC { background: color-mix(in srgb, var(--danger-color) 20%, transparent); color: var(--danger-color); }
        .category-badge.category-TOR { background: color-mix(in srgb, var(--danger-color) 20%, transparent); color: var(--danger-color); }
        .category-badge.category-TY { background: rgba(156, 39, 176, 0.2); color: #9C27B0; }
        .category-badge.category-WD { background: color-mix(in srgb, var(--primary-color) 20%, transparent); color: var(--primary-color); }
        .category-badge.category-GD { background: color-mix(in srgb, var(--success-color) 20%, transparent); color: var(--success-color); }
        .category-badge.category-BD { background: color-mix(in srgb, var(--text-tertiary) 20%, transparent); color: var(--text-tertiary); }
        .category-badge.category-OT { background: rgba(96, 125, 139, 0.2); color: #607D8B; }
        .category-badge.category-MS { background: rgba(0, 188, 212, 0.2); color: #00BCD4; }

        .severity-badge {
            padding: 2px 6px;
            border-radius: 3px;
            font-size: 11px;
            font-weight: 600;
        }

        .severity-badge.severity-0 { background: color-mix(in srgb, var(--text-tertiary) 20%, transparent); color: var(--text-tertiary); }
        .severity-badge.severity-1 { background: color-mix(in srgb, var(--success-color) 20%, transparent); color: var(--success-color); }
        .severity-badge.severity-2 { background: color-mix(in srgb, var(--warning-color) 20%, transparent); color: var(--warning-color); }
        .severity-badge.severity-3 { background: color-mix(in srgb, var(--warning-color) 20%, transparent); color: var(--warning-color); }
        .severity-badge.severity-4 { background: color-mix(in srgb, var(--danger-color) 20%, transparent); color: var(--danger-color); }

        /* 操作按钮 hover 效果 */
        .watches-table .locate-btn,
        .watches-table .delete-btn {
            min-width: 36px;
            min-height: 32px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }

        .watches-table .locate-btn:hover {
            background: color-mix(in srgb, var(--primary-color) 20%, transparent);
        }

        .watches-table .delete-btn:hover {
            background: color-mix(in srgb, var(--danger-color) 20%, transparent);
        }

        @media (max-width: 768px) {
            /* Watch 特定的响应式样式 */
            .watch-type-filters .filter-buttons {
                max-height: 120px;
                overflow-y: auto;
            }

            .watches-table {
                font-size: 12px;
            }

            .watches-table th,
            .watches-table td {
                padding: 8px 6px;
            }
        }

        /* 面板组件系统 */

        /* 通用工具栏 */
        .panel-toolbar,
        .watches-toolbar,
        .rally-toolbar,
        .cases-toolbar {
            display: flex;
            gap: var(--spacing-md);
            margin-bottom: var(--spacing-lg);
            align-items: center;
            flex-wrap: wrap;
        }

        /* 通用搜索框 */
        .panel-search-box,
        .watch-search-box,
        .rally-search-box,
        .case-search-box {
            flex: 1;
            min-width: 200px;
            position: relative;
        }

        .panel-search-box input,
        .watch-search-box input,
        .rally-search-box input,
        .case-search-box input {
            width: 100%;
        }

        /* 通用筛选容器 */
        .panel-type-filters,
        .watch-type-filters,
        .rally-type-filters,
        .case-type-filters,
        .case-review-filters {
            display: flex;
            align-items: center;
            gap: var(--spacing-sm);
            margin-bottom: var(--spacing-lg);
            padding: var(--spacing-md);
            background: rgba(255, 255, 255, 0.03);
            border-radius: 8px;
            border: 1px solid var(--border-color);
        }

        .panel-type-filters .filter-label,
        .watch-type-filters .filter-label,
        .rally-type-filters .filter-label,
        .case-type-filters .filter-label,
        .case-review-filters .filter-label {
            font-size: 13px;
            font-weight: 600;
            color: var(--text-secondary);
            white-space: nowrap;
            margin-right: 8px;
        }

        .panel-type-filters .filter-buttons,
        .watch-type-filters .filter-buttons,
        .rally-type-filters .filter-buttons,
        .case-type-filters .filter-buttons,
        .case-review-filters .filter-buttons {
            display: flex;
            flex-wrap: wrap;
            gap: 6px;
            flex: 1;
        }

        .panel-type-filters .filter-btn,
        .watch-type-filters .filter-btn,
        .rally-type-filters .filter-btn,
        .case-type-filters .filter-btn,
        .case-review-filters .filter-btn {
            padding: 6px 12px;
            font-size: 12px;
            font-weight: 500;
            border: 1px solid var(--border-color);
            background: var(--input-bg);
            color: var(--text-secondary);
            border-radius: 16px;
            cursor: pointer;
            transition: all 0.2s ease;
            white-space: nowrap;
        }

        .panel-type-filters .filter-btn:hover,
        .watch-type-filters .filter-btn:hover,
        .rally-type-filters .filter-btn:hover,
        .case-type-filters .filter-btn:hover,
        .case-review-filters .filter-btn:hover {
            background: rgba(255, 255, 255, 0.1);
            border-color: var(--primary-color);
            color: var(--text-primary);
        }

        .panel-type-filters .filter-btn.active,
        .watch-type-filters .filter-btn.active,
        .rally-type-filters .filter-btn.active,
        .case-type-filters .filter-btn.active,
        .case-review-filters .filter-btn.active {
            background: var(--primary-color);
            border-color: var(--primary-color);
            color: var(--text-light);
            font-weight: 600;
            box-shadow: 0 2px 8px color-mix(in srgb, var(--primary-color) 30%, transparent);
        }

        .panel-type-filters .filter-btn:active,
        .watch-type-filters .filter-btn:active,
        .rally-type-filters .filter-btn:active,
        .case-type-filters .filter-btn:active,
        .case-review-filters .filter-btn:active {
            transform: scale(0.95);
        }

        .cases-stats {
            padding: 8px 10px;
            background: var(--input-bg);
            border: 1px solid var(--border-color);
            border-radius: 6px;
            margin-bottom: 10px;
            font-size: 12px;
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
        }

        .cases-stats .stat-item {
            font-weight: 500;
        }

        .cases-stats .stat-year {
            color: var(--text-secondary);
        }

        .cases-stats .stat-pending {
            color: var(--warning-color);
        }

        .cases-stats .stat-approved {
            color: var(--success-color);
        }

        .cases-stats .stat-rejected {
            color: var(--danger-color);
        }

        /* 通用表格 */
        .panel-table,
        .watches-table,
        .rally-points-table,
        .cases-table {
            width: 100%;
            border-collapse: collapse;
        }

        .panel-table thead,
        .watches-table thead,
        .rally-points-table thead,
        .cases-table thead {
            background: var(--panel-bg);
        }

        .panel-table th,
        .watches-table th,
        .rally-points-table th,
        .cases-table th {
            padding: 12px;
            text-align: left;
            font-size: 12px;
            font-weight: 600;
            color: var(--text-tertiary);
            border-bottom: 1px solid var(--border-color);
            white-space: nowrap;
        }

        .panel-table td,
        .watches-table td,
        .rally-points-table td,
        .cases-table td {
            padding: 12px;
            border-bottom: 1px solid rgba(255, 255, 255, 0.05);
            vertical-align: top;
        }

        .panel-table tbody tr,
        .watches-table tbody tr,
        .rally-points-table tbody tr,
        .cases-table tbody tr {
            transition: var(--transition);
        }

        .panel-table tbody tr:hover,
        .watches-table tbody tr:hover,
        .rally-points-table tbody tr:hover,
        .cases-table tbody tr:hover {
            background: rgba(255, 255, 255, 0.03);
        }

        /* 通用操作按钮 */
        .panel-action-btn,
        .watches-table .action-btn,
        .rally-points-table .action-btn,
        .cases-table .action-btn {
            padding: 6px 10px;
            font-size: 14px;
            border: none;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 4px;
            cursor: pointer;
            transition: var(--transition);
            margin: 0 2px;
        }

        .panel-action-btn:hover,
        .watches-table .action-btn:hover,
        .rally-points-table .action-btn:hover,
        .cases-table .action-btn:hover {
            background: rgba(255, 255, 255, 0.2);
        }

        .panel-action-btn:disabled,
        .watches-table .action-btn:disabled,
        .rally-points-table .action-btn:disabled,
        .cases-table .action-btn:disabled {
            opacity: 0.3;
            cursor: not-allowed;
        }

        /* 案例表格内按钮紧凑化 */
        .cases-table .btn {
            padding: 4px 8px;
            font-size: 12px;
            border-radius: 3px;
            margin: 0 2px;
        }

        /* 通用 Modal 样式 */
        .common-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 10000;
            overflow-y: auto;
        }

        .common-modal.active {
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .modal-content,
        .common-modal .modal-content {
            background: var(--panel-bg);
            max-width: 600px;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
            width: 90%;
            max-height: 90vh;
            overflow-y: auto;
        }

        .modal-header,
        .common-modal .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 20px;
            border-bottom: 1px solid var(--border-color);
            flex-shrink: 0;
        }

        .modal-header h3,
        .common-modal .modal-header h3 {
            margin: 0;
            font-size: 18px;
            font-weight: 600;
            color: var(--text-primary);
        }

        .modal-header-actions,
        .common-modal .modal-header-actions {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .modal-header .close-btn,
        .common-modal .modal-header .close-btn {
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            color: var(--text-tertiary);
            transition: var(--transition);
            padding: 0;
            width: 24px;
            height: 24px;
        }

        .modal-header .close-btn:hover,
        .common-modal .modal-header .close-btn:hover {
            color: var(--text-primary);
        }

        .modal-body,
        .common-modal .modal-body {
            padding: 20px;
            flex: 1;
            overflow-y: auto;
        }

        .modal-footer,
        .common-modal .modal-footer {
            display: flex;
            justify-content: flex-end;
            gap: 10px;
            padding: 20px;
            border-top: 1px solid var(--border-color);
            flex-shrink: 0;
        }

        /* Markdown 渲染内容（关于本站 / 免责声明） */
        .md-render {
            font-size: 13px;
            line-height: 1.8;
            color: var(--text-primary);
            word-break: break-word;
        }

        .md-render h1,
        .md-render h2,
        .md-render h3,
        .md-render h4,
        .md-render h5,
        .md-render h6 {
            margin: 1.2em 0 0.5em;
            font-weight: 600;
            line-height: 1.4;
            color: var(--text-primary);
        }

        .md-render h1 {
            font-size: 20px;
        }

        .md-render h2 {
            font-size: 17px;
            padding-bottom: 6px;
            border-bottom: 1px solid var(--border-color);
        }

        .md-render h3 {
            font-size: 15px;
        }

        .md-render h4 {
            font-size: 14px;
        }

        .md-render h5,
        .md-render h6 {
            font-size: 13px;
        }

        .md-render p {
            margin: 0.6em 0;
        }

        .md-render ul,
        .md-render ol {
            margin: 0.6em 0;
            padding-left: 1.6em;
        }

        .md-render ul {
            list-style: disc;
        }

        .md-render ol {
            list-style: decimal;
        }

        .md-render li {
            margin: 0.25em 0;
        }

        .md-render hr {
            border: none;
            border-top: 1px solid var(--border-color);
            margin: 1.2em 0;
        }

        .md-render strong {
            font-weight: 600;
        }

        .md-render em {
            font-style: italic;
        }

        .md-render code {
            font-family: 'SF Mono', Menlo, Consolas, monospace;
            font-size: 12px;
            background: var(--border-color);
            padding: 2px 4px;
            border-radius: 4px;
        }

        .md-render pre {
            background: var(--border-color);
            padding: 12px;
            border-radius: 6px;
            overflow-x: auto;
        }

        .md-render pre code {
            background: none;
            padding: 0;
        }

        .md-render blockquote {
            margin: 0.6em 0;
            padding: 2px 12px;
            border-left: 3px solid var(--border-color);
            color: var(--text-secondary);
        }

        .md-render a {
            color: var(--primary-color);
            text-decoration: none;
        }

        .md-render a:hover {
            text-decoration: underline;
        }

        .md-render table {
            border-collapse: collapse;
            margin: 0.8em 0;
            width: 100%;
            font-size: 12px;
        }

        .md-render th,
        .md-render td {
            border: 1px solid var(--border-color);
            padding: 6px 10px;
            text-align: left;
        }

        .md-render th {
            background: color-mix(in srgb, var(--text-primary) 6%, transparent);
        }

        /* 案例报告样式 */
        .case-report-content {
            max-width: 760px;
        }

        .case-report-title {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .case-report-badge {
            font-size: 11px;
            padding: 2px 8px;
            border-radius: 999px;
            background: rgba(255, 255, 255, 0.08);
            color: var(--text-secondary);
        }

        .case-report-badge.status-approved {
            background: color-mix(in srgb, var(--success-color) 20%, transparent);
            color: var(--success-color);
        }

        .case-report-badge.status-pending {
            background: color-mix(in srgb, var(--warning-color) 20%, transparent);
            color: var(--warning-color);
        }

        .case-report-badge.status-rejected {
            background: color-mix(in srgb, var(--danger-color) 20%, transparent);
            color: var(--danger-color);
        }

        .case-report-grid {
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 10px 16px;
        }

        .case-report-item {
            display: flex;
            flex-direction: column;
            gap: 2px;
        }

        .case-report-item label {
            font-size: 11px;
            color: var(--text-tertiary);
        }

        .case-report-item div {
            font-size: 13px;
            color: var(--text-primary);
            word-break: break-word;
        }

        .case-rating-container {
            display: flex;
            gap: 24px;
            align-items: flex-start;
        }

        .rating-display {
            flex: 1;
        }

        .rating-stars-large {
            display: flex;
            gap: 4px;
            font-size: 24px;
            color: var(--text-primary);
            margin-bottom: 8px;
        }

        .rating-stars-large .star.filled {
            color: var(--warning-color);
        }

        .rating-stats {
            display: flex;
            align-items: baseline;
            gap: 8px;
        }

        #case-rating-avg-text {
            font-size: 16px;
            font-weight: 600;
            color: var(--text-primary);
        }

        .rating-action {
            min-width: 140px;
            padding: 8px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 4px;
        }

        .rating-stars-interactive {
            display: flex;
            gap: 3px;
            font-size: 28px;
            cursor: pointer;
        }

        .rating-stars-interactive .star {
            color: var(--text-tertiary);
            transition: color 0.15s ease;
            user-select: none;
        }

        .rating-stars-interactive .star:hover,
        .rating-stars-interactive .star.hover {
            color: var(--warning-color);
        }

        .rating-stars-interactive .star.selected {
            color: var(--warning-color);
        }

        .btn-text {
            background: none;
            border: none;
            padding: 4px 0;
            cursor: pointer;
            font-size: 11px;
            text-decoration: underline;
        }

        .btn-text:hover {
            opacity: 0.8;
        }

        /* 案例参与者列表样式 */
        .case-participants-list {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin-top: 8px;
        }

        .participant-tag {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 6px 12px;
            background: color-mix(in srgb, var(--success-color) 15%, transparent);
            border: 1px solid color-mix(in srgb, var(--success-color) 30%, transparent);
            border-radius: 16px;
            font-size: 13px;
            color: var(--success-color);
            transition: all 0.2s ease;
        }

        .participant-tag:hover {
            background: color-mix(in srgb, var(--success-color) 25%, transparent);
            border-color: color-mix(in srgb, var(--success-color) 50%, transparent);
            transform: translateY(-1px);
        }

        .participant-tag .role-badge {
            font-size: 10px;
            padding: 2px 6px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 8px;
            text-transform: uppercase;
        }

        @media (max-width: 640px) {
            .case-rating-container {
                flex-direction: column;
                gap: 16px;
            }

            .rating-action {
                width: 100%;
            }
        }

        @media (max-width: 640px) {
            .case-report-grid {
                grid-template-columns: 1fr;
            }
        }

        @media (max-width: 768px) {
            .panel-toolbar,
            .watches-toolbar,
            .rally-toolbar,
            .cases-toolbar {
                flex-direction: column;
                align-items: stretch;
            }

            .panel-type-filters,
            .watch-type-filters,
            .rally-type-filters,
            .case-type-filters {
                flex-direction: column;
                align-items: stretch;
            }

            .modal-content,
            .common-modal .modal-content {
                width: 95%;
                margin: 20px auto;
            }
        }

        /* 天地图 InfoWindow：与通用弹窗同一套深色视觉 */
        .tdt-infowindow-content-wrapper {
            background: var(--panel-bg) !important;
            color: var(--text-primary) !important;
            border-radius: 8px !important;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3) !important;
        }

        /* InfoWindow 的箭头与面板保持同一背景，避免白尖角残留 */
        .tdt-infowindow-tip {
            background: var(--panel-bg) !important;
        }

        /* 修正地图 SDK 将 InfoWindow 内容压在白色 wrapper 内时的文字可读性 */
        .tdt-infowindow-content {
            color: var(--text-primary);
        }

        /* 案例信息窗按钮：回放为偏白暗色按钮，查看为主强调色按钮 */
        .case-action-btn.btn-play {
            background: rgba(255, 255, 255, 0.14) !important;
            color: var(--text-light) !important;
            border: 1px solid var(--border-color) !important;
        }

        .case-action-btn.btn-play:hover {
            background: rgba(255, 255, 255, 0.2) !important;
            color: var(--text-light) !important;
        }

        .case-action-btn.btn-play:active {
            background: rgba(255, 255, 255, 0.1) !important;
            color: var(--text-light) !important;
        }

        .case-action-btn.btn-view {
            background: var(--primary-color) !important;
            color: var(--text-light) !important;
            border: 1px solid var(--primary-color) !important;
        }

        .case-action-btn.btn-view:hover {
            background: color-mix(in srgb, var(--primary-color) 82%, black) !important;
            color: var(--text-light) !important;
            border-color: color-mix(in srgb, var(--primary-color) 82%, black) !important;
        }

        .case-action-btn.btn-view:active {
            background: color-mix(in srgb, var(--primary-color) 88%, black) !important;
            color: var(--text-light) !important;
            border-color: color-mix(in srgb, var(--primary-color) 88%, black) !important;
        }

        /* 表单样式 */

        .form-group {
            margin-bottom: 15px;
        }

        .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: 600;
            color: var(--text-primary);
            font-size: 14px;
        }

        .form-group label .required {
            color: var(--error-color);
        }

        .form-input {
            width: 100%;
            padding: 8px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            background: var(--input-bg);
            color: var(--text-primary);
            font-size: 14px;
            font-family: inherit;
            transition: var(--transition);
        }

        .form-input:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary-color) 10%, transparent);
        }

        .form-input:disabled {
            background: rgba(255, 255, 255, 0.05);
            cursor: not-allowed;
        }

        .form-row {
            display: flex;
            gap: 15px;
            margin-bottom: 15px;
        }

        .form-row .form-group {
            flex: 1;
            margin-bottom: 0;
        }

        .checkbox-label {
            display: flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            color: var(--text-primary);
            font-size: 14px;
        }

        .settings-hint {
            font-size: 12px;
            color: var(--text-tertiary);
            margin: 0 0 10px;
            line-height: 1.5;
        }

        /* ===== 首次访问欢迎引导 ===== */
        .welcome-lead {
            font-size: 13px;
            color: var(--text-secondary);
            line-height: 1.7;
            margin: 0 0 16px;
        }
        .welcome-actions {
            display: flex;
            gap: 12px;
        }
        .welcome-actions .btn {
            flex: 1;
        }
        .welcome-advanced {
            margin: 0 0 16px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            padding: 10px 12px;
        }
        .welcome-advanced summary {
            cursor: pointer;
            font-size: 13px;
            font-weight: 600;
            color: var(--text-primary);
            margin-bottom: 4px;
            user-select: none;
        }
        .welcome-advanced .checkbox-label {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 5px 0;
        }
        .welcome-contributor {
            background: rgba(27, 142, 236, 0.06);
            border: 1px dashed rgba(27, 142, 236, 0.35);
            border-radius: 8px;
            padding: 12px;
            margin: 16px 0;
            text-align: center;
        }
        .welcome-contributor-note {
            font-size: 12px;
            color: var(--text-secondary);
            line-height: 1.7;
            margin: 10px 0 0;
            white-space: pre-line;
        }
        .welcome-confirm-row {
            display: flex;
            justify-content: center;
            margin-top: 8px;
        }
        #welcome-confirm-btn {
            min-width: 180px;
        }

        /* ===== 卫星云图产品介绍（首次激活云图） ===== */
        .sat-intro-grid {
            display: flex;
            flex-direction: column;
            gap: 12px;
        }
        .sat-intro-card {
            border: 1px solid var(--border-color);
            border-radius: 8px;
            padding: 12px 14px;
        }
        .sat-intro-card h4 {
            margin: 0 0 6px;
            font-size: 14px;
            font-weight: 600;
            color: var(--text-primary);
            display: flex;
            align-items: center;
            flex-wrap: wrap;
        }
        .sat-intro-card p {
            margin: 0;
            font-size: 12.5px;
            line-height: 1.8;
            color: var(--text-secondary);
        }
        .sat-intro-card img.sat-intro-img {
            display: block;
            width: calc(100% + 28px);
            margin: 10px -14px 0;
            aspect-ratio: 16 / 9;
            object-fit: cover;
            max-height: 30vh;
            border-radius: 8px;
            background: #0a0f14;
        }
        .sat-intro-tag {
            display: inline-block;
            font-size: 11px;
            padding: 1px 8px;
            border-radius: 10px;
            margin-left: 8px;
        }
        .sat-intro-tag.free,
        .sat-intro-tag.premium {
            background: rgba(139, 148, 158, 0.16);
            color: #9aa3ad;
        }
        .sat-intro-legend {
            display: flex;
            flex-wrap: wrap;
            gap: 8px 14px;
            margin-top: 8px;
        }
        .sat-intro-legend .sw {
            display: inline-flex;
            align-items: center;
            gap: 5px;
            font-size: 12px;
            color: var(--text-secondary);
        }
        .sat-intro-legend .dot {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            display: inline-block;
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
        .sat-intro-more {
            text-align: center;
            margin-top: 18px;
        }
        .sat-intro-more a {
            color: var(--primary-color);
            font-size: 13px;
            font-weight: 600;
            text-decoration: none;
            cursor: pointer;
            transition: opacity .2s;
        }
        .sat-intro-more a:hover {
            opacity: .8;
            text-decoration: underline;
        }

        .usage-help-grid {
            display: flex;
            flex-direction: column;
            gap: 6px;
        }
        .usage-help-card {
            display: flex;
            align-items: center;
            text-align: left;
            padding: 10px 12px;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            background: transparent;
            cursor: pointer;
            transition: var(--transition);
            color: var(--text-primary);
            font-family: inherit;
            font-size: 13px;
        }
        .usage-help-card:hover {
            background: var(--hover-bg);
            border-color: var(--primary-color);
        }
        .usage-help-title {
            font-weight: 600;
        }

        .checkbox-label input[type="checkbox"] {
            cursor: pointer;
        }

        .radio-label {
            display: flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            color: var(--text-primary);
            font-size: 14px;
            margin-bottom: 8px;
        }

        .radio-label input[type="radio"] {
            cursor: pointer;
        }

        .info-box {
            background: color-mix(in srgb, var(--primary-color) 10%, transparent);
            border-left: 4px solid var(--primary-color);
            padding: 12px;
            margin-bottom: 15px;
            border-radius: 4px;
        }

        .info-box p {
            margin: 0;
            font-size: 12px;
            color: var(--primary-color);
        }

        /* ==================== 邀请用户标签样式 ==================== */

        #invited-users-list {
            margin-top: 12px;
            padding: 10px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 6px;
        }

        #invited-users-list > div:first-child {
            font-size: 12px;
            color: var(--text-secondary);
            margin-bottom: 8px;
        }

        #invited-users-tags {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
        }

        .user-tag {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 6px 12px;
            background: color-mix(in srgb, var(--primary-color) 15%, transparent);
            border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
            border-radius: 16px;
            font-size: 13px;
            color: var(--primary-color);
            transition: all 0.2s ease;
        }

        .user-tag:hover {
            background: color-mix(in srgb, var(--primary-color) 25%, transparent);
            border-color: color-mix(in srgb, var(--primary-color) 50%, transparent);
            transform: translateY(-1px);
        }

        .user-tag .remove-user-btn {
            background: none;
            border: none;
            color: var(--danger-color);
            cursor: pointer;
            font-size: 18px;
            padding: 0;
            width: 18px;
            height: 18px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            transition: all 0.2s ease;
            margin-left: 2px;
        }

        .user-tag .remove-user-btn:hover {
            background: color-mix(in srgb, var(--danger-color) 20%, transparent);
            color: var(--danger-color);
            transform: scale(1.1);
        }

        #invite-user-id-input {
            flex: 1;
            min-width: 0;
        }

        #add-invite-user-btn {
            flex-shrink: 0;
            padding: 8px 16px;
            background: var(--primary-color);
            color: var(--text-light);
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s ease;
            white-space: nowrap;
        }

        #add-invite-user-btn:hover {
            background: var(--secondary-color);
            transform: translateY(-1px);
            box-shadow: 0 2px 8px color-mix(in srgb, var(--primary-color) 30%, transparent);
        }

        #add-invite-user-btn:active {
            transform: translateY(0);
        }

        /* 响应式 */
        @media (max-width: 768px) {
            .form-row {
                flex-direction: column;
                gap: 0;
            }

            .form-row .form-group {
                margin-bottom: 15px;
            }
        }

        /* 响应式断点 */
        @media (max-width: 768px) {
            #data-panel {
                --panel-width: 100%;
                width: 100%;
                right: -100%;
            }

            /* 移动端隐藏 resize handle */
            .panel-resize-handle {
                display: none;
            }

            #product-controls {
                bottom: 85px;
                gap: 4px;
                padding: 6px;
                width: min(340px, 94vw);
            }

            /* 移动端面板 padding=6px → 下拉贴齐外沿的负偏移改为 border(1)+padding(6)=7px */
            #product-range-panel {
                left: -7px;
                right: -7px;
            }

            .radar-control-btn {
                width: 28px;
                height: 21px;
                font-size: 13px;
            }

            .layer-slider-labels {
                font-size: 9px;
            }

            .layer-slider-current {
                font-size: 10px;
            }

            #typhoon-panel {
                top: auto;
                bottom: 200px;
                left: 8px;
                /* 右侧留出图层按钮列（48px 按钮 + 16px 边距），避免遮挡面板开关 */
                right: 72px;
                width: auto;
                max-height: 42vh;
            }

            #playback-panel {
                width: 100%;
                bottom: 60px;
                left: 0;
                border-radius: 16px 16px 0 0;
                max-height: calc(100vh - 180px);
            }

            #playback-panel.collapsed {
                max-height: 100px;
            }

            .playback-content {
                padding: 0 12px 10px;
            }

            .playback-core-controls {
                padding: 6px 12px 0;
            }

            .playback-drag-handle {
                padding: 6px 0;
                border-radius: 16px 16px 0 0;
            }

            .playback-drag-handle::before {
                width: 50px;
                height: 5px;
            }

            .playback-settings-row {
                flex-direction: column;
                gap: 6px;
                align-items: stretch;
            }

            .time-settings {
                flex-wrap: wrap;
            }

            .replay-mode-settings {
                justify-content: flex-start;
            }

            .compact-select {
                font-size: 11px;
                padding: 3px 6px;
            }

            .compact-datetime {
                font-size: 10px;
                padding: 3px 4px;
            }

            .timeline-container {
                margin-bottom: 10px;
            }

            .timeline-labels {
                font-size: 9px;
                margin-bottom: 4px;
            }

            .timeline-labels #timeline-current-time {
                font-size: 10px;
            }

            .playback-controls {
                flex-wrap: nowrap;
                overflow-x: auto;
                gap: 5px;
                margin-bottom: 8px;
            }

            .playback-btn {
                min-width: 36px;
                height: 36px;
                font-size: 16px;
                flex-shrink: 0;
            }

            .playback-speed {
                width: auto;
                margin-left: auto;
                justify-content: flex-start;
                flex-shrink: 0;
            }

            .playback-speed > div {
                flex-direction: row;
                width: auto;
                gap: 4px;
            }

            .playback-speed input[type="number"] {
                width: 50px;
                padding: 2px;
                font-size: 10px;
            }

            .playback-speed label {
                font-size: 9px;
            }

            .playback-mode-switch {
                margin-top: 6px;
            }

            .playback-speed input {
                width: auto;
            }
        }

        /* 隐藏天地图版权信息 */
        .tdt-control-copyright, .tdt-control-attribution {
            display: none !important;
        }

        /* ========== 现代化全局下拉选择器样式 ========== */
        select.form-input, select {
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
            background-color: var(--input-bg);
            color: var(--text-primary);
            border: 1px solid var(--border-color);
            padding: 8px 36px 8px 12px;
            border-radius: 8px;
            font-size: 13px;
            background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24'><path fill='%23bbbbbb' d='M7 10l5 5 5-5z'/></svg>");
            background-repeat: no-repeat;
            background-position: right 10px center;
            transition: border-color 0.3s ease, box-shadow 0.3s ease;
        }

        select.form-input:focus, select:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 6px color-mix(in srgb, var(--primary-color) 6%, transparent);
        }

        /* Hide default arrow on IE */
        select::-ms-expand { display: none; }

        /* ========== 现代化分页/时间轴滑块样式 ========== */
        input[type="range"].timeline-slider {
            -webkit-appearance: none;
            appearance: none;
            width: 100%;
            height: 12px;
            background: transparent;
            margin: 6px 0;
        }

        input[type="range"].timeline-slider::-webkit-slider-runnable-track {
            height: 8px;
            background: color-mix(in srgb, var(--primary-color) 25%, transparent);
            border-radius: 999px;
        }

        input[type="range"].timeline-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 18px;
            height: 18px;
            margin-top: -5px;
            border-radius: 50%;
            background: var(--primary-color);
            box-shadow: 0 4px 12px rgba(0,0,0,0.6);
            border: 2px solid rgba(255,255,255,0.9);
        }

        input[type="range"].timeline-slider:focus::-webkit-slider-runnable-track {
            box-shadow: 0 0 0 6px color-mix(in srgb, var(--primary-color) 6%, transparent);
        }

        /* Firefox styles */
        input[type="range"].timeline-slider::-moz-range-track {
            height: 8px;
            background: color-mix(in srgb, var(--primary-color) 25%, transparent);
            border-radius: 999px;
        }

        input[type="range"].timeline-slider::-moz-range-thumb {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: var(--primary-color);
            border: 2px solid rgba(255,255,255,0.9);
            box-shadow: 0 4px 12px rgba(0,0,0,0.6);
        }

        /* ========== 现代化滚动条样式 ========== */
        /* Firefox */
        :root {
            scrollbar-width: thin;
            scrollbar-color: color-mix(in srgb, var(--primary-color) 80%, transparent) rgba(255,255,255,0.03);
        }

        /* Webkit browsers */
        *::-webkit-scrollbar {
            width: 10px;
            height: 10px;
        }

        *::-webkit-scrollbar-track {
            background: transparent;
            border-radius: 10px;
        }

        *::-webkit-scrollbar-thumb {
            background: color-mix(in srgb, var(--primary-color) 90%, transparent);
            border-radius: 10px;
            border: 2px solid rgba(0,0,0,0.12);
        }

        *::-webkit-scrollbar-thumb:hover {
            filter: brightness(1.05);
        }

        /* 针对面板和表格的更细致样式 */
        .panel-content, .table-container, #status-text, .watches-list {
            scrollbar-width: thin;
            scrollbar-color: color-mix(in srgb, var(--primary-color) 85%, transparent) transparent;
        }

        .panel-content::-webkit-scrollbar-thumb, .table-container::-webkit-scrollbar-thumb, .watches-list::-webkit-scrollbar-thumb {
            background: color-mix(in srgb, var(--primary-color) 85%, transparent);
            border-radius: 10px;
        }

        /* ========== 现代化 Checkbox 样式 ========== */
        input[type="checkbox"] {
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
            width: 18px;
            height: 18px;
            border: 1px solid var(--border-color);
            border-radius: 4px;
            background: transparent;
            display: inline-block;
            vertical-align: middle;
            position: relative;
            cursor: pointer;
            transition: all 0.18s ease;
        }

        input[type="checkbox"]:hover {
            box-shadow: 0 2px 6px rgba(0,0,0,0.15);
        }

        input[type="checkbox"]:checked {
            background: var(--primary-color);
            border-color: transparent;
            box-shadow: 0 4px 10px rgba(0,0,0,0.35);
            background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23ffffff' d='M20.285 6.708l-11.39 11.39-5.18-5.18 1.415-1.415 3.765 3.765 9.975-9.975z'/></svg>");
            background-repeat: no-repeat;
            background-position: center center;
            background-size: 12px 12px;
        }

        input[type="checkbox"]:focus {
            outline: none;
            box-shadow: 0 0 0 6px color-mix(in srgb, var(--primary-color) 6%, transparent);
        }

        /* 使用 Rally Points 风格的灰色勾，统一全系统勾选样式 */
        input[type="checkbox"]:checked {
            background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='%23777777' d='M20.285 6.708l-11.39 11.39-5.18-5.18 1.415-1.415 3.765 3.765 9.975-9.975z'/></svg>");
            background-repeat: no-repeat;
            background-position: center center;
            background-size: 12px 12px;
        }

        /* 兼容老式复选框显示的 label 调整 */
        .checkbox-label {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            color: var(--text-primary);
            font-size: 13px;
        }
