    * { margin: 0; padding: 0; box-sizing: border-box; }

    :root {
      --primary: #8e44ad;
      --primary-light: #9b59b6;
      --accent: #2ecc71;
      --bg: #0f0c29;
      --card-bg: rgba(255, 255, 255, 0.05);
      --card-border: rgba(255, 255, 255, 0.1);
      --text: #ecf0f1;
      --text-muted: #bdc3c7;
      --gradient-1: linear-gradient(135deg, #8e44ad, #3498db);
      --gradient-2: linear-gradient(135deg, #e74c3c, #f1c40f);
      --gradient-3: linear-gradient(135deg, #1abc9c, #2ecc71);
      --font-heading: 'Space Grotesk', sans-serif;
      --font-body: 'Outfit', sans-serif;

      /* ============================================================ */
      /* Figma UI Demo Design Tokens (新视觉体系, 2026-04-22)           */
      /* 对齐 docs/UI示例代码/src/styles/theme.css                     */
      /* 命名与旧 token 完全不冲突, 保留旧 token 确保渐进切换零回归     */
      /* ============================================================ */

      /* ── 背景层 ── */
      --ds-bg-base: #020617;                    /* slate-950: 页面最底背景 */
      --ds-bg-surface: #0f172a;                 /* slate-900: 次层表面 */
      --ds-bg-elevated: rgba(255, 255, 255, 0.05);  /* 毛玻璃卡片底 */
      --ds-bg-raised: rgba(255, 255, 255, 0.08);    /* hover/active 卡片底 */
      --ds-bg-modal: rgba(2, 6, 23, 0.85);          /* Modal 遮罩 */
      --ds-bg-input: rgba(255, 255, 255, 0.04);     /* 深色输入框底 */

      /* ── 光斑 / 网格 / 装饰层 ── */
      --ds-glow-purple: rgba(168, 85, 247, 0.2);    /* purple-500/20 */
      --ds-glow-blue: rgba(59, 130, 246, 0.2);      /* blue-500/20 */
      --ds-glow-cyan: rgba(34, 211, 238, 0.1);      /* cyan-500/10 */
      --ds-glow-pink: rgba(236, 72, 153, 0.15);     /* pink-500/15 */
      --ds-grid-line: rgba(255, 255, 255, 0.02);

      /* ── 边框层 ── */
      --ds-border-subtle: rgba(255, 255, 255, 0.08);
      --ds-border-default: rgba(255, 255, 255, 0.12);
      --ds-border-strong: rgba(255, 255, 255, 0.2);
      --ds-border-brand: rgba(168, 85, 247, 0.3);

      /* ── 文字层 ── */
      --ds-text-primary: #ffffff;
      --ds-text-secondary: #cbd5e1;             /* slate-300: 次级正文 */
      --ds-text-tertiary: #94a3b8;              /* slate-400: 辅助说明 */
      --ds-text-dim: #64748b;                   /* slate-500: 占位/禁用 */

      /* ── 品牌色 ── */
      --ds-brand-purple: #a855f7;               /* purple-500 */
      --ds-brand-purple-hover: #c084fc;         /* purple-400 */
      --ds-brand-cyan: #22d3ee;                 /* cyan-400 */
      --ds-brand-cyan-hover: #67e8f9;           /* cyan-300 */
      --ds-brand-pink: #ec4899;
      --ds-brand-orange: #f97316;
      --ds-brand-green: #10b981;
      --ds-brand-yellow: #eab308;
      --ds-brand-red: #ef4444;

      /* ── 渐变 (对齐 Demo AppCard gradient prop) ── */
      --ds-gradient-brand: linear-gradient(135deg, #a855f7, #22d3ee);            /* 主 CTA */
      --ds-gradient-brand-hover: linear-gradient(135deg, #c084fc, #67e8f9);      /* 主 CTA hover */
      --ds-gradient-purple-pink: linear-gradient(135deg, #a855f7, #ec4899);      /* purple→pink */
      --ds-gradient-blue-cyan: linear-gradient(135deg, #3b82f6, #06b6d4);        /* blue→cyan */
      --ds-gradient-orange-red: linear-gradient(135deg, #f97316, #ef4444);       /* orange→red */
      --ds-gradient-green-emerald: linear-gradient(135deg, #10b981, #059669);    /* green→emerald */
      --ds-gradient-indigo-purple: linear-gradient(135deg, #6366f1, #a855f7);    /* indigo→purple */
      --ds-gradient-yellow-orange: linear-gradient(135deg, #eab308, #f97316);    /* yellow→orange */
      --ds-gradient-red-pink: linear-gradient(135deg, #ef4444, #ec4899);         /* red→pink */
      --ds-gradient-teal-blue: linear-gradient(135deg, #14b8a6, #3b82f6);        /* teal→blue */
      --ds-gradient-hero-title: linear-gradient(90deg, #ffffff, #e9d5ff, #a5f3fc);  /* Hero 标题文字渐变 */

      /* ── 圆角 ── */
      --ds-radius-xs: 4px;
      --ds-radius-sm: 8px;
      --ds-radius-md: 12px;
      --ds-radius-lg: 16px;
      --ds-radius-xl: 20px;
      --ds-radius-2xl: 24px;
      --ds-radius-pill: 9999px;

      /* ── 阴影 / 发光 ── */
      --ds-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
      --ds-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.25);
      --ds-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.35);
      --ds-shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.45);
      --ds-shadow-glow-brand: 0 8px 32px rgba(168, 85, 247, 0.3);
      --ds-shadow-glow-cyan: 0 8px 32px rgba(34, 211, 238, 0.3);
      --ds-ring-focus: 0 0 0 2px rgba(168, 85, 247, 0.5);

      /* ── 毛玻璃 ── */
      --ds-blur-glass: blur(12px) saturate(1.2);
      --ds-blur-heavy: blur(24px) saturate(1.4);
      --ds-blur-light: blur(8px) saturate(1.1);

      /* ── 动效 ── */
      --ds-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
      --ds-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
      --ds-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
      --ds-duration-fast: 0.15s;
      --ds-duration-base: 0.3s;
      --ds-duration-slow: 0.5s;

      /* ── 间距 (可选, 部分场景使用) ── */
      --ds-space-xs: 4px;
      --ds-space-sm: 8px;
      --ds-space-md: 16px;
      --ds-space-lg: 24px;
      --ds-space-xl: 32px;
      --ds-space-2xl: 48px;
    }

    /* ============================================================ */
    /* [data-theme="light"] 浅色主题 (Liquid Glass)                   */
    /* ============================================================ */
    [data-theme="light"] {
      /* 背景层 */
      --ds-bg-base: #f8f7ff;
      --ds-bg-surface: #ffffff;
      --ds-bg-elevated: rgba(255, 255, 255, 0.7);
      --ds-bg-raised: rgba(255, 255, 255, 0.85);
      --ds-bg-modal: rgba(248, 247, 255, 0.8);
      --ds-bg-input: rgba(0, 0, 0, 0.04);
      
      /* 光晕层 */
      --ds-glow-purple: rgba(139, 92, 246, 0.15);
      --ds-glow-blue: rgba(59, 130, 246, 0.15);
      --ds-glow-cyan: rgba(34, 211, 238, 0.1);
      --ds-glow-pink: rgba(236, 72, 153, 0.1);
      --ds-grid-line: rgba(0, 0, 0, 0.04);

      /* 边框层 */
      --ds-border-subtle: rgba(0, 0, 0, 0.05);
      --ds-border-default: rgba(0, 0, 0, 0.1);
      --ds-border-strong: rgba(0, 0, 0, 0.15);
      --ds-border-brand: rgba(139, 92, 246, 0.3);

      /* 文字层 */
      --ds-text-primary: #1e1b4b;
      --ds-text-secondary: #4c4a6a;
      --ds-text-tertiary: #7c7a9a;
      --ds-text-dim: #a5a5c0;

      /* 玻璃态阴影 */
      --ds-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
      --ds-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
      --ds-shadow-lg: 0 8px 32px rgba(139, 92, 246, 0.08);
      --ds-shadow-xl: 0 24px 64px rgba(139, 92, 246, 0.15);
      --ds-shadow-glow-brand: 0 8px 32px rgba(139, 92, 246, 0.2);
      --ds-shadow-glow-cyan: 0 8px 32px rgba(34, 211, 238, 0.2);
    }

    [data-theme="light"] body {
      background: linear-gradient(135deg, rgba(248, 247, 255, 1) 0%, rgba(236, 242, 255, 1) 33%, rgba(232, 255, 250, 1) 66%, rgba(248, 247, 255, 1) 100%);
      background-size: 400% 400%;
      animation: heroBgAnim 15s ease infinite;
    }

    [data-theme="light"] .hero {
      background: transparent;
      border-bottom: 1px solid var(--ds-border-subtle);
    }

    [data-theme="light"] .card,
    [data-theme="light"] .project-card,
    [data-theme="light"] .skill-card,
    [data-theme="light"] .ranking-sidebar {
      background: rgba(255, 255, 255, 0.7);
      backdrop-filter: blur(16px) saturate(1.2);
      -webkit-backdrop-filter: blur(16px) saturate(1.2);
      border: 1px solid rgba(255, 255, 255, 0.5);
      box-shadow: 
        0 8px 32px rgba(139, 92, 246, 0.08),
        inset 0 0 0 1px rgba(255, 255, 255, 0.4);
    }

    [data-theme="light"] .card:hover,
    [data-theme="light"] .project-card:hover,
    [data-theme="light"] .skill-card:hover {
      background: rgba(255, 255, 255, 0.85);
      box-shadow: 
        0 12px 40px rgba(139, 92, 246, 0.12),
        inset 0 0 0 1px rgba(255, 255, 255, 0.6);
    }

    [data-theme="light"] .modal-overlay,
    [data-theme="light"] .search-modal-overlay,
    [data-theme="light"] .my-projects-overlay,
    [data-theme="light"] .cms-overlay {
      background: rgba(248, 247, 255, 0.8);
      backdrop-filter: blur(8px);
      -webkit-backdrop-filter: blur(8px);
    }

    [data-theme="light"] .modal-content,
    [data-theme="light"] .modal-box,
    [data-theme="light"] .search-modal-box,
    [data-theme="light"] .my-projects-box,
    [data-theme="light"] .cms-box {
      background: rgba(255, 255, 255, 0.95);
      border: 1px solid rgba(139, 92, 246, 0.15);
      box-shadow: 0 24px 64px rgba(139, 92, 246, 0.15);
    }

    [data-theme="light"] .btn-primary,
    [data-theme="light"] .search-modal-item.active {
      background: linear-gradient(135deg, #8b5cf6, #06b6d4);
      color: white;
      box-shadow: 0 4px 16px rgba(139, 92, 246, 0.3);
      border: none;
    }

    [data-theme="light"] .btn-primary:hover {
      box-shadow: 0 6px 24px rgba(139, 92, 246, 0.4);
    }

    [data-theme="light"] .navbar {
      background: rgba(255, 255, 255, 0.8);
      backdrop-filter: blur(20px);
      border-bottom: 1px solid rgba(139, 92, 246, 0.1);
    }

    [data-theme="light"] .project-status-filter {
      background: rgba(255, 255, 255, 0.6) !important;
      backdrop-filter: blur(10px);
    }

    /* 修复搜索图标颜色 */
    [data-theme="light"] .search-modal-item-icon {
      background: rgba(139, 92, 246, 0.1);
    }
    
    /* 侧边栏及其他半透明层调整 */
    [data-theme="light"] .ranking-sidebar-cat.active,
    [data-theme="light"] .ranking-sidebar-dim.active {
      background: rgba(139, 92, 246, 0.1);
      color: var(--ds-brand-purple);
    }

    [data-theme="light"] .form-input,
    [data-theme="light"] .search-modal-input {
      background: rgba(255, 255, 255, 0.6);
      border-color: var(--ds-border-strong);
      color: var(--ds-text-primary);
    }

    [data-theme="light"] .form-input:focus,
    [data-theme="light"] .search-modal-input:focus {
      background: #ffffff;
      border-color: var(--ds-brand-purple);
      box-shadow: 0 0 0 2px rgba(139, 92, 246, 0.2);
    }

    /* Theme Toggle Button Styles — 临时隐藏，恢复时将 display:none 改回 display:flex */
    .theme-toggle-btn {
      background: transparent;
      border: 1px solid var(--ds-border-strong);
      color: var(--ds-text-secondary);
      border-radius: var(--ds-radius-pill);
      width: 32px;
      height: 32px;
      display: none;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      transition: all var(--ds-duration-base) var(--ds-ease-out);
      margin-left: 8px;
    }
    .theme-toggle-btn:hover {
      background: var(--ds-bg-elevated);
      color: var(--ds-text-primary);
      border-color: var(--ds-border-brand);
      transform: translateY(-1px);
    }
    .theme-toggle-btn i {
      width: 16px;
      height: 16px;
    }
    .theme-toggle-btn .icon-moon { display: block; }
    .theme-toggle-btn .icon-sun { display: none; }

    [data-theme="light"] .theme-toggle-btn .icon-moon { display: none; }
    [data-theme="light"] .theme-toggle-btn .icon-sun { display: block; }
    [data-theme="light"] .theme-toggle-btn:hover {
      background: rgba(255, 255, 255, 0.9);
    }

    body {
      font-family: var(--font-body);
      background: linear-gradient(to bottom, #0f0c29, #302b63, #24243e);
      color: var(--text);
      min-height: 100vh;
      overflow-x: hidden;
    }

    /* ===== Hero Section ===== */
    .hero {
      position: relative;
      height: 42vh;
      min-height: 320px;
      max-height: 400px;
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      /* Cool animated gradient background */
      background: linear-gradient(-45deg, #0f0c29, #302b63, #24243e, #1a1a3e);
      background-size: 400% 400%;
      animation: heroBgAnim 15s ease infinite;
      cursor: pointer;
    }

    /* Grid overlay for tech vibe */
    .hero::before {
      content: "";
      position: absolute;
      top: 0; left: 0; right: 0; bottom: 0;
      background-image: 
        linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
      background-size: 40px 40px;
      mask-image: radial-gradient(circle at center, black 40%, transparent 100%);
      -webkit-mask-image: radial-gradient(circle at center, black 40%, transparent 100%);
      pointer-events: none;
    }

    @keyframes heroBgAnim {
      0% { background-position: 0% 50%; }
      50% { background-position: 100% 50%; }
      100% { background-position: 0% 50%; }
    }

    #particle-canvas {
      position: absolute;
      top: 0; left: 0;
      width: 100%; height: 100%;
      z-index: 1;
    }

    /* Subtitle Overlay */
    .hero-overlay {
      position: absolute;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      pointer-events: none;
      z-index: 2;
    }

    .hero-subtitle-text {
      margin-top: 160px; /* More space below particle title */
      font-family: var(--font-body);
      font-size: clamp(1.2rem, 4vw, 1.6rem); /* Increased size */
      letter-spacing: 4px;
      font-weight: 600; /* Thicker like tabs */
      text-transform: uppercase;
      background: linear-gradient(90deg, #fff, #a29bfe, #81ecec, #fff);
      background-size: 200% auto;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      animation: textShine 4s linear infinite, fadeInUp 1s ease 2s forwards;
      opacity: 0;
    }
    .hero-subtitle-text .hero-count-num {
      font-family: 'STFangsong', 'FangSong', '华文仿宋', serif;
      font-size: 1.15em;
      font-weight: 700;
      letter-spacing: 2px;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background: inherit;
      background-size: inherit;
    }

    @keyframes textShine {
      to { background-position: 200% center; }
    }

    @keyframes fadeInUp {
      from { opacity: 0; transform: translateY(20px); }
      to { opacity: 0.8; transform: translateY(0); }
    }

    @keyframes gradientShift {
      0%, 100% { background-position: 0% 50%; }
      50% { background-position: 100% 50%; }
    }

    /* ===== Navbar ===== */
    .navbar {
      position: sticky;
      top: 0;
      z-index: 100;
      display: flex;
      justify-content: center;
      gap: 6px;
      padding: 8px 16px;
      background: linear-gradient(135deg, rgba(48, 43, 99, 0.75), rgba(36, 36, 62, 0.8), rgba(15, 12, 41, 0.75));
      backdrop-filter: blur(24px) saturate(1.4);
      -webkit-backdrop-filter: blur(24px) saturate(1.4);
      border-bottom: 1px solid rgba(142, 68, 173, 0.15);
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.05);
      overflow-x: auto;
      scrollbar-width: none;
      -webkit-overflow-scrolling: touch;
    }
    
    .navbar::-webkit-scrollbar {
      display: none;
    }

    .nav-item {
      padding: 10px 28px;
      cursor: pointer;
      font-size: 14px;
      font-weight: 600;
      color: rgba(189, 195, 199, 0.8);
      transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
      position: relative;
      letter-spacing: 0.5px;
      border-radius: 8px;
      background: transparent;
      user-select: none;
      white-space: nowrap;
      flex-shrink: 0;
    }

    .nav-item:hover {
      color: var(--text);
    }

    .nav-item.active {
      color: #fff;
      background: transparent;
      box-shadow: none;
      text-shadow: 0 0 12px rgba(142, 68, 173, 0.6);
    }

    .nav-item::after {
      content: '';
      position: absolute;
      bottom: 0; left: 50%;
      width: 0; height: 3px;
      background: linear-gradient(90deg, #8e44ad, #3498db);
      border-radius: 2px 2px 0 0;
      transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;
      transform: translateX(-50%);
      opacity: 0;
      box-shadow: 0 -2px 8px rgba(142, 68, 173, 0.5);
    }

    .nav-item.active::after {
      width: 100%;
      opacity: 1;
    }

    .nav-count {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      min-width: 20px;
      height: 18px;
      padding: 0 5px;
      font-size: 11px;
      font-weight: 700;
      background: rgba(142, 68, 173, 0.3);
      border-radius: 9px;
      margin-left: 4px;
      vertical-align: middle;
      line-height: 1;
    }

    .nav-item.active .nav-count {
      background: rgba(142, 68, 173, 0.6);
      color: #fff;
    }

    /* Footer Notice */
    .footer-notice {
      text-align: center;
      padding: 20px;
      font-size: 12px;
      color: rgba(189, 195, 199, 0.4);
      border-top: 1px solid rgba(255, 255, 255, 0.05);
      margin-bottom: 20px;
    }

    /* Footer Beian — 2026-04-24: 三段信息（游戏健康忠告 / 备案 / 游戏备案） */
    .footer-beian {
      text-align: center;
      padding: 12px 20px 24px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 6px;
    }
    .footer-beian .footer-health-notice {
      font-size: 12px;
      color: rgba(189, 195, 199, 0.45);
      line-height: 1.6;
      max-width: 780px;
      padding: 0 12px;
    }
    .footer-beian .text-link-row {
      font-size: 12px;
      color: rgba(189, 195, 199, 0.45);
    }
    .footer-beian .text-link-row span {
      display: inline-flex;
      align-items: center;
      gap: 6px;
    }
    .footer-beian .text-link-row .icon {
      width: 14px;
      height: 14px;
      vertical-align: middle;
    }
    .footer-beian .text-link-row .link-item {
      color: rgba(189, 195, 199, 0.45);
      text-decoration: none;
      transition: color 0.2s;
    }
    .footer-beian .text-link-row .link-item:hover {
      color: rgba(189, 195, 199, 0.7);
    }
    .footer-beian .text-link-row .sep {
      color: rgba(189, 195, 199, 0.35);
      margin: 0 4px;
    }
    /* 兼容历史类名 (京公网安备样式), 若后续再启用仍可生效 */
    .footer-beian .beian_img {
      width: 16px;
      height: 16px;
      vertical-align: middle;
    }
    .footer-beian .beian_a {
      font-size: 12px;
      color: rgba(189, 195, 199, 0.45);
      text-decoration: none;
      transition: color 0.2s;
    }
    .footer-beian .beian_a:hover {
      color: rgba(189, 195, 199, 0.7);
    }

    /* ===== Main Content ===== */
    /* 2026-04-23: 主内容区加宽, 减少两侧留白
       - 默认 max-width 1440 (主流笔记本 1366/1440)
       - ≥ 1600 进一步放宽到 1600
       - ≥ 1920 放到 1760 (保留呼吸空间, 避免卡片行过长)
       - 左右 padding 从 20 调到 32, 平衡新的宽度 */
    .main-content {
      max-width: 1440px;
      margin: 0 auto;
      padding: 40px 32px 100px;
    }
    @media (min-width: 1600px) {
      .main-content { max-width: 1600px; }
    }
    @media (min-width: 1920px) {
      .main-content { max-width: 1760px; }
    }
    #main-content {
      display: flex;
      gap: 20px;
    }
    #game-content {
      display: flex;
      gap: 20px;
    }
    #game-content .main-left {
      flex: 3;
      min-width: 0;
    }
    .skill-list-container .main-content {
      display: flex;
      gap: 20px;
    }
    .skill-list-container .main-left {
      flex: 3;
      min-width: 0;
    }
    #main-content .main-left {
      flex: 3;
      min-width: 0;
    }

    /* ===== Ranking Sidebar (Glassmorphism) ===== */
    .ranking-sidebar {
      flex: 1;
      min-width: 220px;
      max-width: 300px;
      position: sticky;
      top: 60px;
      z-index: 50; /* prd4ai-011: 低于 navbar(100) 避免 Safari sticky 层叠重叠 */
      align-self: flex-start;
      max-height: calc(100vh - 80px);
      overflow-y: auto;
      background: rgba(20, 15, 40, 0.55);
      backdrop-filter: blur(24px) saturate(1.6);
      -webkit-backdrop-filter: blur(24px) saturate(1.6);
      border: 1px solid rgba(142, 68, 173, 0.25);
      border-radius: 18px;
      padding: 18px 16px;
      box-shadow:
        0 0 20px rgba(142, 68, 173, 0.15),
        0 0 60px rgba(52, 152, 219, 0.08),
        inset 0 1px 0 rgba(255,255,255,0.06);
      animation: sidebarGlow 4s ease-in-out infinite alternate;
    }
    @keyframes sidebarGlow {
      0% { box-shadow: 0 0 20px rgba(142, 68, 173, 0.15), 0 0 60px rgba(52, 152, 219, 0.08), inset 0 1px 0 rgba(255,255,255,0.06); }
      100% { box-shadow: 0 0 30px rgba(142, 68, 173, 0.25), 0 0 80px rgba(52, 152, 219, 0.15), inset 0 1px 0 rgba(255,255,255,0.08); }
    }
    .ranking-sidebar::-webkit-scrollbar { width: 4px; }
    .ranking-sidebar::-webkit-scrollbar-thumb { background: rgba(142,68,173,0.3); border-radius: 4px; }
    .ranking-sidebar-header {
      display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px;
    }
    .ranking-sidebar-title {
      font-size: 15px; font-weight: 800; color: #fff;
      background: linear-gradient(135deg, #f39c12, #e74c3c);
      -webkit-background-clip: text; -webkit-text-fill-color: transparent;
    }
    .ranking-sidebar-cats {
      display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px;
    }
    .ranking-sidebar-cat {
      padding: 4px 10px; border-radius: 12px; font-size: 11px; font-weight: 600;
      color: rgba(255,255,255,0.5); background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.08); cursor: pointer; transition: all 0.2s;
    }
    .ranking-sidebar-cat:hover { background: rgba(255,255,255,0.1); color: #fff; }
    .ranking-sidebar-cat.active {
      background: linear-gradient(135deg, rgba(142,68,173,0.4), rgba(52,152,219,0.3));
      color: #fff; border-color: rgba(142,68,173,0.5);
    }
    .ranking-sidebar-dims {
      display: flex; gap: 0; margin-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,0.06);
    }
    .ranking-sidebar-dim {
      padding: 6px 12px; font-size: 11px; font-weight: 600;
      color: rgba(255,255,255,0.4); cursor: pointer; border-bottom: 2px solid transparent; transition: all 0.2s;
    }
    .ranking-sidebar-dim:hover { color: #fff; }
    .ranking-sidebar-dim.active { color: #fff; border-bottom-color: var(--primary); }
    .ranking-sidebar-list { display: flex; flex-direction: column; gap: 2px; }
    .ranking-sidebar-item {
      display: flex; align-items: center; gap: 8px; padding: 8px 6px;
      border-radius: 10px; cursor: pointer; transition: background 0.15s;
    }
    .ranking-sidebar-item:hover { background: rgba(255,255,255,0.04); }
    .ranking-sidebar-rank {
      width: 24px; height: 24px; border-radius: 7px; display: flex;
      align-items: center; justify-content: center; font-size: 11px; font-weight: 800;
      flex-shrink: 0; background: rgba(255,255,255,0.06); color: var(--text-muted);
    }
    /* TOP 3 metallic badges with breathing glow */
    .ranking-sidebar-rank.top1 {
      background: linear-gradient(135deg, #f9d423, #f39c12, #e67e22);
      color: #fff; box-shadow: 0 0 8px rgba(243,156,18,0.4);
      animation: breatheGold 2.5s ease-in-out infinite alternate;
    }
    .ranking-sidebar-rank.top2 {
      background: linear-gradient(135deg, #dfe6e9, #b2bec3, #95a5a6);
      color: #2d3436; box-shadow: 0 0 8px rgba(149,165,166,0.3);
      animation: breatheSilver 2.5s ease-in-out infinite alternate;
    }
    .ranking-sidebar-rank.top3 {
      background: linear-gradient(135deg, #e67e22, #d35400, #a04000);
      color: #fff; box-shadow: 0 0 8px rgba(211,84,0,0.35);
      animation: breatheBronze 2.5s ease-in-out infinite alternate;
    }
    @keyframes breatheGold {
      0% { box-shadow: 0 0 6px rgba(243,156,18,0.3); }
      100% { box-shadow: 0 0 14px rgba(243,156,18,0.6); }
    }
    @keyframes breatheSilver {
      0% { box-shadow: 0 0 6px rgba(149,165,166,0.2); }
      100% { box-shadow: 0 0 12px rgba(149,165,166,0.45); }
    }
    @keyframes breatheBronze {
      0% { box-shadow: 0 0 6px rgba(211,84,0,0.25); }
      100% { box-shadow: 0 0 12px rgba(211,84,0,0.5); }
    }
    .ranking-sidebar-icon {
      width: 32px; height: 32px; border-radius: 8px; object-fit: cover;
      background: rgba(255,255,255,0.06); flex-shrink: 0;
    }
    .ranking-sidebar-info { flex: 1; min-width: 0; }
    .ranking-sidebar-name {
      font-size: 12px; font-weight: 600; color: #fff;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .ranking-sidebar-meta {
      font-size: 10px; color: var(--text-muted); margin-top: 1px;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .ranking-sidebar-empty {
      text-align: center; padding: 30px 0; color: var(--text-muted); font-size: 12px;
    }

    /* ===== prd4ai-011 R: 隐藏榜单高斯模糊遮罩 ===== */
    /* body.ranking-hidden 开启时, 3 处榜单侧栏(#rankingSidebar / #gameRankingSidebar / #skillRankingSidebar)
       + H5 榜单弹窗(#rankingOverlay > .ranking-modal) 都会被遮罩覆盖.
       规则:
         - header (.ranking-sidebar-header / .ranking-header) 保留清晰, 作为"标题依旧可见"的锚点
         - header 之外的所有子元素 (cats/dims/list) 都被 filter:blur + 降透明度
         - 再叠加 ::after 深色半透明盖板 + backdrop-filter blur 确保彻底不可辨认
         - 盖板上居中展示"数据筹备中…"
       2026-04-27 v2: 保留 header 漏出 + 同步覆盖 H5 榜单弹窗 */

    /* ---- PC: ranking-sidebar (3 处) ---- */
    body.ranking-hidden .ranking-sidebar {
      pointer-events: none;
    }
    /* 头部漏出 —— 保持可读, 重新开启指针 */
    body.ranking-hidden .ranking-sidebar .ranking-sidebar-header {
      filter: none;
      opacity: 1;
      position: relative;
      z-index: 11;            /* 高于 ::after 盖板 (z-index:10) */
      pointer-events: auto;
    }
    /* header 之后的所有兄弟节点 —— 模糊 + 降透明 */
    body.ranking-hidden .ranking-sidebar .ranking-sidebar-header ~ * {
      filter: blur(10px);
      opacity: 0.35;
      user-select: none;
    }
    body.ranking-hidden .ranking-sidebar::after {
      content: '数据筹备中…';
      position: absolute;
      /* 往下避让 header 高度 (约 42px, 含 margin-bottom) —— 留出头部不被遮盖 */
      top: 44px;
      left: 0; right: 0; bottom: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 16px;
      font-weight: 700;
      letter-spacing: 1px;
      color: #fff;
      text-shadow: 0 1px 3px rgba(0,0,0,0.5);
      background: rgba(18, 18, 28, 0.72);
      backdrop-filter: blur(28px) saturate(1.4);
      -webkit-backdrop-filter: blur(28px) saturate(1.4);
      border-radius: inherit;
      z-index: 10;
      pointer-events: auto;
    }

    /* ---- H5: #rankingOverlay 榜单弹窗 ---- */
    /* .ranking-modal 是 flex 布局, 含 .ranking-header + .ranking-cats + .ranking-dims + .ranking-list */
    body.ranking-hidden #rankingOverlay .ranking-modal {
      position: relative;  /* 让 ::after 相对 modal 定位 */
    }
    body.ranking-hidden #rankingOverlay .ranking-header {
      position: relative;
      z-index: 11;
    }
    body.ranking-hidden #rankingOverlay .ranking-cats,
    body.ranking-hidden #rankingOverlay .ranking-dims,
    body.ranking-hidden #rankingOverlay .ranking-list {
      filter: blur(10px);
      opacity: 0.35;
      pointer-events: none;
      user-select: none;
    }
    body.ranking-hidden #rankingOverlay .ranking-modal::after {
      content: '数据筹备中…';
      position: absolute;
      /* 避让 ranking-header (padding:20px 24px 12px + h2 ~24px ≈ 56px) */
      top: 60px;
      left: 0; right: 0; bottom: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 17px;
      font-weight: 700;
      letter-spacing: 1px;
      color: #fff;
      text-shadow: 0 1px 3px rgba(0,0,0,0.5);
      background: rgba(18, 18, 28, 0.72);
      backdrop-filter: blur(28px) saturate(1.4);
      -webkit-backdrop-filter: blur(28px) saturate(1.4);
      border-bottom-left-radius: 20px;
      border-bottom-right-radius: 20px;
      z-index: 10;
    }

    /* ===== Channel Flow Chart (REQ-005) ===== */
    .ch-flow-channel { margin-top: 10px; }
    .ch-flow-channel-label {
      font-size: 12px; font-weight: 700; color: #e74c3c; margin-bottom: 6px;
      display: flex; align-items: center; gap: 6px;
    }
    .ch-flow-channel-label .ch-icon {
      width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
      background: rgba(231,76,60,0.2); border: 2px solid rgba(231,76,60,0.4); color: #e74c3c; font-size: 10px; font-weight: 700;
    }
    .ch-flow-nodes {
      display: flex; align-items: stretch; gap: 0;
      overflow-x: auto; overflow-y: visible;
      padding: 6px 2px 10px;
      /* V6.0.2: 节点不再换行，超出容器横向滚动 */
      flex-wrap: nowrap;
      scrollbar-width: thin;
    }
    .ch-flow-nodes::-webkit-scrollbar { height: 6px; }
    .ch-flow-nodes::-webkit-scrollbar-thumb { background: rgba(52,152,219,0.4); border-radius: 3px; }
    /* FIX: 每一列节点组在容器高度内垂直居中。这样单节点列（如"渠道初审"）不会顶在最上方，
       对应到多节点列的连线会自然散开，按钮之间获得更宽松的垂直间距。 */
    .ch-flow-group {
      display: flex; flex-direction: column; align-items: stretch;
      justify-content: center;
      gap: 18px; flex-shrink: 0; padding: 2px 0;
    }
    .ch-flow-node {
      display: flex; flex-direction: column; align-items: stretch; min-width: 110px; position: relative;
      /* V6.0.2: 节点整体作为一张卡片，内部 box 与流转按钮视觉融合 */
    }
    .ch-flow-node-box {
      padding: 8px 14px; border-radius: 10px 10px 10px 10px;
      font-size: 11px; font-weight: 600;
      text-align: center; white-space: nowrap; transition: all 0.2s; min-width: 90px;
      position: relative;
    }
    .ch-flow-node-box.current {
      background: rgba(52,152,219,0.85); border: 2px solid #3498db; color: #fff; box-shadow: 0 0 10px rgba(52,152,219,0.4);
    }
    .ch-flow-node-box.passed {
      background: rgba(52,152,219,0.2); border: 2px solid rgba(52,152,219,0.4); color: #3498db;
    }
    .ch-flow-node-box.pending {
      background: transparent; border: 2px dashed rgba(255,255,255,0.15); color: var(--text-muted);
    }
    /* V6.0.2: 节点带流转按钮时，合并边框形成"卡片"观感 */
    .ch-flow-node.has-btn .ch-flow-node-box {
      border-radius: 10px 10px 0 0;
      border-bottom: none;
    }
    .ch-flow-node.has-btn .ch-flow-node-box.pending {
      border-color: rgba(46,204,113,0.5);
      background: rgba(46,204,113,0.06);
      color: #2ecc71;
    }
    /* PRD4AI-007 buglist #10/#11/#12: 改用 DOM 浮层 tooltip（fixed 定位 + 可交互），
       彻底解决：CSS attr() 渲染实体字符导致的乱码、被弹窗/卡片遮挡、以及链接无法点击的问题。 */
    .flow-node-with-tip { cursor: help; }
    .flow-tip-popover {
      position: fixed;
      background: rgba(15,12,41,0.96);
      color: #fff;
      padding: 8px 12px;
      border-radius: 8px;
      font-size: 12px;
      font-weight: 400;
      white-space: pre-wrap;
      word-break: break-word;
      min-width: 140px;
      max-width: 320px;
      line-height: 1.55;
      border: 1px solid rgba(255,255,255,0.18);
      box-shadow: 0 6px 18px rgba(0,0,0,0.55);
      z-index: 99999;
      pointer-events: auto;
    }
    .flow-tip-popover a {
      color: #5dade2;
      text-decoration: underline;
      word-break: break-all;
    }
    .flow-tip-popover a:hover { color: #85c1e9; }
    .flow-tip-popover::after {
      content: '';
      position: absolute;
      top: 100%;
      left: 50%;
      transform: translateX(-50%);
      border: 6px solid transparent;
      border-top-color: rgba(15,12,41,0.96);
    }
    .flow-tip-popover.flow-tip-below::after {
      top: auto;
      bottom: 100%;
      border-top-color: transparent;
      border-bottom-color: rgba(15,12,41,0.96);
    }
    .ch-flow-arrow {
      display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,0.25);
      font-size: 16px; padding: 0 4px; align-self: center;
    }
    /* V6.0.2: 组间 SVG 连线容器（N×M 连线） */
    .ch-flow-connectors {
      align-self: stretch;
      flex-shrink: 0;
      width: 96px;
      position: relative;
      pointer-events: none;
    }
    .ch-flow-connectors svg { width: 100%; height: 100%; display: block; overflow: visible; }
    .ch-flow-connectors path { fill: none; stroke: rgba(52,152,219,0.45); stroke-width: 1.5; }
    .ch-flow-connectors path.dim { stroke: rgba(255,255,255,0.12); }
    /* PRD4AI-007 buglist #14: 项目状态流转图的 SVG Bezier 连线复用 ch-flow 的视觉样式 */
    .proj-flow-svg-connector svg { overflow: visible; }
    .proj-flow-svg-connector path { fill: none; stroke: rgba(52,152,219,0.55); stroke-width: 1.8; }
    .proj-flow-svg-connector path.dim { stroke: rgba(255,255,255,0.18); }
    /* PRD4AI-007 R7: 流转按钮居中展示在连接线中点 */
    .ch-flow-line-btn {
      padding: 3px 10px;
      border-radius: 10px;
      border: 1px solid rgba(46,204,113,0.75);
      /* 不透明底，保证按钮清楚地盖在连线之上 */
      background: linear-gradient(180deg, #14321f, #1b5836);
      color: #5ee39a;
      font-size: 10px; font-weight: 700;
      cursor: pointer; white-space: nowrap;
      box-shadow: 0 2px 6px rgba(0,0,0,0.3);
      max-width: 60px;
      line-height: 1.25;
      z-index: 2;
      transition: background 0.12s ease, box-shadow 0.12s ease;
    }
    .ch-flow-line-btn:hover {
      background: linear-gradient(180deg, #1b5836, #2ecc71);
      color: #fff;
      box-shadow: 0 3px 10px rgba(46,204,113,0.4);
    }
    .ch-flow-transition-btn {
      /* V6.0.2: 按钮改为贴合节点底部的"延伸部分"，与目标状态强关联 */
      margin-top: 0; padding: 6px 10px;
      border-radius: 0 0 10px 10px;
      border: 2px solid rgba(46,204,113,0.55); border-top: 1px dashed rgba(46,204,113,0.45);
      background: linear-gradient(180deg, rgba(46,204,113,0.18), rgba(46,204,113,0.28));
      color: #2ecc71; font-size: 10px; font-weight: 700;
      cursor: pointer; transition: all 0.2s;
      display: flex; align-items: center; justify-content: center; gap: 4px;
      white-space: nowrap;
    }
    .ch-flow-transition-btn:hover {
      background: linear-gradient(180deg, rgba(46,204,113,0.3), rgba(46,204,113,0.45));
      transform: translateY(1px);
      box-shadow: 0 2px 8px rgba(46,204,113,0.25);
    }
    /* Transition confirm modal */
    .ch-transition-overlay {
      display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.7); backdrop-filter: blur(4px); z-index: 10000;
      align-items: center; justify-content: center; padding: 20px;
    }
    .ch-transition-overlay.show { display: flex; }
    .ch-transition-modal {
      background: var(--card-bg); border-radius: 16px; padding: 24px; max-width: 400px; width: 100%;
      border: 1px solid rgba(255,255,255,0.1);
    }
    .ch-transition-modal h3 {
      font-size: 16px; font-weight: 700; color: #fff; margin: 0 0 6px;
    }
    .ch-transition-modal .ch-trans-info {
      font-size: 12px; color: var(--text-muted); margin-bottom: 14px;
    }
    .ch-transition-modal textarea {
      width: 100%; min-height: 80px; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12);
      border-radius: 10px; padding: 10px; font-size: 13px; color: var(--text); resize: vertical;
      font-family: var(--font-body);
    }
    .ch-transition-modal textarea:focus { outline: none; border-color: var(--primary); }
    .ch-transition-modal .ch-trans-actions {
      display: flex; gap: 10px; justify-content: flex-end; margin-top: 14px;
    }
    .ch-transition-modal .ch-trans-cancel {
      padding: 8px 16px; border-radius: 10px; border: 1px solid rgba(255,255,255,0.15);
      background: transparent; color: var(--text-muted); cursor: pointer; font-size: 13px;
    }
    .ch-transition-modal .ch-trans-confirm {
      padding: 8px 20px; border-radius: 10px; border: none;
      background: var(--gradient-1); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
    }
    .ch-transition-modal .ch-trans-confirm:disabled { opacity: 0.4; cursor: not-allowed; }

    .module-section {
      margin-bottom: 60px;
    }

    .module-title {
      font-size: clamp(1.4rem, 3vw, 1.8rem);
      font-weight: 800;
      margin-bottom: 28px;
      display: flex;
      align-items: center;
      gap: 12px;
      flex-wrap: nowrap;
    }
    .module-title .title-toggle-spacer {
      flex: 1;
    }

    .module-title .dot {
      width: 10px; height: 10px;
      border-radius: 50%;
      display: inline-block;
    }
    .module-title .module-count {
      font-family: inherit;
      font-size: 0.65em;
      font-weight: 400;
      color: var(--text-muted);
      opacity: 0.7;
      margin-left: -4px;
      vertical-align: baseline;
    }

    .module-title[data-cat="life_health"] .dot { background: var(--accent); }
    .module-title[data-cat="cool_creative"] .dot { background: #00cec9; }
    .module-title[data-cat="casual_game"] .dot { background: #fd79a8; }
    .module-title[data-cat="work_efficiency"] .dot { background: var(--primary); }

    /* ── 模块排序切换按钮（module-title 右侧 icon） ── */
    .module-sort-btn {
      flex-shrink: 0;
      width: 32px;
      height: 32px;
      padding: 0;
      border-radius: 8px;
      border: 1px solid rgba(255,255,255,0.18);
      background: rgba(255,255,255,0.06);
      color: var(--text-muted);
      cursor: pointer;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      transition: all 0.15s;
    }
    .module-sort-btn:hover {
      background: rgba(255,255,255,0.12);
      color: #fff;
      border-color: rgba(255,255,255,0.28);
    }
    .module-sort-btn i { width: 16px; height: 16px; }

    /* 排序下拉菜单 */
    .project-order-menu {
      position: absolute;
      z-index: 9999;
      min-width: 140px;
      padding: 6px;
      border-radius: 10px;
      background: rgba(20,18,50,0.98);
      border: 1px solid rgba(255,255,255,0.12);
      box-shadow: 0 8px 24px rgba(0,0,0,0.5);
      display: none;
    }
    .project-order-menu.show { display: block; }
    .project-order-menu .order-item {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 8px 10px;
      border-radius: 6px;
      cursor: pointer;
      font-size: 13px;
      color: var(--text-muted);
      transition: background 0.12s;
    }
    .project-order-menu .order-item:hover { background: rgba(255,255,255,0.08); color: #fff; }
    .project-order-menu .order-item.active { background: var(--accent); color: #fff; }
    .project-order-menu .order-item i { width: 14px; height: 14px; }

    /* Cards Grid
       2026-04-23: 卡片模式统一 3 列布局 (桌面); 移动端 @media 下方会改成 1 列;
       list-mode 使用独立的 grid-template-columns 规则 (见下方 .cards-grid.list-mode) */
    .cards-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 24px;
    }
    @media (min-width: 1400px) {
      .cards-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 28px;
      }
    }
    @media (min-width: 1100px) and (max-width: 1399px) {
      .cards-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 24px;
      }
    }
    /* 1024-1099: 仍保持 3 列但稍缩小 gap, 避免极端宽度下卡片过宽 */
    @media (min-width: 900px) and (max-width: 1099px) {
      .cards-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 20px;
      }
    }
    /* 平板窄屏 (768-899): 降级为 2 列, 避免 3 列时每张卡片过窄 */
    @media (min-width: 769px) and (max-width: 899px) {
      .cards-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 18px;
      }
    }

    .card {
      background: #1a1a2e;
      border-radius: 16px;
      overflow: hidden;
      cursor: pointer;
      transition: transform 0.3s ease, box-shadow 0.3s ease;
      will-change: transform;
      position: relative;
      display: flex;
      flex-direction: column;
      padding: 16px;
      gap: 12px;
      box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 2px 8px rgba(0,0,0,0.3);
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      -webkit-touch-callout: none;
    }

    .card:hover {
      transform: translateY(-3px);
      box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 8px 24px rgba(0,0,0,0.4), 0 0 0 1px rgba(142,68,173,0.15);
      z-index: 2;
    }

    .card:active {
      opacity: 0.85;
      transition: opacity 0.1s;
    }

    /* New icon-based card head: icon left + title right */
    .card-head {
      display: flex;
      align-items: center;
      gap: 12px;
      min-width: 0;
    }
    .card-icon-wrap {
      width: 56px;
      height: 56px;
      flex-shrink: 0;
      border-radius: 14px;
      overflow: hidden;
      background: rgba(255,255,255,0.04);
      box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06);
      position: relative;
    }
    .card-icon {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }
    .card-text {
      flex: 1;
      min-width: 0;
      display: flex;
      flex-direction: column;
      gap: 4px;
    }

    /* 2026-04-23: 移除彩虹渐变与 titleColorShift 动画
       深色毛玻璃视觉下, 标题是卡片最强焦点, 纯白对比度最高, 阅读最舒适,
       符合 App Store / Figma Demo 的应用标题风格 */
    .card-title {
      font-size: 17px;
      font-weight: 800;
      margin-bottom: 0;
      min-width: 0;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      color: var(--ds-text-primary);
    }

    /* wrap 层隔离 flex 上下文，使 -webkit-line-clamp 在 .card-desc 上正常工作 */
    .card-desc-wrap {
      min-width: 0;
      overflow: hidden;
    }
    .card-desc {
      font-size: 13px;
      color: var(--text-muted);
      line-height: 1.6;
      /* PRD4AI-007 buglist #15: 卡片描述超出 2 行时自动省略展示 */
      display: -webkit-box;
      -webkit-line-clamp: 2;
      line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
      text-overflow: ellipsis;
      word-break: break-word;
      overflow-wrap: anywhere;
      max-height: calc(1.6em * 2);
      margin-bottom: 0;
    }

    .card-rating {
      font-size: 12px;
      color: #f1c40f;
      margin-top: 4px;
      font-weight: 600;
      line-height: 1;
    }
    .card-rating-none {
      color: var(--text-muted);
      font-weight: 400;
    }

    .card-footer {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      margin-top: 6px;
    }

    .card-like-btn {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      background: rgba(231,76,60,0.10);
      border: 1px solid transparent;
      color: #ff8a7a;
      font-size: 12px;
      padding: 4px 11px;
      border-radius: 14px;
      cursor: pointer;
      transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.15s;
      user-select: none;
    }
    .card-like-btn:hover {
      background: rgba(231,76,60,0.18);
      border-color: rgba(231,76,60,0.35);
      color: #ff6b5a;
      transform: translateY(-1px);
    }
    .card-like-btn.liked {
      background: rgba(231,76,60,0.85);
      border-color: rgba(231,76,60,0.9);
      color: #fff;
    }
    .card-like-btn .like-icon { font-size: 13px; }
    .card-like-btn .like-count { font-weight: 600; }

    .card-action-btns {
      display: inline-flex;
      align-items: center;
      gap: 8px;
    }

    .card-qr-btn,
    .card-share-btn {
      display: inline-flex;
      align-items: center;
      gap: 3px;
      background: rgba(255,255,255,0.06);
      border: 1px solid transparent;
      color: var(--text-muted);
      font-size: 12px;
      padding: 4px 9px;
      border-radius: 14px;
      cursor: pointer;
      transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.15s;
      user-select: none;
    }
    .card-qr-btn:hover {
      background: rgba(52,152,219,0.18);
      border-color: rgba(52,152,219,0.4);
      color: #5fb0e8;
      transform: translateY(-1px);
    }
    .card-share-btn:hover {
      background: rgba(46,204,113,0.18);
      border-color: rgba(46,204,113,0.4);
      color: #5fd18a;
      transform: translateY(-1px);
    }
    .card-qr-btn .qr-icon,
    .card-share-btn .share-icon {
      font-size: 13px;
    }
    .card-share-btn .share-text {
      font-size: 12px;
    }

    /* QR Code Modal */
    .qr-modal-overlay {
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.6);
      backdrop-filter: blur(6px);
      -webkit-backdrop-filter: blur(6px);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 10000;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.25s;
    }
    .qr-modal-overlay.show {
      opacity: 1;
      pointer-events: auto;
    }
    .qr-modal-box {
      background: #1a1a2e;
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 16px;
      padding: 28px;
      text-align: center;
      min-width: 280px;
      max-width: 340px;
      box-shadow: 0 20px 60px rgba(0,0,0,0.5);
      transform: scale(0.9);
      transition: transform 0.25s;
    }
    .qr-modal-overlay.show .qr-modal-box {
      transform: scale(1);
    }
    .qr-modal-title {
      font-size: 16px;
      font-weight: 600;
      color: var(--text);
      margin-bottom: 16px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .qr-modal-canvas-wrapper {
      display: inline-block;
      background: #fff;
      padding: 16px;
      border-radius: 12px;
      margin-bottom: 16px;
    }
    .qr-modal-canvas-wrapper canvas {
      display: block;
    }
    .qr-modal-url {
      font-size: 12px;
      color: var(--text-muted);
      word-break: break-all;
      margin-bottom: 16px;
      line-height: 1.4;
      max-height: 48px;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .qr-modal-close {
      background: var(--gradient-1);
      color: #fff;
      border: none;
      padding: 8px 28px;
      border-radius: 20px;
      cursor: pointer;
      font-size: 14px;
      transition: opacity 0.2s;
    }
    .qr-modal-close:hover {
      opacity: 0.85;
    }

    /* Admin Stats Panel */
    .admin-stats-btn {
      background: rgba(46,204,113,0.2);
      border: 1px solid rgba(46,204,113,0.4);
      color: #2ecc71;
      font-size: 12px;
      font-weight: 700;
      padding: 6px 14px;
      border-radius: 20px;
      cursor: pointer;
      display: none;
      transition: all 0.2s;
    }
    .admin-stats-btn:hover { background: rgba(46,204,113,0.35); }
    body.admin-mode .admin-stats-btn { display: inline-block; }

    .stats-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.7);
      backdrop-filter: blur(4px);
      z-index: 1100;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .stats-overlay.show { display: flex; }
    .stats-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 32px;
      max-width: 700px;
      width: 100%;
      max-height: 80vh;
      overflow-y: auto;
      animation: modalIn 0.3s ease;
    }
    .stats-box h3 { font-size: 20px; font-weight: 800; margin-bottom: 20px; text-align: center; }
    .stats-summary {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
      gap: 12px;
      margin-bottom: 24px;
    }
    .stats-card {
      background: rgba(255,255,255,0.05);
      border: 1px solid var(--card-border);
      border-radius: 12px;
      padding: 16px;
      text-align: center;
    }
    .stats-card .stats-value {
      font-size: 28px;
      font-weight: 800;
      background: var(--gradient-1);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
    }
    .stats-card .stats-label {
      font-size: 12px;
      color: var(--text-muted);
      margin-top: 4px;
    }
    .stats-table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 16px;
    }
    .stats-table th, .stats-table td {
      padding: 8px 12px;
      text-align: left;
      border-bottom: 1px solid var(--card-border);
      font-size: 13px;
    }
    .stats-table th {
      color: var(--text-muted);
      font-weight: 600;
      font-size: 12px;
    }
    .stats-section-title {
      font-size: 16px;
      font-weight: 700;
      margin: 20px 0 12px;
      color: var(--text);
    }

    /* ===== Kafka Log Viewer (Admin) ===== */
    .kafka-log-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.7);
      backdrop-filter: blur(4px);
      z-index: 1100;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .kafka-log-overlay.show { display: flex; }
    .kafka-log-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 32px;
      max-width: 960px;
      width: 100%;
      max-height: 85vh;
      overflow-y: auto;
      animation: modalIn 0.3s ease;
    }
    .kafka-log-box h3 {
      font-size: 20px;
      font-weight: 800;
      margin-bottom: 20px;
      text-align: center;
    }
    .kafka-filter-bar {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      margin-bottom: 16px;
      align-items: center;
    }
    .kafka-filter-bar select,
    .kafka-filter-bar input {
      padding: 8px 12px;
      background: rgba(255,255,255,0.05);
      border: 1px solid var(--card-border);
      border-radius: 8px;
      color: var(--text);
      font-size: 13px;
      outline: none;
      transition: border-color 0.2s;
    }
    .kafka-filter-bar select:focus,
    .kafka-filter-bar input:focus {
      border-color: var(--primary);
    }
    .kafka-filter-bar select { min-width: 110px; }
    .kafka-filter-bar input { min-width: 140px; flex: 1; max-width: 200px; }
    .kafka-filter-bar .kafka-btn-sm {
      padding: 8px 14px;
      border: 1px solid var(--card-border);
      border-radius: 8px;
      background: transparent;
      color: var(--text-muted);
      font-size: 13px;
      cursor: pointer;
      transition: all 0.2s;
      white-space: nowrap;
      display: inline-flex;
      align-items: center;
      gap: 4px;
    }
    .kafka-filter-bar .kafka-btn-sm:hover {
      border-color: var(--text-muted);
      color: var(--text);
    }
    .kafka-filter-bar .kafka-btn-sm.active {
      background: rgba(142, 68, 173, 0.25);
      border-color: var(--primary);
      color: #fff;
    }
    .kafka-log-table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 8px;
      table-layout: fixed;
    }
    .kafka-log-table th,
    .kafka-log-table td {
      padding: 8px 10px;
      text-align: left;
      border-bottom: 1px solid var(--card-border);
      font-size: 12px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .kafka-log-table th {
      color: var(--text-muted);
      font-weight: 600;
      font-size: 11px;
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }
    .kafka-log-table tbody tr {
      cursor: pointer;
      transition: background 0.15s;
    }
    .kafka-log-table tbody tr:hover {
      background: rgba(255,255,255,0.04);
    }
    .kafka-badge {
      display: inline-block;
      padding: 2px 8px;
      border-radius: 6px;
      font-size: 11px;
      font-weight: 600;
    }
    .kafka-badge.send { background: rgba(52, 152, 219, 0.2); color: #5dade2; }
    .kafka-badge.receive { background: rgba(46, 204, 113, 0.2); color: #58d68d; }
    .kafka-badge.info { background: rgba(52, 152, 219, 0.15); color: #85c1e9; }
    .kafka-badge.error { background: rgba(231, 76, 60, 0.2); color: #ec7063; }
    .kafka-badge.warn { background: rgba(243, 156, 18, 0.2); color: #f5b041; }
    .kafka-detail-row td {
      padding: 12px 16px !important;
      white-space: normal !important;
      background: rgba(255,255,255,0.02);
      border-bottom: 2px solid var(--card-border);
    }
    .kafka-detail-content {
      font-size: 12px;
      line-height: 1.6;
    }
    .kafka-detail-content .kafka-detail-grid {
      display: grid;
      grid-template-columns: 100px 1fr;
      gap: 4px 12px;
      margin-bottom: 10px;
    }
    .kafka-detail-content .kafka-detail-label {
      color: var(--text-muted);
      font-weight: 600;
    }
    .kafka-detail-content pre {
      background: rgba(0,0,0,0.3);
      border: 1px solid var(--card-border);
      border-radius: 8px;
      padding: 12px;
      overflow-x: auto;
      font-size: 11px;
      line-height: 1.5;
      color: #a9dfbf;
      max-height: 200px;
    }
    .kafka-status-bar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-size: 12px;
      color: var(--text-muted);
      margin-top: 12px;
      padding-top: 12px;
      border-top: 1px solid var(--card-border);
    }
    .kafka-log-table .col-id { width: 48px; }
    .kafka-log-table .col-time { width: 150px; }
    .kafka-log-table .col-dir { width: 68px; }
    .kafka-log-table .col-type { width: 60px; }
    .kafka-log-table .col-project { width: 120px; }
    .kafka-log-table .col-topic { width: 140px; }
    .kafka-log-table .col-detail { width: auto; }
    @media (max-width: 768px) {
      .kafka-log-box { padding: 20px 16px; }
      .kafka-filter-bar { flex-direction: column; }
      .kafka-filter-bar select,
      .kafka-filter-bar input { max-width: 100%; width: 100%; }
      .kafka-log-table .col-topic,
      .kafka-log-table .col-id { display: none; }
      .kafka-log-table th.col-topic,
      .kafka-log-table th.col-id { display: none; }
    }

    /* Empty state */
    .empty-state {
      text-align: center;
      padding: 48px 20px;
      color: var(--text-muted);
      font-size: 15px;
    }

    .empty-state a {
      color: var(--primary-light);
      cursor: pointer;
      text-decoration: underline;
    }

    /* Loading skeleton */
    .skeleton-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
      gap: 24px;
    }

    .skeleton-card {
      background: var(--card-bg);
      border: 1px solid var(--card-border);
      border-radius: 16px;
      overflow: hidden;
    }

    .skeleton-img {
      width: 100%; height: 180px;
      background: linear-gradient(90deg, #1e1e3a 25%, #2d2d5e 50%, #1e1e3a 75%);
      background-size: 200% 100%;
      animation: shimmer 1.5s infinite;
    }

    .skeleton-text {
      margin: 16px;
      height: 16px;
      border-radius: 4px;
      background: linear-gradient(90deg, #1e1e3a 25%, #2d2d5e 50%, #1e1e3a 75%);
      background-size: 200% 100%;
      animation: shimmer 1.5s infinite;
    }

    .skeleton-text.short { width: 60%; height: 12px; margin-top: 10px; }

    /* 2026-04-23 bugfix #3: list-mode 骨架, 对齐新版项目卡片(行布局: icon 左 + 文本右) */
    .skeleton-grid-list {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
      gap: 16px;
    }
    @media (min-width: 769px) {
      .skeleton-grid-list { grid-template-columns: repeat(3, 1fr); }
    }
    @media (min-width: 769px) and (max-width: 1023px) {
      .skeleton-grid-list { grid-template-columns: repeat(2, 1fr); }
    }
    @media (max-width: 768px) {
      .skeleton-grid-list { grid-template-columns: 1fr; gap: 10px; }
    }
    .skeleton-card-list {
      display: flex;
      flex-direction: row;
      align-items: center;
      gap: 10px;
      padding: 10px;
      background: var(--card-bg);
      border: 1px solid var(--card-border);
      border-radius: 16px;
    }
    .skeleton-img-icon {
      width: 64px;
      height: 64px;
      flex-shrink: 0;
      border-radius: 12px;
      margin: 0;
    }
    .skeleton-list-body {
      flex: 1;
      min-width: 0;
      display: flex;
      flex-direction: column;
      gap: 6px;
    }
    .skeleton-list-body .skeleton-text {
      margin: 0;
      height: 14px;
    }
    .skeleton-list-body .skeleton-text.short {
      margin-top: 0;
      height: 10px;
    }

    @keyframes shimmer {
      0% { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }

    /* Error state */
    .error-state {
      text-align: center;
      padding: 48px 20px;
      color: var(--accent);
    }

    .error-state button {
      margin-top: 12px;
      padding: 8px 24px;
      border: 1px solid var(--accent);
      background: transparent;
      color: var(--accent);
      border-radius: 8px;
      cursor: pointer;
      font-size: 14px;
    }

    /* ===== Upload Button ===== */
    .upload-section {
      position: fixed;
      bottom: 40px;
      left: 50%;
      transform: translateX(-50%);
      z-index: 900;
      text-align: center;
      padding: 0;
      pointer-events: none;
    }

    .upload-btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: auto;
      height: 56px;
      padding: 0 32px;
      border-radius: 28px;
      font-size: 16px;
      font-weight: 700;
      color: #fff;
      background: var(--gradient-1);
      border: none;
      cursor: pointer;
      transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
      box-shadow: 0 10px 25px rgba(142, 68, 173, 0.5);
      pointer-events: auto;
    }

    .upload-btn span { display: inline-block; }
    .upload-btn::after { content: none; }

    .upload-btn:hover {
      transform: scale(1.05);
      box-shadow: 0 15px 35px rgba(142, 68, 173, 0.7);
    }
    
    .upload-tooltip {
      position: absolute;
      top: -40px;
      left: 50%;
      transform: translateX(-50%) translateY(10px);
      background: rgba(0,0,0,0.8);
      color: #fff;
      padding: 6px 12px;
      border-radius: 6px;
      font-size: 14px;
      opacity: 0;
      pointer-events: none;
      transition: all 0.3s ease;
      white-space: nowrap;
    }

    .upload-section:hover .upload-tooltip {
      opacity: 1;
      transform: translateX(-50%) translateY(0);
    }

    /* ===== Modal ===== */
    .modal-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 1000;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }

    .modal-overlay.show {
      display: flex;
    }

    .modal {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      width: 100%;
      max-width: 520px;
      max-height: 90vh;
      overflow-y: auto;
      padding: 32px;
      position: relative;
      animation: modalIn 0.3s ease;
    }
    /* 2026-04-23: 项目上传/编辑弹窗加宽到 800, 表单字段多, 520 显得局促;
       Skill 上传/编辑弹窗保持 520 不变 */
    #uploadModal,
    #editModal {
      max-width: 800px;
    }

    @keyframes modalIn {
      from { opacity: 0; transform: translateY(30px) scale(0.96); }
      to { opacity: 1; transform: translateY(0) scale(1); }
    }

    .modal-title {
      font-size: 22px;
      font-weight: 800;
      margin-bottom: 24px;
      text-align: center;
    }

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

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

    .form-label .required {
      color: var(--accent);
      margin-left: 2px;
    }

    .form-input, .form-textarea {
      width: 100%;
      padding: 12px 16px;
      background: rgba(255,255,255,0.05);
      border: 1px solid var(--card-border);
      border-radius: 10px;
      color: var(--text);
      font-size: 14px;
      outline: none;
      transition: border-color 0.2s;
      font-family: inherit;
    }

    .form-input:focus, .form-textarea:focus {
      border-color: var(--primary);
    }

    .form-textarea {
      resize: vertical;
      min-height: 80px;
    }

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

    .form-error {
      font-size: 12px;
      color: var(--accent);
      margin-top: 4px;
      display: none;
    }

    .form-error.show { display: block; }

    /* Category selector */
    .category-options {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
    }

    .category-option {
      padding: 8px 20px;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      cursor: pointer;
      font-size: 13px;
      transition: all 0.2s;
      color: var(--text-muted);
    }

    .category-option:hover {
      border-color: var(--primary);
      color: var(--text);
    }

    .category-option.selected {
      background: var(--gradient-1);
      border-color: transparent;
      color: #fff;
      font-weight: 600;
    }

    /* Image upload area */
    .upload-area {
      border: 2px dashed var(--card-border);
      border-radius: 12px;
      padding: 32px;
      text-align: center;
      cursor: pointer;
      transition: all 0.2s;
      color: var(--text-muted);
      font-size: 14px;
      position: relative;
    }

    .upload-area:hover {
      border-color: var(--primary);
      background: rgba(108, 92, 231, 0.05);
    }

    .upload-area.has-image {
      padding: 8px;
    }

    .upload-area .upload-icon {
      font-size: 36px;
      margin-bottom: 8px;
    }

    .upload-preview {
      width: 100%;
      max-height: 200px;
      object-fit: contain;
      border-radius: 8px;
      display: none;
    }

    .upload-area.has-image .upload-preview { display: block; }
    .upload-area.has-image .upload-placeholder { display: none; }

    .remove-image {
      position: absolute;
      top: 8px; right: 8px;
      width: 28px; height: 28px;
      background: rgba(253, 121, 168, 0.9);
      border: none;
      border-radius: 50%;
      color: #fff;
      font-size: 16px;
      cursor: pointer;
      display: none;
      align-items: center;
      justify-content: center;
      line-height: 1;
    }

    .upload-area.has-image .remove-image { display: flex; }

    .upload-loading {
      display: none;
      color: var(--primary-light);
      font-size: 14px;
    }

    /* Modal buttons */
    .modal-buttons {
      display: flex;
      gap: 12px;
      margin-top: 28px;
    }

    .btn-cancel {
      flex: 1;
      padding: 14px;
      background: transparent;
      border: 1px solid var(--card-border);
      color: var(--text-muted);
      border-radius: 12px;
      font-size: 15px;
      cursor: pointer;
      transition: all 0.2s;
      font-weight: 600;
    }

    .btn-cancel:hover { border-color: var(--text-muted); color: var(--text); }

    .btn-submit {
      flex: 1.5;
      padding: 14px;
      background: var(--gradient-1);
      border: none;
      color: #fff;
      border-radius: 12px;
      font-size: 15px;
      cursor: pointer;
      font-weight: 700;
      transition: all 0.2s;
      position: relative;
    }

    .btn-submit:hover { box-shadow: 0 4px 20px rgba(108, 92, 231, 0.5); }
    .btn-submit:disabled { opacity: 0.6; cursor: not-allowed; }

    .btn-submit .spinner {
      display: none;
      width: 18px; height: 18px;
      margin-right: 8px;
      vertical-align: middle;
      animation: spin 1s linear infinite;
    }

    .btn-submit.loading .spinner { display: inline-block; }
    .btn-submit.loading .btn-text { opacity: 0.7; }

    /* ===== 统一按钮图标样式 ===== */
    button svg[data-lucide] {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      vertical-align: middle;
    }

    /* 小尺寸按钮图标 (16px) */
    .my-projects-btn svg[data-lucide],
    .header-login-btn svg[data-lucide],
    .cms-tab svg[data-lucide] {
      width: 16px;
      height: 16px;
      margin-right: 6px;
    }

    /* 中尺寸按钮图标 (18px)
       注: .notif-bell-btn 无文字只有图标, 不能共用 margin-right:6px
       (否则 svg 被右推 6px, 在圆形按钮里看起来偏左), 单独处理 */
    .admin-stats-btn svg[data-lucide],
    .admin-batch-btn svg[data-lucide],
    .admin-export-btn svg[data-lucide],
    .admin-account-btn svg[data-lucide],
    .admin-cms-btn svg[data-lucide] {
      width: 18px;
      height: 18px;
      margin-right: 6px;
    }
    /* 2026-04-23: 铃铛图标仅自身, 居中对齐不做偏移 */
    .notif-bell-btn svg[data-lucide] {
      width: 18px;
      height: 18px;
      margin: 0;
    }

    /* 大尺寸按钮图标 (20px) */
    /* PRD4AI-007 buglist #4: comment-img-btn 作为独立图标按钮，内部 svg 需要居中对齐（去掉右侧留白 margin） */
    .comment-img-btn svg[data-lucide] {
      width: 20px;
      height: 20px;
      margin: 0;
    }

    /* ===== 状态标签图标样式 ===== */
    .channel-status-badge svg[data-lucide] {
      width: 12px;
      height: 12px;
      margin-right: 4px;
      vertical-align: middle;
    }

    #projDetailAppStatusLabel svg[data-lucide] {
      width: 14px;
      height: 14px;
      margin-right: 6px;
      vertical-align: middle;
    }

    /* ===== 加载中图标样式 ===== */
    .spinner[data-lucide="loader-2"] {
      animation: spin 1s linear infinite;
    }

    /* ===== Toast图标样式 ===== */
    .toast svg[data-lucide] {
      width: 16px;
      height: 16px;
      margin-right: 8px;
      vertical-align: middle;
    }

    @keyframes spin { to { transform: rotate(360deg); } }

    /* Toast */
    .toast {
      position: fixed;
      top: 20px;
      left: 50%;
      transform: translateX(-50%) translateY(-100px);
      padding: 12px 28px;
      border-radius: 10px;
      font-size: 14px;
      font-weight: 600;
      z-index: 9999;
      transition: transform 0.3s ease;
      pointer-events: none;
    }

    .toast.show { transform: translateX(-50%) translateY(0); }
    .toast.success { background: #00b894; color: #fff; }
    .toast.error { background: var(--accent); color: #fff; }
    .toast.info { background: var(--primary); color: #fff; }

    /* Confirm dialog */
    .confirm-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.5);
      z-index: 1100;
      align-items: center;
      justify-content: center;
    }
    .confirm-overlay.show { display: flex; }
    .confirm-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 16px;
      padding: 28px;
      text-align: center;
      max-width: 360px;
      width: 90%;
    }
    .confirm-box p { margin-bottom: 20px; font-size: 15px; }
    .confirm-buttons { display: flex; gap: 12px; }
    .confirm-buttons button {
      flex: 1;
      padding: 10px;
      border-radius: 10px;
      font-size: 14px;
      cursor: pointer;
      font-weight: 600;
      border: none;
    }
    .confirm-buttons .btn-stay {
      background: var(--gradient-1);
      color: #fff;
    }
    .confirm-buttons .btn-leave {
      background: transparent;
      border: 1px solid var(--card-border);
      color: var(--text-muted);
    }

    /* ===== User Auth ===== */
    .user-toolbar {
      position: fixed;
      top: 12px;
      right: 12px;
      z-index: 1100;
      display: flex;
      align-items: center;
      gap: 8px;
    }
    .user-logout-btn {
      background: rgba(255,255,255,0.1);
      border: 1px solid var(--card-border);
      color: var(--text-muted);
      font-size: 12px;
      padding: 6px 14px;
      height: 36px;
      line-height: 22px;
      border-radius: 20px;
      cursor: pointer;
      display: none;
      transition: all 0.2s;
      /* 2026-04-24: 对齐 icon 和文本 */
      align-items: center;
      gap: 6px;
    }
    .user-logout-btn:hover { background: rgba(255,255,255,0.15); color: var(--text); }
    .user-logout-btn.show { display: inline-flex; }
    .user-logout-btn svg[data-lucide] { width: 14px; height: 14px; }

    .user-badge {
      color: var(--text-muted);
      font-size: 12px;
      padding: 6px 14px;
      height: 36px;
      line-height: 22px;
      border-radius: 20px;
      display: none;
      background: rgba(46,204,113,0.15);
      border: 1px solid rgba(46,204,113,0.3);
      cursor: pointer;
    }
    .user-badge:hover { background: rgba(46,204,113,0.25); color: var(--text); }
    .user-badge.show { display: inline-block; }

    /* ===== REQ-004: Notification Bell ===== */
    .notif-bell-btn {
      position: relative;
      width: 36px; height: 36px;
      border-radius: 50%;
      border: 1px solid rgba(255,255,255,0.12);
      background: rgba(255,255,255,0.07);
      color: var(--text-muted);
      font-size: 16px;
      cursor: pointer;
      display: none;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
    }
    .notif-bell-btn.show { display: flex; }
    .notif-bell-btn:hover { background: rgba(255,255,255,0.13); color: var(--text); }

    /* prd4ai-009: 顶栏搜索按钮（取代原 hero 搜索栏） */
    .top-search-btn {
      position: relative;
      width: 36px; height: 36px;
      border-radius: 50%;
      border: 1px solid rgba(255,255,255,0.12);
      background: rgba(255,255,255,0.07);
      color: var(--text-muted);
      font-size: 16px;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
    }
    .top-search-btn:hover { background: rgba(255,255,255,0.13); color: var(--text); }
    .top-search-btn svg[data-lucide] { width: 18px; height: 18px; }

    /* 2026-04-24: 移动端榜单入口 — 嵌入 hero 内部, 绝对定位在 primary-tabs 下方,
       与 primary-tabs 同一图层叠在 canvas (z-index:1) 之上。
       样式弱化为 icon+文字的文本按钮, 与主站色调 (muted white) 协调。
       PC 模式 (ranking-sidebar 可见) 时隐藏, 避免双入口。
       2026-05-11: 强化展示强度, 增加边框(浅白)和奖杯角标(金色) */
    .mobile-ranking-entry {
      display: none;
    }
    @media (max-width: 768px) {
      .mobile-ranking-entry {
        position: absolute;
        bottom: 16px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 10;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        padding: 5px 14px;
        border: 1px solid rgba(255, 255, 255, 0.12);
        border-radius: 20px;
        background: rgba(255, 255, 255, 0.07);
        color: rgba(255, 255, 255, 0.75);
        font-size: 12px;
        font-weight: 500;
        letter-spacing: 0.3px;
        cursor: pointer;
        white-space: nowrap;
        transition: all 0.2s ease;
        backdrop-filter: blur(8px);
        -webkit-backdrop-filter: blur(8px);
      }
      .mobile-ranking-entry:hover,
      .mobile-ranking-entry:active {
        background: rgba(255, 255, 255, 0.13);
        border-color: rgba(255, 255, 255, 0.25);
        color: rgba(255, 255, 255, 0.95);
        transform: translateX(-50%) translateY(-1px);
      }
      .mobile-ranking-entry svg[data-lucide] {
        width: 14px;
        height: 14px;
        stroke: currentColor;
      }
      /* 2026-05-11: 奖杯角标金色样式 */
      .mobile-ranking-entry .trophy-icon {
        color: #ffd700;
        font-size: 14px;
      }
    }

    /* 部署工具按钮 */
    .deploy-tool-btn {
      background: rgba(52, 152, 219, 0.15);
      border: 1px solid rgba(52, 152, 219, 0.3);
      color: var(--text-muted);
      font-size: 12px;
      padding: 6px 14px;
      height: 36px;
      line-height: 22px;
      border-radius: 20px;
      cursor: pointer;
      display: inline-flex;
      align-items: center;
      gap: 4px;
      transition: all 0.2s;
      white-space: nowrap;
    }
    .deploy-tool-btn:hover { background: rgba(52, 152, 219, 0.25); color: var(--text); }
    .deploy-tool-btn svg[data-lucide] { width: 14px; height: 14px; }

    .notif-badge {
      position: absolute;
      top: -4px; right: -4px;
      background: #e74c3c;
      color: #fff;
      font-size: 10px;
      font-weight: 700;
      border-radius: 10px;
      padding: 1px 5px;
      min-width: 16px;
      text-align: center;
      line-height: 14px;
      display: none;
    }
    .notif-badge.show { display: block; }

    /* Notification slide panel */
    .notif-panel {
      position: fixed;
      top: 0;
      right: -360px;
      width: 360px;
      height: 100vh;
      background: #1a1a35;
      border-left: 1px solid rgba(255,255,255,0.12);
      box-shadow: -8px 0 32px rgba(0,0,0,0.5);
      z-index: 1100;
      display: flex;
      flex-direction: column;
      transition: right 0.3s ease;
    }
    .notif-panel.show {
      right: 0;
    }
    .notif-panel-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      background: rgba(0,0,0,0.5);
      z-index: 1099;
      display: none;
    }
    .notif-panel-overlay.show {
      display: block;
    }
    .notif-panel-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 20px 16px 16px;
      border-bottom: 1px solid rgba(255,255,255,0.07);
      flex-shrink: 0;
      background: rgba(0,0,0,0.1);
    }
    .notif-panel-title {
      font-size: 14px;
      font-weight: 700;
      color: var(--text);
    }
    /* 2026-04-24 buglist #34: 返回按钮 + 标题 左侧分组, PC 端隐藏按钮 */
    .notif-panel-title-group {
      display: flex;
      align-items: center;
      gap: 8px;
      min-width: 0;
    }
    .notif-back-btn {
      display: none;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      padding: 0;
      border: none;
      background: rgba(255,255,255,0.06);
      color: var(--text);
      border-radius: 8px;
      cursor: pointer;
      transition: background 0.2s;
    }
    .notif-back-btn:hover { background: rgba(255,255,255,0.12); }
    .notif-back-btn svg[data-lucide] { width: 16px; height: 16px; }
    .notif-read-all-btn {
      font-size: 12px;
      color: var(--primary);
      background: none;
      border: none;
      cursor: pointer;
      padding: 2px 6px;
      border-radius: 6px;
      transition: background 0.2s;
    }
    .notif-read-all-btn:hover { background: rgba(142,68,173,0.15); }
    .notif-list {
      flex: 1;
      overflow-y: auto;
      padding: 8px 0;
      max-height: calc(100vh - 120px);
    }
    .notif-list::-webkit-scrollbar { width: 4px; }
    .notif-list::-webkit-scrollbar-track { background: transparent; }
    .notif-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 2px; }
    .notif-item {
      display: flex;
      gap: 10px;
      align-items: flex-start;
      padding: 10px 16px;
      cursor: pointer;
      transition: background 0.15s;
      border-left: 3px solid transparent;
      position: relative;
    }
    .notif-item:hover { background: rgba(255,255,255,0.04); }
    .notif-item.unread {
      background: rgba(142,68,173,0.07);
      border-left-color: var(--primary);
    }
    .notif-item.unread:hover { background: rgba(142,68,173,0.12); }
    .notif-icon {
      font-size: 18px;
      flex-shrink: 0;
      margin-top: 2px;
    }
    .notif-body { flex: 1; min-width: 0; }
    .notif-text {
      font-size: 13px;
      color: var(--text);
      line-height: 1.5;
      display: -webkit-box;
      -webkit-line-clamp: 5;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
    .notif-time {
      font-size: 11px;
      color: rgba(255,255,255,0.3);
      margin-top: 3px;
    }
    .notif-empty {
      text-align: center;
      padding: 40px 20px;
      color: rgba(255,255,255,0.25);
    }
    .notif-empty-icon { font-size: 36px; margin-bottom: 10px; }
    .notif-empty-text { font-size: 13px; }

    /* ===== REQ-006: Notification Tabs ===== */
    .notif-tabs {
      display: flex;
      border-bottom: 1px solid rgba(255,255,255,0.1);
      padding: 0 12px;
      gap: 0;
      background: rgba(0,0,0,0.1);
    }
    .notif-tab {
      position: relative;
      flex: 1;
      padding: 10px 4px 8px;
      text-align: center;
      font-size: 13px;
      color: var(--text-muted);
      cursor: pointer;
      border-bottom: 2px solid transparent;
      transition: all 0.2s;
      background: none;
      border-top: none; border-left: none; border-right: none;
      font-family: inherit;
    }
    .notif-tab:hover { color: var(--text); background: rgba(255,255,255,0.03); }
    .notif-tab.active {
      color: var(--accent);
      border-bottom-color: var(--accent);
      font-weight: 600;
    }
    .notif-tab-badge {
      position: absolute;
      top: 4px;
      right: 2px;
      background: #e74c3c;
      color: #fff;
      font-size: 9px;
      font-weight: 700;
      border-radius: 8px;
      padding: 1px 4px;
      min-width: 14px;
      text-align: center;
      line-height: 12px;
      display: none;
    }
    .notif-tab-badge.show { display: block; }
    .notif-tab-content { display: none; flex-direction: column; flex: 1; min-height: 0; }
    .notif-tab-content.active { display: flex; }
    .notif-report-card {
      margin: 6px 0 4px;
      padding: 8px 12px;
      background: rgba(142,68,173,0.08);
      border: 1px solid rgba(142,68,173,0.2);
      border-radius: 8px;
      font-size: 12px;
      color: var(--text-muted);
      line-height: 1.5;
    }
    .notif-report-toggle {
      cursor: pointer;
      color: var(--accent);
      font-size: 11px;
      margin-top: 4px;
      display: inline-block;
    }
    .notif-report-toggle:hover { text-decoration: underline; }
    .notif-report-body { display: none; margin-top: 6px; white-space: pre-wrap; }
    .notif-report-body a { color: var(--primary); text-decoration: underline; }
    .notif-report-body.show { display: block; }
    /* 2026-04-24 buglist #20: 通知中心测试报告文字链优化为白色 + 图标, 替代原默认浅紫色效果不佳 */
    .notif-report-link {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      color: #fff;
      font-size: 12px;
      font-weight: 600;
      text-decoration: underline;
      text-underline-offset: 2px;
      padding: 2px 4px;
      border-radius: 4px;
      transition: opacity 0.15s;
    }
    .notif-report-link:hover { opacity: 0.78; color: #fff; }
    .notif-report-link::before {
      content: '';
      width: 14px;
      height: 14px;
      flex-shrink: 0;
      background: currentColor;
      mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/><path d='M15 3h6v6'/><path d='M10 14 21 3'/></svg>") center / contain no-repeat;
      -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/><path d='M15 3h6v6'/><path d='M10 14 21 3'/></svg>") center / contain no-repeat;
    }

    /* ===== REQ-006: Role Management in Account List ===== */
    .account-item { flex-wrap: wrap; gap: 8px; }
    .account-info { flex: 1; min-width: 0; }
    .account-role-row {
      display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap;
    }
    .role-select {
      background: rgba(255,255,255,0.07);
      border: 1px solid rgba(255,255,255,0.15);
      color: var(--text);
      border-radius: 6px;
      padding: 4px 8px;
      font-size: 12px;
      cursor: pointer;
    }
    .role-select:focus { outline: none; border-color: var(--primary); }
    .channel-bind-select {
      background: rgba(255,255,255,0.07);
      border: 1px solid rgba(255,255,255,0.15);
      color: var(--text);
      border-radius: 6px;
      padding: 4px 8px;
      font-size: 12px;
      cursor: pointer;
      display: none;
    }
    .channel-bind-select.show { display: inline-block; }
    .role-save-btn {
      background: rgba(46,204,113,0.2);
      border: 1px solid rgba(46,204,113,0.4);
      color: #2ecc71;
      padding: 4px 12px;
      border-radius: 6px;
      font-size: 12px;
      cursor: pointer;
      font-weight: 600;
    }
    .role-save-btn:hover { background: rgba(46,204,113,0.35); }
    .role-badge {
      display: inline-block;
      padding: 2px 8px;
      border-radius: 10px;
      font-size: 11px;
      font-weight: 600;
    }
    .role-badge.user { background: rgba(189,195,199,0.15); color: #bdc3c7; }
    .role-badge.operator { background: rgba(52,152,219,0.2); color: #3498db; }
    .role-badge.tester { background: rgba(241,196,15,0.2); color: #f1c40f; }
    .role-badge.channel_operator { background: rgba(155,89,182,0.2); color: #9b59b6; }


    /* User login overlay */
    .user-login-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 2000;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .user-login-overlay.show { display: flex; }

    .user-login-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 32px;
      max-width: 380px;
      width: 100%;
      text-align: center;
      animation: modalIn 0.3s ease;
    }
    .user-login-box h3 { font-size: 20px; font-weight: 800; margin-bottom: 8px; }
    .user-login-box .login-hint { font-size: 13px; color: var(--text-muted); margin-bottom: 24px; }
    .user-login-box .form-input { margin-bottom: 12px; }
    .user-login-box .login-error { font-size: 12px; color: #e74c3c; margin-bottom: 12px; min-height: 18px; }
    .user-login-box .login-buttons { display: flex; gap: 12px; margin-top: 8px; }

    /* Change password overlay */
    /* 注意：z-index 必须高于 .channel-page (2000)，否则在渠道分发页内打开时会被遮挡 */
    .change-pwd-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 2100;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .change-pwd-overlay.show { display: flex; }
    .change-pwd-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 32px;
      max-width: 380px;
      width: 100%;
      text-align: center;
      animation: modalIn 0.3s ease;
    }
    .change-pwd-box h3 { font-size: 20px; font-weight: 800; margin-bottom: 8px; }
    .change-pwd-box .pwd-hint { font-size: 13px; color: #f39c12; margin-bottom: 20px; }
    .change-pwd-box .form-input { margin-bottom: 12px; }
    .change-pwd-box .pwd-error { font-size: 12px; color: #e74c3c; margin-bottom: 12px; min-height: 18px; }

    /* Account management overlay */
    .account-mgmt-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 1100;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .account-mgmt-overlay.show { display: flex; }
    .account-mgmt-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 32px;
      max-width: 500px;
      width: 100%;
      max-height: 80vh;
      overflow-y: auto;
      animation: modalIn 0.3s ease;
    }
    .account-mgmt-box h3 { font-size: 20px; font-weight: 800; margin-bottom: 20px; text-align: center; }
    .account-add-row {
      display: flex;
      gap: 8px;
      margin-bottom: 20px;
    }
    .account-add-row .form-input { flex: 1; margin-bottom: 0; }
    .account-add-btn {
      padding: 10px 20px;
      background: var(--gradient-1);
      border: none;
      color: #fff;
      border-radius: 10px;
      font-size: 14px;
      cursor: pointer;
      font-weight: 600;
      white-space: nowrap;
    }
    .account-list { list-style: none; }
    .account-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 12px 16px;
      background: rgba(255,255,255,0.03);
      border: 1px solid var(--card-border);
      border-radius: 10px;
      margin-bottom: 8px;
    }
    .account-item .account-name { font-size: 14px; font-weight: 600; }
    .account-item .account-date { font-size: 12px; color: var(--text-muted); }
    .account-delete-btn {
      background: rgba(231, 76, 60, 0.8);
      border: none;
      color: #fff;
      padding: 6px 14px;
      border-radius: 8px;
      font-size: 12px;
      cursor: pointer;
      font-weight: 600;
    }
    .account-delete-btn:hover { background: rgba(231, 76, 60, 1); }
    .account-empty { text-align: center; color: var(--text-muted); font-size: 14px; padding: 20px; }

    .account-batch-btn {
      padding: 10px 20px;
      background: rgba(46, 204, 113, 0.15);
      border: 1px solid rgba(46, 204, 113, 0.4);
      color: #2ecc71;
      border-radius: 10px;
      font-size: 14px;
      cursor: pointer;
      font-weight: 600;
      transition: all 0.2s;
    }
    .account-batch-btn:hover { background: rgba(46, 204, 113, 0.3); }

    .admin-account-btn {
      background: rgba(52,152,219,0.2);
      border: 1px solid rgba(52,152,219,0.4);
      color: #3498db;
      font-size: 12px;
      font-weight: 700;
      padding: 6px 14px;
      border-radius: 20px;
      cursor: pointer;
      display: none;
      transition: all 0.2s;
    }
    .admin-account-btn:hover { background: rgba(52,152,219,0.35); }
    body.admin-mode .admin-account-btn { display: inline-block; }

    .admin-batch-btn {
      background: rgba(230, 126, 34, 0.2);
      color: #e67e22;
      border: 1px solid rgba(230, 126, 34, 0.4);
      border-radius: 20px;
      padding: 6px 14px;
      font-size: 12px;
      font-weight: 700;
      cursor: pointer;
      display: none;
      transition: all 0.2s;
    }
    .admin-batch-btn:hover { background: rgba(230, 126, 34, 0.35); }
    body.admin-mode .admin-batch-btn { display: inline-block; }

    .admin-export-btn {
      background: rgba(155, 89, 182, 0.2);
      border: 1px solid rgba(155, 89, 182, 0.4);
      color: #9b59b6;
      font-size: 12px;
      font-weight: 700;
      padding: 6px 14px;
      border-radius: 20px;
      cursor: pointer;
      display: none;
      transition: all 0.2s;
    }
    .admin-export-btn:hover { background: rgba(155, 89, 182, 0.35); }
    body.admin-mode .admin-export-btn { display: inline-block; }

    /* Admin mode: project ID now shown in detail modal instead of cards */

    /* Batch modify modal */
    .batch-modify-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.7);
      z-index: 10000;
      justify-content: center;
      align-items: center;
      backdrop-filter: blur(4px);
    }
    .batch-modify-overlay.show { display: flex; }
    .batch-modify-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 16px;
      padding: 28px;
      width: 90%;
      max-width: 700px;
      max-height: 85vh;
      overflow-y: auto;
    }
    .batch-modify-box h3 { font-size: 18px; margin-bottom: 16px; }
    .batch-upload-zone {
      border: 2px dashed rgba(142, 68, 173, 0.4);
      border-radius: 12px;
      padding: 30px 20px;
      text-align: center;
      cursor: pointer;
      transition: all 0.2s;
      margin-bottom: 16px;
    }
    .batch-upload-zone:hover { border-color: rgba(142, 68, 173, 0.7); background: rgba(142, 68, 173, 0.05); }
    .batch-upload-zone.has-file { border-color: #2ecc71; background: rgba(46, 204, 113, 0.05); }
    .batch-preview-table {
      width: 100%;
      border-collapse: collapse;
      font-size: 12px;
      margin-bottom: 16px;
    }
    .batch-preview-table th {
      background: rgba(142, 68, 173, 0.2);
      padding: 8px 6px;
      text-align: left;
      border-bottom: 1px solid var(--card-border);
      white-space: nowrap;
    }
    .batch-preview-table td {
      padding: 6px;
      border-bottom: 1px solid rgba(255,255,255,0.05);
      max-width: 150px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .batch-preview-table tr:hover td { background: rgba(255,255,255,0.03); }

    /* ===== Admin Mode ===== */
    .admin-trigger {
      position: fixed;
      top: 12px;
      left: 12px;
      width: 40px;
      height: 40px;
      z-index: 999;
      cursor: pointer;
      background: transparent;
      border: none;
      opacity: 0;
    }

    .admin-badge {
      background: linear-gradient(135deg, #e74c3c, #fd79a8);
      color: #fff;
      font-size: 12px;
      font-weight: 700;
      padding: 6px 14px;
      border-radius: 20px;
      display: none;
      animation: fadeInUp 0.3s ease;
    }

    .admin-badge.show { display: inline-block; }

    .admin-logout-btn {
      background: rgba(255,255,255,0.1);
      border: 1px solid var(--card-border);
      color: var(--text-muted);
      font-size: 12px;
      padding: 6px 14px;
      border-radius: 20px;
      cursor: pointer;
      display: none;
      transition: all 0.2s;
    }

    .admin-logout-btn:hover { background: rgba(255,255,255,0.15); color: var(--text); }
    .admin-logout-btn.show { display: inline-block; }

    /* Admin top-left toolbar container - hidden, replaced by side nav */
    .admin-toolbar {
      display: none !important;
    }

    /* ===== Admin Side Nav (REQ-005) ===== */
    .admin-sidenav {
      position: fixed;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
      width: 56px;
      z-index: 999;
      display: none;
      flex-direction: column;
      align-items: center;
      gap: 2px;
      padding: 12px 0;
      background: rgba(15, 12, 41, 0.85);
      backdrop-filter: blur(16px) saturate(1.5);
      -webkit-backdrop-filter: blur(16px) saturate(1.5);
      border-right: 1px solid rgba(255,255,255,0.1);
      border-radius: 0 16px 16px 0;
      box-shadow: 4px 0 24px rgba(0,0,0,0.4);
    }
    body.admin-mode .admin-sidenav { display: flex; }
    /* 运营角色（Operator）也显示左侧工具栏和导出按钮，但隐藏管理员专属项 */
    body.operator-mode .admin-sidenav { display: flex; }
    body.operator-mode .admin-export-btn { display: inline-block; }
    body.operator-mode .admin-sidenav .admin-only { display: none !important; }
    body.operator-mode .admin-sidenav .admin-sidenav-header { display: none !important; }
    body.operator-mode .admin-sidenav .admin-sidenav-divider:first-of-type { display: none !important; }
    /* REQ-001 V5.1: 管理员/运营/测试角色隐藏发布按钮 */
    body.admin-mode .upload-section { display: none !important; }
    body.operator-mode .upload-section { display: none !important; }
    body.tester-mode .upload-section { display: none !important; }

    .admin-sidenav-header {
      width: 36px;
      height: 36px;
      border-radius: 50%;
      background: linear-gradient(135deg, #8e44ad, #3498db);
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 18px;
      margin-bottom: 8px;
      flex-shrink: 0;
    }

    .admin-sidenav-divider {
      width: 32px;
      height: 1px;
      background: rgba(255,255,255,0.1);
      margin: 4px 0;
    }

    .admin-sidenav-btn {
      position: relative;
      width: 40px;
      height: 40px;
      border-radius: 10px;
      border: none;
      background: transparent;
      color: rgba(255,255,255,0.6);
      font-size: 18px;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
      flex-shrink: 0;
    }
    .admin-sidenav-btn:hover {
      background: rgba(255,255,255,0.12);
      color: #fff;
    }
    .admin-sidenav-btn.active {
      background: rgba(142, 68, 173, 0.35);
      color: #fff;
    }
    .admin-sidenav-btn .sidenav-tooltip {
      position: absolute;
      left: calc(100% + 12px);
      top: 50%;
      transform: translateY(-50%);
      background: rgba(20, 20, 50, 0.95);
      border: 1px solid rgba(255,255,255,0.15);
      color: #fff;
      font-size: 12px;
      font-weight: 600;
      padding: 5px 10px;
      border-radius: 8px;
      white-space: nowrap;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.15s;
      z-index: 10;
    }
    .admin-sidenav-btn:hover .sidenav-tooltip { opacity: 1; }

    .admin-sidenav-logout {
      margin-top: 8px;
      width: 36px;
      height: 36px;
      border-radius: 10px;
      border: 1px solid rgba(231, 76, 60, 0.3);
      background: rgba(231, 76, 60, 0.1);
      color: rgba(231, 76, 60, 0.8);
      font-size: 16px;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
      flex-shrink: 0;
      position: relative;
    }
    .admin-sidenav-logout:hover {
      background: rgba(231, 76, 60, 0.25);
      color: #e74c3c;
    }
    .admin-sidenav-logout .sidenav-tooltip {
      position: absolute;
      left: calc(100% + 12px);
      top: 50%;
      transform: translateY(-50%);
      background: rgba(20, 20, 50, 0.95);
      border: 1px solid rgba(255,255,255,0.15);
      color: #fff;
      font-size: 12px;
      font-weight: 600;
      padding: 5px 10px;
      border-radius: 8px;
      white-space: nowrap;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.15s;
      z-index: 10;
    }
    .admin-sidenav-logout:hover .sidenav-tooltip { opacity: 1; }

    .card-admin-actions {
      display: none;
      position: absolute;
      top: 6px;
      right: 6px;
      z-index: 10;
      gap: 4px;
    }

    body.admin-mode .card-admin-actions {
      display: flex;
    }

    /* REQ-006 M01: operator-mode — shows edit/delete on cards but NOT admin system UI */
    body.operator-mode .card-admin-actions {
      display: flex;
    }
    body.operator-mode .admin-mode .skill-card-admin-actions,
    body.operator-mode .skill-card-admin-actions {
      display: flex;
    }

    .card-user-actions {
      display: flex;
      position: absolute;
      top: 6px;
      right: 6px;
      z-index: 10;
      gap: 4px;
    }

    body.admin-mode .card-user-actions {
      display: none;
    }

    .card-admin-btn {
      width: 24px;
      height: 24px;
      border-radius: 6px;
      border: none;
      cursor: pointer;
      font-size: 11px;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
      backdrop-filter: blur(8px);
    }

    .card-admin-btn.edit-btn {
      background: rgba(52, 152, 219, 0.85);
      color: #fff;
    }

    .card-admin-btn.edit-btn:hover {
      background: rgba(52, 152, 219, 1);
      transform: scale(1.1);
    }

    .card-admin-btn.delete-btn {
      background: rgba(231, 76, 60, 0.85);
      color: #fff;
    }

    .card-admin-btn.delete-btn:hover {
      background: rgba(231, 76, 60, 1);
      transform: scale(1.1);
    }

    /* Admin login modal */
    .admin-login-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 1200;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }

    .admin-login-overlay.show { display: flex; }

    .admin-login-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 32px;
      max-width: 380px;
      width: 100%;
      text-align: center;
      animation: modalIn 0.3s ease;
    }

    .admin-login-box h3 {
      font-size: 20px;
      font-weight: 800;
      margin-bottom: 8px;
    }

    .admin-login-box .login-hint {
      font-size: 13px;
      color: var(--text-muted);
      margin-bottom: 24px;
    }

    .admin-login-box .form-input {
      margin-bottom: 8px;
    }

    .admin-login-box .login-error {
      font-size: 12px;
      color: #e74c3c;
      margin-bottom: 12px;
      min-height: 18px;
    }

    .admin-login-box .login-buttons {
      display: flex;
      gap: 12px;
      margin-top: 8px;
    }

    /* Delete confirm modal */
    .delete-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.6);
      backdrop-filter: blur(4px);
      z-index: 1100;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }

    .delete-overlay.show { display: flex; }

    .delete-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 16px;
      padding: 28px;
      max-width: 400px;
      width: 100%;
      text-align: center;
      animation: modalIn 0.3s ease;
    }

    .delete-box h4 {
      font-size: 18px;
      margin-bottom: 12px;
      color: #e74c3c;
    }

    .delete-box .delete-project-name {
      font-size: 15px;
      color: var(--text);
      margin-bottom: 20px;
      padding: 12px;
      background: rgba(255,255,255,0.05);
      border-radius: 10px;
    }

    .delete-box .delete-buttons {
      display: flex;
      gap: 12px;
    }

    /* Mobile */
    @media (max-width: 768px) {
      /* 2026-04-23 (20260423 Bug #9): iPhone Safari 当聚焦 font-size < 16px 的 input 时自动放大页面,
         需要把所有输入控件 font-size 提到 16px (viewport 也禁了 user-scalable, 双保险) */
      input[type="text"], input[type="email"], input[type="password"], input[type="search"],
      input[type="tel"], input[type="url"], input[type="number"], input[type="date"],
      textarea, select {
        font-size: 16px !important;
      }
      /* 2026-04-24: 手机 hero 收紧垂直空间 — 避免浪费过多首屏.
         安全带: 顶部预留 ~55px (给 fixed user-toolbar), 底部预留 ~95px (给 primary-tabs @bottom:52 + mobile-ranking-entry @bottom:16).
         粒子标题在 canvas 绘制时额外向上偏移 (见 getTextPositions), 避免被底部 UI 遮盖. */
      .hero { min-height: 260px; height: 36vh; max-height: 340px; }
      .hero-subtitle-text { margin-top: 70px; }
      /* 2026-04-23: 手机端 navbar 居中对齐; 使用 safe center 在内容溢出时回退为左起, 避免起点被推到视口外无法滚动 */
      .navbar { justify-content: safe center; padding: 8px 16px; overflow-x: auto; }
      .nav-item { padding: 12px 16px; font-size: 14px; white-space: nowrap; flex-shrink: 0; }
      .cards-grid { grid-template-columns: 1fr; gap: 16px; }
      .card-title { font-size: 17px; }
      .card-desc { font-size: 13px; }
      .modal { padding: 24px 20px; max-height: 85vh; }
      .upload-btn { padding: 14px 36px; font-size: 16px; }
      .main-content { padding: 24px 12px 80px; }
      #main-content { flex-direction: column; }
      #game-content { flex-direction: column; }
      .skill-list-container .main-content { flex-direction: column; }
      .ranking-sidebar { display: none; }

      /* View mode toggle - only on mobile */
      .view-mode-toggle { display: flex !important; }

      /* List mode styles */
      .cards-grid.list-mode {
        display: flex;
        flex-direction: column;
        gap: 10px;
      }
      .cards-grid.list-mode .card {
        flex-direction: row;
        align-items: center;
        padding: 10px;
        gap: 10px;
      }
      .cards-grid.list-mode .card-head {
        flex: 1;
        min-width: 0;
        overflow: hidden;
      }
      .cards-grid.list-mode .card-text {
        min-width: 0;
        overflow: hidden;
      }
      .cards-grid.list-mode .card-icon-wrap {
        width: 56px;
        height: 56px;
        flex-shrink: 0;
        border-radius: 12px;
      }
      .cards-grid.list-mode .card-title {
        /* 2026-04-23: 字号统一 17px (与桌面默认一致) */
        font-size: 17px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
      .cards-grid.list-mode .card-desc-wrap { overflow: hidden; }
      .cards-grid.list-mode .card-desc {
        /* 2026-04-23: 字号统一 13px */
        font-size: 13px;
        -webkit-line-clamp: 1;
        line-clamp: 1;
        display: block;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
      }
      .cards-grid.list-mode .share-text { display: none; }
      .cards-grid.list-mode .card:hover { transform: none; box-shadow: none; }
      .cards-grid.list-mode .card-admin-actions,
      .cards-grid.list-mode .card-user-actions {
        top: 4px; right: 4px;
      }
    }

    /* View mode toggle button - inline in module title */
    .view-mode-toggle {
      display: flex;
      align-items: center;
      gap: 4px;
      margin: 0;
      padding: 0;
      flex-shrink: 0;
    }

    /* PC list-mode styles */
    @media (min-width: 769px) {
      .cards-grid.list-mode {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 16px;
      }
      .cards-grid.list-mode .card {
        flex-direction: row;
        align-items: center;
        padding: 10px;
        gap: 10px;
      }
      .cards-grid.list-mode .card-head {
        flex: 1;
        min-width: 0;
        overflow: hidden;
      }
      .cards-grid.list-mode .card-text {
        min-width: 0;
        overflow: hidden;
      }
      .cards-grid.list-mode .card-icon-wrap {
        width: 64px;
        height: 64px;
        flex-shrink: 0;
        border-radius: 12px;
      }
      .cards-grid.list-mode .card-title { font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
      .cards-grid.list-mode .card-desc-wrap { overflow: hidden; }
      .cards-grid.list-mode .card-desc { font-size: 13px; -webkit-line-clamp: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
      .cards-grid.list-mode .share-text { display: none; }
      .cards-grid.list-mode .card:hover { transform: none; box-shadow: none; }
      .cards-grid.list-mode .card-admin-actions,
      .cards-grid.list-mode .card-user-actions { top: 4px; right: 4px; }
    }
    @media (min-width: 1280px) {
      .cards-grid.list-mode { grid-template-columns: repeat(3, 1fr); }
    }
    @media (min-width: 1024px) and (max-width: 1279px) {
      .cards-grid.list-mode { grid-template-columns: repeat(2, 1fr); }
    }
    @media (min-width: 769px) and (max-width: 1023px) {
      .cards-grid.list-mode { grid-template-columns: repeat(2, 1fr); }
    }
    .view-mode-btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 28px;
      height: 28px;
      border-radius: 6px;
      border: 1px solid var(--card-border);
      background: transparent;
      color: var(--text-muted);
      cursor: pointer;
      transition: all 0.2s;
    }
    .view-mode-btn.active {
      background: rgba(142, 68, 173, 0.3);
      border-color: rgba(142, 68, 173, 0.6);
      color: #fff;
    }
    .view-mode-btn svg { width: 16px; height: 16px; }

    /* ===== Primary Category Switcher ===== */
    .primary-tabs {
      position: absolute;
      bottom: 70px;
      left: 50%;
      transform: translateX(-50%);
      display: flex;
      justify-content: center;
      gap: 12px;
      z-index: 10;
    }
    .primary-tab {
      position: relative;
      padding: 10px 32px;
      border-radius: 16px;
      font-size: 15px;
      font-weight: 700;
      color: rgba(255,255,255,0.6);
      cursor: pointer;
      transition: all 0.3s ease;
      background: rgba(255,255,255,0.08);
      backdrop-filter: blur(16px) saturate(1.4);
      -webkit-backdrop-filter: blur(16px) saturate(1.4);
      border: 1px solid rgba(255,255,255,0.12);
      user-select: none;
      letter-spacing: 0.5px;
      white-space: nowrap;
      flex-shrink: 0;
      box-shadow: 0 4px 16px rgba(0,0,0,0.2);
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 2px;
    }
    .primary-tab-label {
      font-size: inherit;
      font-weight: inherit;
    }
    .primary-tab-count {
      font-size: 11px;
      font-weight: 600;
      opacity: 0.6;
      line-height: 1;
    }
    .primary-tab.active .primary-tab-count {
      opacity: 0.9;
    }
    .primary-tab:hover {
      color: rgba(255,255,255,0.9);
      background: rgba(255,255,255,0.14);
      border-color: rgba(255,255,255,0.2);
      box-shadow: 0 6px 24px rgba(0,0,0,0.3);
      transform: translateY(-1px);
    }
    .primary-tab.active {
      color: #fff;
      background: linear-gradient(135deg, rgba(142, 68, 173, 0.45), rgba(52, 152, 219, 0.35));
      border-color: rgba(142, 68, 173, 0.5);
      box-shadow: 0 6px 24px rgba(142, 68, 173, 0.35);
    }

    /* ===== Skill Grid (REQ-001) ===== */
    .skill-list-container {
      display: none;
    }
    .skill-list-container.show {
      display: block;
    }
    /* Skill category tabs */
    .skill-cat-tabs {
      display: flex;
      gap: 8px;
      flex-wrap: wrap;
      margin-bottom: 20px;
      padding: 0 0 8px;
      border-bottom: 1px solid rgba(255,255,255,0.06);
    }
    .skill-cat-tab {
      padding: 6px 16px;
      border-radius: 20px;
      border: 1px solid rgba(255,255,255,0.1);
      background: rgba(255,255,255,0.04);
      color: var(--text-muted);
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s;
      font-family: var(--font-body);
    }
    .skill-cat-tab:hover {
      background: rgba(142,68,173,0.15);
      border-color: rgba(142,68,173,0.3);
      color: var(--text);
    }
    .skill-cat-tab.active {
      background: linear-gradient(135deg, rgba(142,68,173,0.35), rgba(52,152,219,0.25));
      border-color: rgba(142,68,173,0.5);
      color: #fff;
    }
    /* Skill grid */
    .skill-grid {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 16px;
    }
    @media (max-width: 1100px) {
      .skill-grid { grid-template-columns: repeat(3, 1fr); }
    }
    @media (max-width: 768px) {
      .skill-grid { grid-template-columns: repeat(2, 1fr); }
    }
    @media (max-width: 480px) {
      .skill-grid { grid-template-columns: 1fr; }
    }
    /* Skill card */
    .skill-card {
      background: var(--card-bg);
      border: 1px solid var(--card-border);
      border-radius: 16px;
      overflow: hidden;
      cursor: pointer;
      transition: transform 0.2s, box-shadow 0.2s;
      position: relative;
      display: flex;
      flex-direction: column;
    }
    .skill-card:hover {
      transform: translateY(-4px);
      box-shadow: 0 12px 32px rgba(108, 92, 231, 0.25);
      border-color: rgba(142,68,173,0.4);
    }
    .skill-card-cover {
      width: 100%;
      aspect-ratio: 16/9;
      background: linear-gradient(135deg, rgba(142,68,173,0.2), rgba(52,152,219,0.15));
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 40px;
      overflow: hidden;
      flex-shrink: 0;
      position: relative;
    }
    .skill-card-cover img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      opacity: 0;
      transition: opacity 0.3s;
    }
    .skill-card-cover img.loaded { opacity: 1; }
    /* Badge corner labels */
    .skill-badge {
      position: absolute;
      top: 8px;
      right: 8px;
      padding: 3px 8px;
      border-radius: 8px;
      font-size: 11px;
      font-weight: 800;
      letter-spacing: 0.5px;
      z-index: 2;
    }
    .skill-badge-ysp {
      background: linear-gradient(135deg, #f39c12, #e67e22);
      color: #fff;
      box-shadow: 0 2px 8px rgba(243,156,18,0.4);
    }
    .skill-badge-qb {
      background: linear-gradient(135deg, #3498db, #2980b9);
      color: #fff;
      box-shadow: 0 2px 8px rgba(52,152,219,0.4);
    }
    /* prd4ai-011 R: 双标签合并时使用"平台上架必备"（紫/金渐变，区分于单色） */
    .skill-badge-both {
      background: linear-gradient(135deg, #8e44ad, #f39c12);
      color: #fff;
      box-shadow: 0 2px 8px rgba(142, 68, 173, 0.45);
    }
    .skill-card-body {
      padding: 14px 16px;
      flex: 1;
      display: flex;
      flex-direction: column;
    }
    .skill-card-name {
      font-size: 15px;
      font-weight: 700;
      color: var(--text);
      margin-bottom: 6px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .skill-card-desc {
      font-size: 12px;
      color: var(--text-muted);
      line-height: 1.5;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
      flex: 1;
      margin-bottom: 10px;
    }
    .skill-card-meta {
      font-size: 11px;
      color: rgba(189,195,199,0.5);
      margin-bottom: 10px;
    }
    .skill-card-footer {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
      border-top: 1px solid rgba(255,255,255,0.06);
      padding-top: 10px;
      margin-top: auto;
    }
    .skill-card-stats {
      display: flex;
      gap: 10px;
      font-size: 12px;
      color: rgba(189,195,199,0.55);
    }
    .skill-card-stats span {
      display: flex;
      align-items: center;
      gap: 3px;
    }
    /* Star button */
    .skill-star-btn {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      padding: 5px 12px;
      background: rgba(255,255,255,0.05);
      border: 1px solid rgba(255,255,255,0.1);
      color: var(--text-muted);
      border-radius: 10px;
      font-size: 12px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s;
      flex-shrink: 0;
    }
    .skill-star-btn:hover {
      background: rgba(241,196,15,0.15);
      border-color: rgba(241,196,15,0.3);
      color: #f1c40f;
    }
    .skill-star-btn.starred {
      background: rgba(241,196,15,0.2);
      border-color: rgba(241,196,15,0.45);
      color: #f1c40f;
    }
    /* Admin badge button on skill card */
    .skill-card-admin-actions {
      display: none;
      gap: 4px;
    }
    .admin-mode .skill-card-admin-actions {
      display: flex;
    }
    /* REQ-006 M01: operator can also manage skills */
    body.operator-mode .skill-card-admin-actions {
      display: flex;
    }
    .skill-badge-btn {
      padding: 3px 8px;
      border-radius: 8px;
      border: none;
      font-size: 11px;
      font-weight: 700;
      cursor: pointer;
      transition: all 0.2s;
    }
    .skill-badge-btn-ysp {
      background: rgba(243,156,18,0.25);
      color: #f39c12;
      border: 1px solid rgba(243,156,18,0.4);
    }
    .skill-badge-btn-ysp:hover, .skill-badge-btn-ysp.active {
      background: rgba(243,156,18,0.5);
    }
    .skill-badge-btn-qb {
      background: rgba(52,152,219,0.25);
      color: #3498db;
      border: 1px solid rgba(52,152,219,0.4);
    }
    .skill-badge-btn-qb:hover, .skill-badge-btn-qb.active {
      background: rgba(52,152,219,0.5);
    }
    /* Skill detail modal */
    .skill-detail-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.75);
      backdrop-filter: blur(6px);
      z-index: 1500;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .skill-detail-overlay.show { display: flex; }
    .skill-detail-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      max-width: 640px;
      width: 100%;
      max-height: 85vh;
      overflow-y: auto;
      animation: modalIn 0.3s ease;
    }
    .skill-detail-cover {
      width: 100%;
      aspect-ratio: 16/9;
      background: linear-gradient(135deg, rgba(142,68,173,0.3), rgba(52,152,219,0.2));
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 64px;
      border-radius: 20px 20px 0 0;
      overflow: hidden;
      flex-shrink: 0;
      position: relative;
    }
    .skill-detail-cover img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    .skill-detail-content {
      padding: 24px;
    }
    .skill-detail-header {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
      gap: 12px;
      margin-bottom: 16px;
    }
    .skill-detail-title {
      font-size: 22px;
      font-weight: 800;
      color: var(--text);
      line-height: 1.3;
    }
    .skill-detail-close {
      width: 32px;
      height: 32px;
      border-radius: 50%;
      border: 1px solid var(--card-border);
      background: rgba(255,255,255,0.05);
      color: var(--text-muted);
      font-size: 18px;
      cursor: pointer;
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
    }
    .skill-detail-close:hover { background: rgba(255,255,255,0.12); color: var(--text); }
    .skill-detail-badge {
      display: inline-block;
      padding: 3px 10px;
      border-radius: 8px;
      font-size: 12px;
      font-weight: 700;
      margin-bottom: 12px;
    }
    .skill-detail-meta {
      font-size: 13px;
      color: var(--text-muted);
      margin-bottom: 16px;
      display: flex;
      gap: 16px;
      flex-wrap: wrap;
    }
    .skill-detail-desc-short {
      font-size: 14px;
      color: var(--text-muted);
      line-height: 1.7;
      margin-bottom: 16px;
      padding: 14px;
      background: rgba(255,255,255,0.04);
      border-radius: 10px;
      border-left: 3px solid rgba(142,68,173,0.5);
    }
    .skill-detail-long-desc {
      font-size: 14px;
      color: var(--text);
      line-height: 1.8;
      margin-bottom: 20px;
      white-space: pre-wrap;
    }
    .skill-detail-timeline-title {
      font-size: 13px;
      font-weight: 700;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: 1px;
      margin-bottom: 12px;
    }
    .skill-timeline {
      display: flex;
      flex-direction: column;
      gap: 0;
      margin-bottom: 20px;
    }
    .skill-timeline-item {
      display: flex;
      gap: 12px;
      position: relative;
      padding-bottom: 16px;
    }
    .skill-timeline-item:last-child { padding-bottom: 0; }
    .skill-timeline-item:last-child .skill-timeline-line { display: none; }
    .skill-timeline-dot-wrap {
      display: flex;
      flex-direction: column;
      align-items: center;
      flex-shrink: 0;
      width: 20px;
    }
    .skill-timeline-dot {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: rgba(142,68,173,0.7);
      border: 2px solid rgba(142,68,173,0.4);
      margin-top: 4px;
      flex-shrink: 0;
    }
    .skill-timeline-item:first-child .skill-timeline-dot {
      background: var(--primary);
      border-color: rgba(142,68,173,0.8);
      box-shadow: 0 0 8px rgba(142,68,173,0.5);
    }
    .skill-timeline-line {
      width: 1px;
      flex: 1;
      background: rgba(255,255,255,0.1);
      margin-top: 4px;
    }
    .skill-timeline-content {
      flex: 1;
      padding-bottom: 4px;
    }
    .skill-timeline-ver {
      font-size: 12px;
      font-weight: 700;
      color: var(--primary-light);
      margin-bottom: 2px;
    }
    .skill-timeline-file {
      font-size: 13px;
      color: var(--text);
      margin-bottom: 2px;
    }
    .skill-timeline-date {
      font-size: 11px;
      color: rgba(189,195,199,0.5);
    }
    .skill-detail-actions {
      display: flex;
      gap: 10px;
      margin-top: 16px;
      flex-wrap: wrap;
    }
    .skill-detail-download-btn {
      flex: 1;
      min-width: 120px;
      padding: 12px 20px;
      background: linear-gradient(135deg, rgba(46,204,113,0.2), rgba(46,204,113,0.1));
      border: 1px solid rgba(46,204,113,0.4);
      color: #2ecc71;
      border-radius: 12px;
      font-size: 14px;
      font-weight: 700;
      cursor: pointer;
      transition: all 0.2s;
      text-align: center;
    }
    .skill-detail-download-btn:hover {
      background: rgba(46,204,113,0.3);
      box-shadow: 0 4px 16px rgba(46,204,113,0.25);
    }
    .skill-detail-star-btn {
      padding: 12px 20px;
      background: rgba(255,255,255,0.05);
      border: 1px solid rgba(255,255,255,0.1);
      color: var(--text-muted);
      border-radius: 12px;
      font-size: 14px;
      font-weight: 700;
      cursor: pointer;
      transition: all 0.2s;
    }
    .skill-detail-star-btn.starred {
      background: rgba(241,196,15,0.2);
      border-color: rgba(241,196,15,0.45);
      color: #f1c40f;
    }
    .skill-detail-star-btn:hover {
      background: rgba(241,196,15,0.15);
      border-color: rgba(241,196,15,0.3);
      color: #f1c40f;
    }
    /* REQ-005: Skill rating stars */
    .skill-rating-star {
      font-size: 20px;
      color: #ccc;
      cursor: pointer;
      transition: color 0.15s, transform 0.1s;
      user-select: none;
    }
    .skill-rating-star:hover,
    .skill-rating-star.hover {
      color: #f1c40f;
      transform: scale(1.2);
    }
    .skill-rating-star.my-rated {
      color: #e67e22;
    }
    .skill-rating-star.avg-filled {
      color: #f1c40f;
    }
    .skill-rating-stars:hover .skill-rating-star {
      color: #ccc;
    }
    .skill-rating-stars:hover .skill-rating-star:hover,
    .skill-rating-stars:hover .skill-rating-star:hover ~ .skill-rating-star { /* not easy in CSS, handled in JS */ }

    /* ===== Project Rating Popconfirm ===== */
    .proj-rating-row {
      display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    }
    .proj-rating-avg-stars {
      display: flex; gap: 1px; align-items: center;
    }
    .proj-rating-avg-stars .star-icon {
      width: 16px; height: 16px; color: #f1c40f; fill: #f1c40f;
    }
    .proj-rating-avg-stars .star-icon.empty {
      fill: none; color: #555;
    }
    .proj-rating-avg-text {
      font-size: 14px; font-weight: 600; color: var(--text-primary, #ecf0f1); margin-left: 2px;
    }
    .proj-rating-count {
      font-size: 12px; color: var(--text-muted, #bdc3c7);
    }
    .proj-rating-action-btn {
      display: inline-flex; align-items: center; gap: 4px;
      font-size: 12px; padding: 3px 10px; border-radius: 12px;
      border: 1px solid rgba(241,196,15,0.4); background: rgba(241,196,15,0.08);
      color: #f1c40f; cursor: pointer; transition: all 0.2s; user-select: none;
    }
    .proj-rating-action-btn:hover {
      background: rgba(241,196,15,0.18); border-color: rgba(241,196,15,0.6);
    }
    .proj-rating-my-score {
      font-size: 12px; color: var(--primary, #8e44ad); cursor: pointer;
      user-select: none; transition: opacity 0.2s;
    }
    .proj-rating-my-score:hover { opacity: 0.8; text-decoration: underline; }

    /* Popconfirm bubble — prd4ai-011: 统一改为居中模态, PC/移动均从页面中心弹出 */
    .rating-popconfirm {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: 9999;
      background: #1e1b3a; border: 1px solid rgba(255,255,255,0.15);
      border-radius: 12px; padding: 18px 20px;
      box-shadow: 0 8px 32px rgba(0,0,0,0.45);
      width: min(320px, calc(100vw - 32px));
      min-width: 200px;
      animation: popconfirmFadeIn 0.15s ease-out;
    }
    .rating-popconfirm::before { display: none; } /* 居中模态不需要箭头 */
    /* 2026-04-24 buglist #31: 手机端额外样式保留兼容 */
    @media (max-width: 768px) {
      .rating-popconfirm.is-mobile-modal {
        position: fixed;
        top: 50%;
        left: 50%;
        right: auto;
        bottom: auto;
        margin: 0;
        transform: translate(-50%, -50%);
        width: min(320px, calc(100vw - 32px));
        min-width: 0;
        z-index: 9999;
        padding: 18px 20px;
      }
      /* 手机模态形态下不画箭头, 由 backdrop 提供上下文 */
      .rating-popconfirm.is-mobile-modal::before { display: none; }
      /* 手机端让按钮区/星星区留出更大点击热区 */
      .rating-popconfirm.is-mobile-modal .rating-popconfirm-title {
        font-size: 15px;
        text-align: center;
        margin-bottom: 14px;
      }
      .rating-popconfirm.is-mobile-modal .rating-popconfirm-stars {
        justify-content: center;
        gap: 8px;
        margin-bottom: 16px;
      }
      .rating-popconfirm.is-mobile-modal .rating-popconfirm-stars .pop-star { font-size: 28px; }
      .rating-popconfirm.is-mobile-modal .rating-popconfirm-btns { justify-content: center; gap: 12px; }
      .rating-popconfirm.is-mobile-modal .rating-popconfirm-btns button { padding: 8px 22px; font-size: 14px; }
    }
    /* 手机模态的半透明背板, 与 popconfirm 同步显隐 */
    .rating-popconfirm-backdrop {
      display: none;
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.45);
      z-index: 9998;
      animation: popconfirmFadeIn 0.15s ease-out;
    }
    .rating-popconfirm-backdrop.show { display: block; }
    .rating-popconfirm::before {
      content: ''; position: absolute; top: -6px;
      left: var(--arrow-left, 24px);
      width: 12px; height: 12px; background: #1e1b3a;
      border-left: 1px solid rgba(255,255,255,0.15);
      border-top: 1px solid rgba(255,255,255,0.15);
      transform: rotate(45deg);
    }
    /* 2026-04-27 buglist: 评分弹窗动画修复
       原 keyframe 使用 translateY 会覆盖 .rating-popconfirm 外层的 translate(-50%, -50%)
       导致弹窗先定位在 top:50%/left:50% 的左上角点（视觉上右下方区域），动画结束后
       才"跳回"中心。改为仅动画 opacity + scale（不覆盖居中 transform）。*/
    @keyframes popconfirmFadeIn {
      from { opacity: 0; transform: translate(-50%, -50%) scale(0.96); }
      to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
    }
    .rating-popconfirm-title {
      font-size: 13px; color: var(--text, #ecf0f1); margin-bottom: 10px; font-weight: 500;
    }
    .rating-popconfirm-stars {
      display: flex; gap: 4px; margin-bottom: 12px;
    }
    .rating-popconfirm-stars .pop-star {
      font-size: 24px; cursor: pointer; transition: all 0.15s; user-select: none;
      color: #555; fill: none;
    }
    .rating-popconfirm-stars .pop-star.active {
      color: #f1c40f; fill: #f1c40f;
    }
    .rating-popconfirm-stars .pop-star:hover {
      transform: scale(1.2);
    }
    .rating-popconfirm-btns {
      display: flex; gap: 8px; justify-content: flex-end;
    }
    .rating-popconfirm-btns button {
      font-size: 12px; padding: 4px 14px; border-radius: 6px; cursor: pointer;
      border: 1px solid rgba(255,255,255,0.15); transition: all 0.2s;
    }
    .rating-popconfirm-btns .pop-cancel {
      background: transparent; color: var(--text-muted, #bdc3c7);
    }
    .rating-popconfirm-btns .pop-cancel:hover {
      background: rgba(255,255,255,0.06);
    }
    .rating-popconfirm-btns .pop-confirm {
      background: #f1c40f; color: #1e1b3a; border-color: #f1c40f; font-weight: 600;
    }
    .rating-popconfirm-btns .pop-confirm:hover {
      background: #f39c12;
    }
    .rating-popconfirm-btns .pop-confirm:disabled {
      opacity: 0.4; cursor: not-allowed;
    }
    /* Legacy skill styles kept for compat */
    .skill-edit-btn, .skill-delete-btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      border-radius: 8px;
      border: none;
      cursor: pointer;
      font-size: 14px;
      transition: all 0.2s;
    }
    .skill-edit-btn {
      background: rgba(52, 152, 219, 0.2);
      color: #3498db;
      border: 1px solid rgba(52, 152, 219, 0.3);
    }
    .skill-edit-btn:hover { background: rgba(52, 152, 219, 0.4); }
    .skill-delete-btn {
      background: rgba(231, 76, 60, 0.2);
      color: #e74c3c;
      border: 1px solid rgba(231, 76, 60, 0.3);
    }
    .skill-delete-btn:hover { background: rgba(231, 76, 60, 0.4); }
    .skill-like-btn {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      padding: 6px 14px;
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid rgba(255, 255, 255, 0.1);
      color: var(--text-muted);
      border-radius: 10px;
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s;
    }
    .skill-like-btn:hover {
      background: rgba(231, 76, 60, 0.15);
      border-color: rgba(231, 76, 60, 0.3);
      color: #e74c3c;
    }
    .skill-like-btn.liked {
      background: rgba(231, 76, 60, 0.2);
      border-color: rgba(231, 76, 60, 0.4);
      color: #e74c3c;
    }

    /* ===== Search Modal (prd4ai-009: 替换原 hero 搜索栏) ===== */
    .search-modal-overlay {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 2000;
      background: rgba(5, 3, 15, 0.72);
      backdrop-filter: blur(4px);
      align-items: flex-start;
      justify-content: center;
      padding-top: 10vh;
    }
    .search-modal-overlay.show { display: flex; }
    .search-modal-box {
      width: 100%;
      max-width: 640px;
      max-height: 78vh;
      background: linear-gradient(180deg, rgba(30,25,60,0.98), rgba(18,14,40,0.98));
      border: 1px solid rgba(142, 68, 173, 0.3);
      border-radius: 16px;
      box-shadow: 0 20px 60px rgba(0,0,0,0.5);
      display: flex;
      flex-direction: column;
      overflow: hidden;
      animation: searchModalIn 0.18s ease-out;
    }
    @keyframes searchModalIn {
      from { opacity: 0; transform: translateY(-12px); }
      to   { opacity: 1; transform: translateY(0); }
    }
    .search-modal-head {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 14px 18px;
      border-bottom: 1px solid rgba(255,255,255,0.08);
    }
    .search-modal-head .icon {
      color: var(--text-muted);
      display: flex;
      align-items: center;
    }
    .search-modal-input {
      flex: 1;
      background: transparent;
      border: none;
      outline: none;
      color: var(--text);
      font-size: 15px;
      font-family: var(--font-body);
    }
    .search-modal-input::placeholder { color: rgba(189, 195, 199, 0.5); }
    .search-modal-close {
      background: rgba(255,255,255,0.08);
      border: none;
      color: var(--text-muted);
      width: 28px;
      height: 28px;
      border-radius: 50%;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 16px;
      line-height: 1;
    }
    .search-modal-close:hover { background: rgba(255,255,255,0.18); color: var(--text); }
    .search-modal-body {
      flex: 1;
      overflow-y: auto;
      padding: 6px 0;
    }
    .search-modal-hint {
      padding: 28px 20px;
      color: var(--text-muted);
      text-align: center;
      font-size: 13px;
    }
    .search-modal-item {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 10px 18px;
      cursor: pointer;
      transition: background 0.15s;
      border-left: 3px solid transparent;
    }
    .search-modal-item:hover,
    .search-modal-item.active {
      background: rgba(142, 68, 173, 0.12);
      border-left-color: #8e44ad;
    }
    .search-modal-item-icon {
      width: 40px;
      height: 40px;
      border-radius: 10px;
      background: rgba(255,255,255,0.05);
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      overflow: hidden;
      /* PRD4AI-007 buglist #16: 防止容器被子元素撑开 */
      min-width: 40px;
      min-height: 40px;
      /* 2026-04-23 bugfix #12: 作为 absolute img 的定位锚 */
      position: relative;
    }
    .search-modal-item-icon img {
      width: 100%;
      height: 100%;
      max-width: 100%;
      max-height: 100%;
      object-fit: cover;
      display: block;
      flex-shrink: 0;
      /* 2026-04-23 bugfix: 父级 display:flex 时, img 会被 align-items:center 影响到宽度
         使用 absolute 定位 + inset 可以确保 img 严格填充容器 40x40, 不出现偏左残影 */
      position: absolute;
      inset: 0;
    }
    .search-modal-item-icon .fallback {
      color: rgba(255,255,255,0.3);
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    /* PRD4AI-007 buglist #16: lucide svg 默认 24px，这里强制撑满容器 */
    .search-modal-item-icon .fallback svg,
    .search-modal-item-icon svg[data-lucide] {
      width: 22px;
      height: 22px;
    }
    /* 2026-04-23: 按类型着色 fallback 图标, 视觉更一致 */
    .search-modal-item-icon.type-app {
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.18), rgba(34, 211, 238, 0.1));
    }
    .search-modal-item-icon.type-app .fallback { color: var(--ds-brand-purple-hover); }
    .search-modal-item-icon.type-game {
      background: linear-gradient(135deg, rgba(236, 72, 153, 0.18), rgba(239, 68, 68, 0.1));
    }
    .search-modal-item-icon.type-game .fallback { color: #f472b6; }
    .search-modal-item-icon.type-skill {
      background: linear-gradient(135deg, rgba(34, 211, 238, 0.18), rgba(59, 130, 246, 0.1));
    }
    .search-modal-item-icon.type-skill .fallback { color: var(--ds-brand-cyan); }
    /* 2026-04-23: 按类型着色 fallback 图标, 视觉更一致 */
    .search-modal-item-icon.type-app {
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.18), rgba(34, 211, 238, 0.1));
    }
    .search-modal-item-icon.type-app .fallback { color: var(--ds-brand-purple-hover); }
    .search-modal-item-icon.type-game {
      background: linear-gradient(135deg, rgba(236, 72, 153, 0.18), rgba(239, 68, 68, 0.1));
    }
    .search-modal-item-icon.type-game .fallback { color: #f472b6; }
    .search-modal-item-icon.type-skill {
      background: linear-gradient(135deg, rgba(34, 211, 238, 0.18), rgba(59, 130, 246, 0.1));
    }
    .search-modal-item-icon.type-skill .fallback { color: var(--ds-brand-cyan); }
    .search-modal-item-main {
      flex: 1;
      min-width: 0;
    }
    .search-modal-item-title {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 14px;
      color: var(--text);
      font-weight: 600;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .search-modal-badge {
      font-size: 10px;
      font-weight: 600;
      padding: 2px 6px;
      border-radius: 4px;
      flex-shrink: 0;
      line-height: 1.4;
      letter-spacing: 0.5px;
    }
    .search-modal-badge.type-app   { background: rgba(52, 152, 219, 0.18); color: #5dadeb; border: 1px solid rgba(52,152,219,0.3); }
    .search-modal-badge.type-game  { background: rgba(230, 126, 34, 0.18); color: #f1a053; border: 1px solid rgba(230,126,34,0.3); }
    .search-modal-badge.type-skill { background: rgba(142, 68, 173, 0.18); color: #c39bd3; border: 1px solid rgba(142,68,173,0.3); }
    .search-modal-item-desc {
      font-size: 12px;
      color: var(--text-muted);
      margin-top: 2px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    /* 搜索结果操作按钮（编辑/删除） */
    .search-modal-item-actions {
      display: flex;
      gap: 6px;
      margin-left: auto;
      flex-shrink: 0;
      align-items: center;
    }
    .search-modal-action-btn {
      width: 28px;
      height: 28px;
      border-radius: 6px;
      border: none;
      cursor: pointer;
      font-size: 12px;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
      backdrop-filter: blur(8px);
    }
    .search-modal-action-btn.edit-btn {
      background: rgba(52, 152, 219, 0.85);
      color: #fff;
    }
    .search-modal-action-btn.edit-btn:hover {
      background: rgba(52, 152, 219, 1);
      transform: scale(1.1);
    }
    .search-modal-action-btn.delete-btn {
      background: rgba(231, 76, 60, 0.85);
      color: #fff;
    }
    .search-modal-action-btn.delete-btn:hover {
      background: rgba(231, 76, 60, 1);
      transform: scale(1.1);
    }

    @media (max-width: 768px) {
      .search-modal-overlay { padding-top: 0; align-items: stretch; }
      .search-modal-box { max-height: 100vh; border-radius: 0; }
    }

    /* ===== Header Login Button (未登录时显示) ===== */
    .header-login-btn {
      background: linear-gradient(135deg, rgba(142, 68, 173, 0.3), rgba(52, 152, 219, 0.25));
      border: 1px solid rgba(142, 68, 173, 0.4);
      color: var(--text);
      font-size: 12px;
      font-weight: 600;
      padding: 6px 16px;
      height: 36px;
      line-height: 22px;
      border-radius: 20px;
      cursor: pointer;
      display: inline-block;
      transition: all 0.2s;
    }
    .header-login-btn:hover { background: linear-gradient(135deg, rgba(142, 68, 173, 0.45), rgba(52, 152, 219, 0.35)); }
    .header-login-btn.hide { display: none; }

    /* ===== My Projects Button ===== */
    .my-projects-btn {
      background: rgba(142, 68, 173, 0.15);
      border: 1px solid rgba(142, 68, 173, 0.3);
      color: var(--text-muted);
      font-size: 12px;
      padding: 6px 14px;
      height: 36px;
      line-height: 22px;
      border-radius: 20px;
      cursor: pointer;
      display: none;
      transition: all 0.2s;
    }
    .my-projects-btn:hover { background: rgba(142, 68, 173, 0.25); color: var(--text); }
    .my-projects-btn.show { display: inline-block; }
    /* spec RP-01/02/03/04: admin/operator/tester/channel_operator 不可发布项目 → 隐藏"我的项目"入口 */
    body.admin-mode .my-projects-btn,
    body.operator-mode .my-projects-btn,
    body.tester-mode .my-projects-btn { display: none !important; }

    /* ===== My Projects Modal ===== */
    .my-projects-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 1200;
      align-items: flex-start;
      justify-content: center;
      padding: 40px 20px;
      overflow-y: auto;
    }
    .my-projects-overlay.show { display: flex; }
    .my-projects-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 28px;
      max-width: 800px;
      width: 100%;
      animation: modalIn 0.3s ease;
    }
    .my-projects-box .modal-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 20px;
    }
    .my-projects-box .modal-header h3 {
      font-size: 20px;
      font-weight: 800;
    }
    .my-projects-box .close-btn {
      width: 32px;
      height: 32px;
      border-radius: 50%;
      border: 1px solid var(--card-border);
      background: rgba(255,255,255,0.05);
      color: var(--text-muted);
      font-size: 18px;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
    }
    .my-projects-box .close-btn:hover {
      background: rgba(255,255,255,0.1);
      color: var(--text);
    }
    .my-projects-list {
      display: flex;
      flex-direction: column;
      gap: 12px;
    }
    .my-project-item {
      background: var(--card-bg);
      border: 1px solid var(--card-border);
      border-radius: 12px;
      padding: 16px;
      display: flex;
      align-items: center;
      gap: 16px;
      transition: transform 0.2s;
      cursor: pointer;
    }
    .my-project-item:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(108, 92, 231, 0.15);
    }
    .my-project-item .project-thumb {
      width: 80px;
      height: 50px;
      border-radius: 8px;
      object-fit: cover;
      flex-shrink: 0;
    }
    .my-project-item .project-info {
      flex: 1;
      min-width: 0;
    }
    .my-project-item .project-name {
      font-size: 15px;
      font-weight: 700;
      color: var(--text);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .my-project-item .project-category-badge {
      display: inline-block;
      font-size: 11px;
      padding: 2px 8px;
      border-radius: 6px;
      background: rgba(142, 68, 173, 0.2);
      color: var(--primary-light);
      margin-top: 4px;
    }
    .my-project-item .project-desc {
      font-size: 12px;
      color: var(--text-muted);
      margin-top: 4px;
      display: -webkit-box;
      -webkit-line-clamp: 1;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
    .my-project-item .project-actions {
      display: flex;
      gap: 6px;
      flex-shrink: 0;
    }
    .my-project-item .project-actions button {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      border-radius: 8px;
      border: none;
      cursor: pointer;
      font-size: 14px;
      transition: all 0.2s;
    }
    .my-project-item .project-actions .mp-edit-btn {
      background: rgba(52, 152, 219, 0.2);
      color: #3498db;
      border: 1px solid rgba(52, 152, 219, 0.3);
    }
    .my-project-item .project-actions .mp-edit-btn:hover { background: rgba(52, 152, 219, 0.4); }
    .my-project-item .project-actions .mp-delete-btn {
      background: rgba(231, 76, 60, 0.2);
      color: #e74c3c;
      border: 1px solid rgba(231, 76, 60, 0.3);
    }
    .my-project-item .project-actions .mp-delete-btn:hover { background: rgba(231, 76, 60, 0.4); }

    /* ===== CMS Modal ===== */
    .cms-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 1200;
      align-items: flex-start;
      justify-content: center;
      padding: 40px 20px;
      overflow-y: auto;
    }
    .cms-overlay.show { display: flex; }
    .cms-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 28px;
      max-width: 700px;
      width: 100%;
      animation: modalIn 0.3s ease;
    }
    .cms-box .modal-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 20px;
    }
    .cms-box .modal-header h3 { font-size: 20px; font-weight: 800; }

    /* CMS tabs */
    .cms-tabs {
      display: flex;
      gap: 4px;
      margin-bottom: 20px;
      background: rgba(255,255,255,0.04);
      border: 1px solid var(--card-border);
      border-radius: 12px;
      padding: 4px;
    }
    .cms-tab {
      flex: 1;
      padding: 8px 14px;
      border-radius: 9px;
      border: none;
      background: transparent;
      color: var(--text-muted);
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s;
    }
    .cms-tab.active {
      background: rgba(142, 68, 173, 0.3);
      color: #fff;
      border: 1px solid rgba(142, 68, 173, 0.4);
    }
    .cms-tab:hover:not(.active) { color: var(--text); background: rgba(255,255,255,0.06); }

    .cms-panel { display: none; }
    .cms-panel.active { display: block; }

    .cms-section-title {
      font-size: 15px;
      font-weight: 700;
      margin-bottom: 12px;
      color: var(--primary-light);
    }
    .channel-list {
      display: flex;
      flex-direction: column;
      gap: 8px;
      margin-bottom: 16px;
      max-height: 320px;
      overflow-y: auto;
    }
    .channel-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 10px 14px;
      background: var(--card-bg);
      border: 1px solid var(--card-border);
      border-radius: 10px;
      gap: 8px;
      flex-wrap: wrap;
    }
    .channel-item .channel-name {
      font-size: 14px;
      color: var(--text);
      flex: 1;
    }
    .channel-item .channel-edit-input {
      flex: 1;
      background: rgba(255,255,255,0.08);
      border: 1px solid rgba(142,68,173,0.4);
      border-radius: 6px;
      padding: 4px 8px;
      font-size: 13px;
      color: var(--text);
      outline: none;
      display: none;
    }
    .channel-item.editing .channel-name { display: none; }
    .channel-item.editing .channel-edit-input { display: block; }
    .channel-item-btns { display: flex; gap: 6px; flex-shrink: 0; }
    .channel-item .channel-edit-btn {
      background: rgba(52, 152, 219, 0.2);
      color: #3498db;
      border: 1px solid rgba(52, 152, 219, 0.3);
      border-radius: 6px;
      padding: 4px 10px;
      font-size: 12px;
      cursor: pointer;
      transition: all 0.2s;
    }
    .channel-item .channel-edit-btn:hover { background: rgba(52, 152, 219, 0.4); }
    .channel-item .channel-save-btn {
      background: rgba(46, 204, 113, 0.2);
      color: #2ecc71;
      border: 1px solid rgba(46, 204, 113, 0.3);
      border-radius: 6px;
      padding: 4px 10px;
      font-size: 12px;
      cursor: pointer;
      transition: all 0.2s;
      display: none;
    }
    .channel-item.editing .channel-save-btn { display: inline-block; }
    .channel-item.editing .channel-edit-btn { display: none; }
    .channel-item .channel-delete-btn {
      background: rgba(231, 76, 60, 0.2);
      color: #e74c3c;
      border: 1px solid rgba(231, 76, 60, 0.3);
      border-radius: 6px;
      padding: 4px 10px;
      font-size: 12px;
      cursor: pointer;
      transition: all 0.2s;
    }
    .channel-item .channel-delete-btn:hover { background: rgba(231, 76, 60, 0.4); }
    .channel-add-row {
      display: flex;
      gap: 8px;
      margin-top: 8px;
    }
    .channel-add-row .form-input {
      flex: 1;
    }
    .channel-add-row .btn-add {
      padding: 8px 18px;
      background: var(--gradient-1);
      color: #fff;
      border: none;
      border-radius: 10px;
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
    }

    /* CMS Status tab */
    .cms-channel-selector {
      display: flex;
      gap: 6px;
      flex-wrap: wrap;
      margin-bottom: 16px;
    }
    .cms-channel-tab {
      padding: 6px 14px;
      border-radius: 20px;
      border: 1px solid var(--card-border);
      background: transparent;
      color: var(--text-muted);
      font-size: 12px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s;
    }
    .cms-channel-tab.active {
      background: rgba(142, 68, 173, 0.3);
      border-color: rgba(142, 68, 173, 0.5);
      color: #fff;
    }
    .cms-channel-tab:hover:not(.active) { color: var(--text); border-color: rgba(255,255,255,0.2); }
    .cms-status-list {
      display: flex;
      flex-direction: column;
      gap: 8px;
      margin-bottom: 16px;
      max-height: 450px;
      overflow-y: auto;
    }
    .cms-status-item {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 8px 14px;
      background: var(--card-bg);
      border: 1px solid var(--card-border);
      border-radius: 10px;
      transition: border-color 0.2s;
    }
    .cms-status-item .status-name {
      flex: 1;
      font-size: 13px;
      color: var(--text);
    }
    .cms-status-item .status-delete-btn {
      background: rgba(231, 76, 60, 0.2);
      color: #e74c3c;
      border: 1px solid rgba(231, 76, 60, 0.3);
      border-radius: 6px;
      padding: 3px 8px;
      font-size: 12px;
      cursor: pointer;
      transition: all 0.2s;
    }
    .cms-status-item .status-delete-btn:hover { background: rgba(231, 76, 60, 0.4); }
    .cms-status-add-row {
      display: flex;
      gap: 8px;
      margin-top: 8px;
    }
    .cms-status-add-row .form-input { flex: 1; }
    .cms-status-add-row .btn-add {
      padding: 8px 18px;
      background: var(--gradient-1);
      color: #fff;
      border: none;
      border-radius: 10px;
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
    }

    /* Channel multi-select for project edit (admin mode) */
    .channel-multi-select {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-top: 8px;
    }
    .channel-check-item {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      padding: 6px 14px;
      border: 1px solid var(--card-border);
      border-radius: 8px;
      cursor: pointer;
      font-size: 13px;
      color: var(--text-muted);
      transition: all 0.2s;
      user-select: none;
    }
    .channel-check-item.checked {
      background: rgba(142, 68, 173, 0.2);
      border-color: rgba(142, 68, 173, 0.5);
      color: var(--primary-light);
    }
    .channel-check-item:hover {
      background: rgba(255,255,255,0.05);
    }

    .skill-empty {
      text-align: center;
      padding: 60px 20px;
      color: var(--text-muted);
      font-size: 15px;
    }

    /* ===== Upload Type Selector Modal ===== */
    .upload-type-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0, 0, 0, 0.7);
      backdrop-filter: blur(4px);
      z-index: 1000;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .upload-type-overlay.show { display: flex; }
    .upload-type-box {
      background: #1a1a35;
      border: 1px solid var(--card-border);
      border-radius: 20px;
      padding: 32px;
      max-width: 380px;
      width: 100%;
      text-align: center;
      animation: modalIn 0.3s ease;
    }
    .upload-type-box h3 {
      font-size: 20px;
      font-weight: 800;
      margin-bottom: 24px;
    }
    .upload-type-btns {
      display: flex;
      flex-direction: column;
      gap: 14px;
    }
    .upload-type-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;
      padding: 16px 24px;
      border-radius: 14px;
      font-size: 16px;
      font-weight: 700;
      cursor: pointer;
      transition: all 0.2s;
      border: 1px solid var(--card-border);
      background: rgba(255,255,255,0.03);
      color: var(--text);
    }
    .upload-type-btn:hover {
      background: rgba(142, 68, 173, 0.15);
      border-color: rgba(142, 68, 173, 0.4);
      transform: translateY(-2px);
      box-shadow: 0 8px 20px rgba(142, 68, 173, 0.2);
    }
    .upload-type-btn .type-icon { font-size: 24px; }

    /* Skill upload form specific */
    .skill-file-upload-area {
      border: 2px dashed var(--card-border);
      border-radius: 12px;
      padding: 32px;
      text-align: center;
      cursor: pointer;
      transition: all 0.2s;
      color: var(--text-muted);
      font-size: 14px;
      position: relative;
    }
    .skill-file-upload-area:hover {
      border-color: var(--primary);
      background: rgba(108, 92, 231, 0.05);
    }
    .skill-file-upload-area.has-file {
      border-color: #2ecc71;
      background: rgba(46, 204, 113, 0.05);
    }
    .skill-file-info {
      display: none;
      font-size: 14px;
      color: #2ecc71;
      font-weight: 600;
    }
    .skill-file-upload-area.has-file .skill-file-info { display: block; }
    .skill-file-upload-area.has-file .skill-file-placeholder { display: none; }

    @media (max-width: 768px) {
      /* 2026-04-24 buglist #19: primary-tabs 宽度限制为屏幕宽度, 防止横向溢出到屏幕外 */
      .primary-tabs {
        gap: 8px;
        bottom: 52px;
        max-width: calc(100vw - 24px);
        width: auto;
        padding: 0 12px;
        box-sizing: border-box;
        flex-wrap: nowrap;
        justify-content: center;
      }
      .primary-tab { padding: 8px 12px; font-size: 12px; border-radius: 12px; white-space: nowrap; flex-shrink: 1; min-width: 0; }
      .primary-tab-label { overflow: hidden; text-overflow: ellipsis; }
      .skill-item { padding: 14px 16px; flex-wrap: wrap; }
      .skill-actions { width: 100%; justify-content: flex-end; margin-top: 8px; }
      .search-bar-container { display: none; } /* prd4ai-009: 老 hero 搜索栏已下线，保留兼容选择器防止样式冲突 */
      .search-bar-input { font-size: 13px; padding: 8px 32px 8px 36px; }
      .header-login-btn { font-size: 11px; padding: 5px 12px; }
      /* 2026-04-24 buglist #37: 手机H5 我的项目按钮图标居中, 用 inline-flex 替代 inline-block
         (原 inline-block 下 justify-content 无效, SVG 贴左边)
         2026-04-27 bugfix: 基础样式 (L1662) 给 .my-projects-btn svg[data-lucide] 统一留了
         margin-right: 6px 用于与文字之间留白; H5 下文字被隐藏 (.btn-text { display:none })
         且按钮宽度固定 32px, 这 6px margin 会把 SVG 挤向左侧导致视觉不居中 → 此处显式重置 */
      .my-projects-btn { font-size: 0; width: 32px; height: 32px; padding: 0; border-radius: 50%; justify-content: center; align-items: center; gap: 0; }
      .my-projects-btn.show { display: inline-flex; }
      .my-projects-btn svg[data-lucide] { width: 16px; height: 16px; margin-right: 0; margin-left: 0; }
      .deploy-tool-btn { font-size: 0; width: 32px; height: 32px; padding: 0; border-radius: 50%; justify-content: center; }
      .deploy-tool-btn svg[data-lucide] { width: 16px; height: 16px; margin-right: 0; margin-left: 0; }
      .notif-bell-btn { }
      /* PRD4AI-007 buglist #8: H5 下只改变 width，不要覆写 right，否则 .notif-panel 默认的 right: -360px 被覆盖会自动弹出 */
      .notif-panel { width: calc(100vw - 24px); max-width: 380px; right: calc(-100vw + 24px); }
      .notif-panel.show { right: 12px; }
      /* 2026-04-24 buglist #34: 手机H5 展示通知中心返回按钮 */
      .notif-back-btn { display: inline-flex; }
      .user-badge { font-size: 11px; padding: 5px 10px; }
      /* 2026-04-24 buglist #52: 手机端退出登录按钮在未登录时也可见 — 基础样式保持 display:none，仅 .show 时展示 */
      .user-logout-btn { font-size: 0; width: 32px; height: 32px; padding: 0; border-radius: 50%; justify-content: center; align-items: center; gap: 0; }
      .user-logout-btn.show { display: inline-flex; }
      .user-logout-btn svg[data-lucide] { width: 16px; height: 16px; }
      /* 2026-04-24 buglist #18: 手机端顶栏按钮过多, 只保留图标隐藏文案, 保持 PC 展示不变 */
      .my-projects-btn .btn-text,
      .user-logout-btn .btn-text { display: none; }

      /* 2026-04-24 buglist #36: 用户反馈列表手机H5 表格转卡片 */
      #feedbackPageOverlay > div { padding: 16px 12px !important; }
      #feedbackPageOverlay h2 { font-size: 16px !important; }
      #feedbackChannelIdBanner { font-size: 12px !important; word-break: break-all; }
      .feedback-list-wrap { overflow-x: visible; }
      .feedback-table,
      .feedback-table thead,
      .feedback-table tbody,
      .feedback-table tr,
      .feedback-table td {
        display: block;
        width: 100% !important;
      }
      .feedback-table thead { display: none; }
      .feedback-table tr {
        background: rgba(255,255,255,0.04);
        border: 1px solid rgba(255,255,255,0.08) !important;
        border-radius: 12px;
        padding: 12px 14px;
        margin-bottom: 12px;
      }
      .feedback-table td {
        padding: 6px 0 !important;
        border: none !important;
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        gap: 12px;
        font-size: 13px;
        width: auto !important;
      }
      .feedback-table td::before {
        content: attr(data-label);
        flex-shrink: 0;
        min-width: 64px;
        color: var(--text-muted);
        font-weight: 600;
        font-size: 12px;
      }
      .feedback-table td[data-label="反馈描述"] {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
        padding-bottom: 10px !important;
        border-bottom: 1px dashed rgba(255,255,255,0.08) !important;
        margin-bottom: 6px;
      }
      .feedback-table td[data-label="反馈描述"]::before { min-width: 0; }
      .feedback-table td[data-label="操作"] { justify-content: flex-end; }
      .feedback-table td[data-label="操作"]::before { display: none; }
    }

    /* ===== Rankings Modal (REQ-004) ===== */
    .ranking-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.75);
      backdrop-filter: blur(6px);
      z-index: 1500;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .ranking-overlay.show { display: flex; }
    .ranking-modal {
      background: var(--card-bg);
      border-radius: 20px;
      width: 100%;
      max-width: 640px;
      max-height: 85vh;
      display: flex;
      flex-direction: column;
      box-shadow: 0 24px 80px rgba(0,0,0,0.5);
      border: 1px solid rgba(255,255,255,0.08);
      overflow: hidden;
      animation: modalSlideIn 0.3s ease;
    }
    @keyframes modalSlideIn {
      from { transform: translateY(30px); opacity: 0; }
      to { transform: translateY(0); opacity: 1; }
    }
    .ranking-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 20px 24px 12px;
      border-bottom: 1px solid rgba(255,255,255,0.06);
    }
    .ranking-header h2 {
      font-size: 20px;
      font-weight: 700;
      background: linear-gradient(135deg, #f39c12, #e74c3c);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      margin: 0;
    }
    .ranking-close-btn {
      background: rgba(255,255,255,0.08);
      border: none;
      color: var(--text-muted);
      font-size: 20px;
      width: 36px;
      height: 36px;
      border-radius: 50%;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.2s;
    }
    .ranking-close-btn:hover { background: rgba(255,255,255,0.15); color: #fff; }
    .ranking-cats {
      display: flex;
      gap: 8px;
      padding: 12px 24px;
      overflow-x: auto;
      flex-shrink: 0;
    }
    .ranking-cat-chip {
      padding: 6px 16px;
      border-radius: 20px;
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
      background: rgba(255,255,255,0.06);
      color: var(--text-muted);
      border: 1px solid rgba(255,255,255,0.08);
      transition: all 0.2s;
    }
    .ranking-cat-chip:hover { background: rgba(255,255,255,0.1); color: #fff; }
    .ranking-cat-chip.active {
      background: linear-gradient(135deg, rgba(142,68,173,0.4), rgba(52,152,219,0.3));
      color: #fff;
      border-color: rgba(142,68,173,0.5);
    }
    .ranking-dims {
      display: flex;
      gap: 0;
      padding: 0 24px 12px;
      border-bottom: 1px solid rgba(255,255,255,0.06);
    }
    .ranking-dim-tab {
      padding: 8px 20px;
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      color: var(--text-muted);
      border-bottom: 2px solid transparent;
      transition: all 0.2s;
    }
    .ranking-dim-tab:hover { color: #fff; }
    .ranking-dim-tab.active {
      color: #fff;
      border-bottom-color: var(--primary);
    }
    .ranking-list {
      flex: 1;
      overflow-y: auto;
      padding: 8px 0;
    }
    .ranking-item {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 12px 24px;
      cursor: pointer;
      transition: background 0.15s;
    }
    .ranking-item:hover { background: rgba(255,255,255,0.04); }
    .ranking-rank {
      width: 28px;
      height: 28px;
      border-radius: 8px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 13px;
      font-weight: 700;
      flex-shrink: 0;
      background: rgba(255,255,255,0.06);
      color: var(--text-muted);
    }
    .ranking-rank.top1 { background: linear-gradient(135deg, #f39c12, #e67e22); color: #fff; }
    .ranking-rank.top2 { background: linear-gradient(135deg, #bdc3c7, #95a5a6); color: #fff; }
    .ranking-rank.top3 { background: linear-gradient(135deg, #e67e22, #d35400); color: #fff; }
    .ranking-icon {
      width: 40px;
      height: 40px;
      border-radius: 10px;
      object-fit: cover;
      background: rgba(255,255,255,0.06);
      flex-shrink: 0;
    }
    .ranking-info {
      flex: 1;
      min-width: 0;
    }
    .ranking-name {
      font-size: 14px;
      font-weight: 600;
      color: #fff;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .ranking-meta {
      font-size: 11px;
      color: var(--text-muted);
      margin-top: 2px;
    }
    .ranking-metric {
      font-size: 13px;
      font-weight: 600;
      color: var(--primary-light);
      flex-shrink: 0;
      white-space: nowrap;
    }
    .ranking-empty {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 60px 24px;
      color: var(--text-muted);
      font-size: 14px;
    }

    /* ===== CMS Monthly Rankings Panel ===== */
    .monthly-ranking-panel {
      padding: 20px;
    }
    .monthly-ranking-months {
      display: flex;
      gap: 8px;
      overflow-x: auto;
      padding-bottom: 12px;
      margin-bottom: 16px;
      border-bottom: 1px solid rgba(255,255,255,0.06);
    }
    .monthly-ranking-month-chip {
      padding: 6px 14px;
      border-radius: 16px;
      font-size: 12px;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
      background: rgba(255,255,255,0.06);
      color: var(--text-muted);
      border: 1px solid rgba(255,255,255,0.08);
      transition: all 0.2s;
    }
    .monthly-ranking-month-chip:hover { background: rgba(255,255,255,0.1); color: #fff; }
    .monthly-ranking-month-chip.active {
      background: linear-gradient(135deg, rgba(142,68,173,0.4), rgba(52,152,219,0.3));
      color: #fff;
      border-color: rgba(142,68,173,0.5);
    }
    .monthly-ranking-list {
      max-height: 400px;
      overflow-y: auto;
    }
    .monthly-ranking-item {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 10px 0;
      border-bottom: 1px solid rgba(255,255,255,0.04);
    }
    .monthly-ranking-item:last-child { border-bottom: none; }

    /* ===== Project Detail Modal (REQ-002) ===== */
    .proj-detail-overlay {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      background: rgba(0,0,0,0.75);
      backdrop-filter: blur(6px);
      z-index: 1500;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .proj-detail-overlay.show { display: flex; }
    .proj-detail-box {
      background: #1a1a35;
      border: 1px solid rgba(255,255,255,0.12);
      border-radius: 20px;
      width: 100%;
      max-width: 780px;
      max-height: 90vh;
      overflow-y: auto;
      /* 2026-04-24 buglist #31: 禁掉横向滚动, 任何子元素意外撑宽都不会让详情弹窗可以左右滑动 */
      overflow-x: hidden;
      animation: modalIn 0.3s ease;
      position: relative;
    }
    .proj-detail-header {
      position: relative;
      height: 220px;
      overflow: hidden;
      border-radius: 20px 20px 0 0;
      flex-shrink: 0;
    }
    /* PRD4AI-007 buglist #2: 封面图通过 cover 铺满整个 header，底部用 blur 背景做色彩延展填充 */
    .proj-detail-bg {
      position: absolute;
      top: -30px; left: -30px;
      width: calc(100% + 60px);
      height: calc(100% + 60px);
      object-fit: cover;
      filter: blur(28px) saturate(1.3);
      transform: scale(1.1);
      pointer-events: none;
      z-index: 0;
    }
    .proj-detail-screenshot {
      position: absolute;
      top: 0; left: 0;
      width: 100%; height: 100%;
      object-fit: contain;
      z-index: 1;
    }
    /* PRD4AI-007 buglist #2: 封面图前景层 - 居中 contain，被模糊背景填充环绕 */
    .proj-detail-cover {
      position: absolute;
      top: 0; left: 0;
      width: 100%; height: 100%;
      object-fit: contain;
      z-index: 2;
      pointer-events: none;
    }
    .proj-detail-close {
      position: absolute;
      top: 12px; right: 12px;
      width: 32px; height: 32px;
      border-radius: 50%;
      border: none;
      background: rgba(0,0,0,0.5);
      color: #fff;
      font-size: 18px;
      cursor: pointer;
      z-index: 10;
      display: flex; align-items: center; justify-content: center;
      transition: background 0.2s;
      backdrop-filter: blur(8px);
    }
    .proj-detail-close:hover { background: rgba(0,0,0,0.8); }
    .proj-detail-body {
      padding: 20px 32px 28px;
    }
    .proj-detail-title {
      font-size: 22px;
      font-weight: 800;
      margin-bottom: 6px;
      background: linear-gradient(135deg, #f093fb, #f5576c, #ffd47a);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
    }
    .proj-detail-meta {
      display: flex;
      align-items: center;
      gap: 12px;
      font-size: 13px;
      color: var(--text-muted);
      margin-bottom: 12px;
      flex-wrap: wrap;
    }
    .proj-detail-desc {
      font-size: 14px;
      color: var(--text-muted);
      line-height: 1.7;
      margin-bottom: 16px;
    }
    .proj-detail-actions {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      margin-bottom: 16px;
    }
    .proj-detail-open-btn {
      padding: 10px 24px;
      border-radius: 12px;
      border: none;
      background: var(--gradient-1);
      color: #fff;
      font-size: 14px;
      font-weight: 700;
      cursor: pointer;
      transition: opacity 0.2s;
    }
    .proj-detail-open-btn:hover { opacity: 0.85; }

    /* H5 ActionSheet — 打开项目按钮列表 */
    .h5-action-sheet-overlay {
      display: none;
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.5);
      z-index: 3000;
      opacity: 0;
      transition: opacity 0.25s ease;
    }
    .h5-action-sheet-overlay.show {
      display: flex;
      align-items: flex-end;
      justify-content: center;
      opacity: 1;
    }
    .h5-action-sheet {
      width: 100%;
      max-width: 420px;
      max-height: 50vh;
      background: #1e1e2e;
      border-radius: 16px 16px 0 0;
      padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px));
      overflow-y: auto;
      transform: translateY(100%);
      transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
    }
    .h5-action-sheet-overlay.show .h5-action-sheet {
      transform: translateY(0);
    }
    .h5-action-sheet-title {
      font-size: 13px;
      color: #999;
      text-align: center;
      margin-bottom: 12px;
    }
    .h5-action-sheet-item {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
      width: 100%;
      padding: 14px 16px;
      border: none;
      border-radius: 12px;
      font-size: 15px;
      font-weight: 600;
      cursor: pointer;
      margin-bottom: 8px;
      transition: opacity 0.15s;
    }
    .h5-action-sheet-item:active { opacity: 0.7; }
    .h5-action-sheet-item.primary {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: #fff;
    }
    .h5-action-sheet-item.secondary {
      background: rgba(255,255,255,0.08);
      color: #eee;
      border: 1px solid rgba(255,255,255,0.12);
    }
    .h5-action-sheet-cancel {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      padding: 14px 16px;
      border: none;
      border-radius: 12px;
      font-size: 15px;
      font-weight: 500;
      cursor: pointer;
      margin-top: 4px;
      background: rgba(255,255,255,0.05);
      color: #999;
    }
    .h5-action-sheet-cancel:active { opacity: 0.7; }
    .proj-detail-qr-btn,
    .proj-detail-share-btn {
      padding: 10px 18px;
      border-radius: 12px;
      border: 1px solid rgba(255,255,255,0.15);
      background: rgba(255,255,255,0.06);
      color: var(--text);
      font-size: 14px;
      cursor: pointer;
      transition: all 0.2s;
      display: flex; align-items: center; gap: 6px;
    }
    .proj-detail-qr-btn:hover { border-color: #3498db; color: #3498db; background: rgba(52,152,219,0.1); }
    .proj-detail-share-btn:hover { border-color: #2ecc71; color: #2ecc71; background: rgba(46,204,113,0.1); }
    /* 央视频二维码按钮（V6.x 起仅渠道分发页 YSP 渠道使用；主站项目详情按钮已删除） */
    .ysp-qr-btn {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 7px 14px;
      border-radius: 10px;
      border: none;
      cursor: pointer;
      font-size: 12px;
      font-weight: 600;
      color: #fff;
      background: linear-gradient(135deg, #e74c3c, #c0392b);
      box-shadow: 0 2px 8px rgba(231,76,60,0.3);
      transition: transform 0.15s, box-shadow 0.15s;
    }
    .ysp-qr-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(231,76,60,0.45); }
    .proj-detail-like-btn {
      padding: 10px 18px;
      border-radius: 12px;
      border: 1px solid rgba(255,255,255,0.15);
      background: rgba(255,255,255,0.06);
      color: var(--text);
      font-size: 14px;
      cursor: pointer;
      transition: all 0.2s;
      display: flex; align-items: center; gap: 6px;
      margin-left: auto;
    }
    .proj-detail-like-btn:hover { border-color: #e74c3c; color: #e74c3c; }
    .proj-detail-like-btn.liked { border-color: #e74c3c; color: #e74c3c; background: rgba(231,76,60,0.12); }
    /* Channel assignment section in detail modal (admin only) */
    .proj-detail-channels {
      display: none;
      margin-top: 16px;
      padding-top: 16px;
      border-top: 1px solid rgba(255,255,255,0.07);
    }
    body.admin-mode .proj-detail-channels { display: block; }
    body.operator-mode .proj-detail-channels { display: block; }
    /* url_json read-only display section (admin/operator only) */
    .proj-detail-url-json {
      display: none;
      margin-top: 16px;
      padding-top: 16px;
      border-top: 1px solid rgba(255,255,255,0.07);
    }
    body.admin-mode .proj-detail-url-json { display: block; }
    body.operator-mode .proj-detail-url-json { display: block; }
    /* URL 可用性状态徽标 */
    .url-avail-badge {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      font-size: 10px;
      padding: 2px 6px;
      border-radius: 8px;
      font-weight: 600;
      vertical-align: middle;
      margin-left: 6px;
    }
    .url-avail-badge.available { background: rgba(46,204,113,0.15); color: #2ecc71; }
    .url-avail-badge.unavailable { background: rgba(231,76,60,0.15); color: #e74c3c; }
    .url-avail-badge.override { border: 1px dashed rgba(241,196,15,0.5); }
    .url-avail-badge .avail-dot {
      width: 6px; height: 6px; border-radius: 50%; display: inline-block;
    }
    .url-avail-badge.available .avail-dot { background: #2ecc71; }
    .url-avail-badge.unavailable .avail-dot { background: #e74c3c; }
    /* 管理员/运营可用性操作控件 */
    .url-override-controls {
      display: none;
      align-items: center;
      gap: 6px;
      margin-top: 4px;
    }
    body.admin-mode .url-override-controls,
    body.operator-mode .url-override-controls { display: flex; }
    .url-override-toggle {
      -webkit-appearance: none;
      appearance: none;
      width: 32px; height: 18px;
      background: rgba(255,255,255,0.1);
      border-radius: 9px;
      position: relative;
      cursor: pointer;
      transition: background 0.2s;
      border: none;
      outline: none;
      flex-shrink: 0;
    }
    .url-override-toggle:checked { background: #2ecc71; }
    .url-override-toggle::before {
      content: '';
      position: absolute;
      width: 14px; height: 14px;
      border-radius: 50%;
      background: white;
      top: 2px; left: 2px;
      transition: transform 0.2s;
    }
    .url-override-toggle:checked::before { transform: translateX(14px); }
    .url-override-label { font-size: 10px; color: var(--text-muted); user-select: none; }
    .url-override-release {
      font-size: 10px;
      color: #f1c40f;
      cursor: pointer;
      opacity: 0.7;
      background: none;
      border: none;
      padding: 0;
      font-family: inherit;
    }
    .url-override-release:hover { opacity: 1; }
    .proj-detail-channels-title {
      font-size: 13px;
      font-weight: 700;
      color: var(--text-muted);
      margin-bottom: 10px;
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }
    .proj-detail-channel-row {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 8px 12px;
      background: rgba(255,255,255,0.04);
      border-radius: 10px;
      margin-bottom: 6px;
      flex-wrap: wrap;
    }
    .proj-detail-channel-name {
      font-size: 13px;
      font-weight: 600;
      color: var(--text);
      flex: 1;
      min-width: 80px;
    }
    .proj-detail-channel-status-select {
      background: rgba(255,255,255,0.08);
      border: 1px solid rgba(255,255,255,0.15);
      border-radius: 8px;
      color: var(--text);
      font-size: 12px;
      padding: 4px 8px;
      cursor: pointer;
      transition: border-color 0.2s;
      font-family: var(--font-body);
    }
    .proj-detail-channel-status-select:focus { outline: none; border-color: var(--primary); }
    .proj-channel-check-toggle {
      width: 20px; height: 20px;
      border-radius: 6px;
      border: 1px solid rgba(255,255,255,0.2);
      background: transparent;
      cursor: pointer;
      display: flex; align-items: center; justify-content: center;
      font-size: 11px;
      transition: all 0.2s;
      flex-shrink: 0;
    }
    .proj-channel-check-toggle.on { background: rgba(46,204,113,0.2); border-color: #2ecc71; color: #2ecc71; }
    .proj-channel-check-toggle:hover { border-color: var(--primary); }

    /* ===== REQ-003: Comment Preview Section ===== */
    .comment-preview-section {
      margin-top: 16px;
      padding-top: 16px;
      border-top: 1px solid rgba(255,255,255,0.07);
    }
    .comment-preview-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 12px;
    }
    .comment-preview-title {
      font-size: 13px;
      font-weight: 700;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: 0.5px;
    }
    .comment-view-all-btn {
      font-size: 12px;
      color: var(--primary);
      background: none;
      border: none;
      cursor: pointer;
      padding: 2px 6px;
      border-radius: 6px;
      transition: background 0.2s;
    }
    .comment-view-all-btn:hover { background: rgba(142,68,173,0.15); }
    .comment-preview-list {
      display: flex;
      flex-direction: column;
      gap: 8px;
      margin-bottom: 12px;
    }
    .comment-preview-item {
      display: flex;
      gap: 8px;
      align-items: flex-start;
    }
    .comment-avatar {
      width: 28px; height: 28px;
      border-radius: 50%;
      background: linear-gradient(135deg, var(--primary), #3498db);
      display: flex; align-items: center; justify-content: center;
      font-size: 12px;
      font-weight: 700;
      color: #fff;
      flex-shrink: 0;
    }
    .comment-preview-content {
      flex: 1;
      min-width: 0;
    }
    .comment-preview-author {
      font-size: 12px;
      font-weight: 600;
      color: var(--text);
      margin-bottom: 2px;
    }
    .comment-preview-text {
      font-size: 12px;
      color: var(--text-muted);
      line-height: 1.5;
      word-break: break-word;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
    .comment-preview-time {
      font-size: 11px;
      color: rgba(255,255,255,0.3);
      margin-top: 2px;
    }
    .comment-empty-hint {
      font-size: 12px;
      color: rgba(255,255,255,0.25);
      text-align: center;
      padding: 8px 0;
    }
    .comment-input-row {
      display: flex;
      gap: 8px;
      align-items: center;
    }
    .comment-input {
      flex: 1;
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 10px;
      padding: 8px 12px;
      font-size: 13px;
      color: var(--text);
      font-family: var(--font-body);
      resize: none;
      transition: border-color 0.2s;
      height: 36px;
      line-height: 20px;
    }
    .comment-input:focus { outline: none; border-color: var(--primary); }
    .comment-input::placeholder { color: rgba(255,255,255,0.25); }
    .comment-img-btn {
      width: 36px; height: 36px;
      border-radius: 10px;
      border: 1px solid rgba(255,255,255,0.1);
      background: rgba(255,255,255,0.06);
      color: var(--text-muted);
      cursor: pointer;
      display: flex; align-items: center; justify-content: center;
      font-size: 16px;
      flex-shrink: 0;
      transition: all 0.2s;
    }
    .comment-img-btn:hover { border-color: var(--primary); color: var(--primary); }
    .comment-img-preview {
      margin-top: 6px;
      position: relative;
      display: inline-block;
      /* 2026-04-23 (20260423 Bug #1): 避免父级 overflow:hidden 裁掉 remove 按钮 */
      overflow: visible;
    }
    .comment-img-preview img {
      max-width: 120px; max-height: 80px;
      border-radius: 8px;
      border: 1px solid rgba(255,255,255,0.1);
    }
    .comment-img-preview .remove-img {
      /* 2026-04-23 (20260423 Bug #1): 按钮从"外飘"(-6px/-6px)改为"内贴角", 避免被 iOS Safari 父级裁切 */
      position: absolute; top: 4px; right: 4px;
      width: 22px; height: 22px;
      border-radius: 50%;
      background: rgba(231, 76, 60, 0.92);
      color: #fff;
      border: 1px solid rgba(255,255,255,0.35);
      font-size: 14px;
      cursor: pointer;
      display: flex; align-items: center; justify-content: center;
      /* 2026-04-23 buglist #15: 防止被外层 overflow 裁切, 保证删除按钮在右上角始终可见 */
      z-index: 2;
      line-height: 1;
      padding: 0;
      box-shadow: 0 2px 8px rgba(0,0,0,0.4);
    }
    /* 2026-04-23 buglist #15 + 2026-04-24 buglist #22: 全部评论弹窗内的图片预览
       - 与输入框左对齐 (margin 与 footer padding 对齐)
       - flex 子项时不要被 stretch 成全宽, align-self:flex-start 让容器宽度等于图片
       - 放在输入框下方 (footer 后) */
    .comment-img-preview-panel {
      margin: 8px 16px 12px;
      padding: 0;
      /* 确保 remove 按钮不会被容器裁掉 */
      overflow: visible;
      /* .comment-full-panel 是 display:flex; flex-direction:column, 默认 stretch 子项全宽.
         这里强制 align-self:flex-start, 同时用 inline-block 的紧凑宽度. */
      align-self: flex-start;
      width: auto;
      max-width: 140px;
    }
    .comment-img-preview-panel img {
      max-width: 120px;
      max-height: 90px;
      border-radius: 10px;
      border: 1px solid rgba(255,255,255,0.12);
      display: block;
    }
    .comment-content-img { max-width: 200px; max-height: 150px; border-radius: 8px; margin-top: 4px; cursor: pointer; }
    .comment-send-btn {
      padding: 8px 16px;
      border-radius: 10px;
      border: none;
      background: var(--gradient-1);
      color: #fff;
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      transition: opacity 0.2s;
      white-space: nowrap;
    }
    .comment-send-btn:hover { opacity: 0.85; }
    .comment-send-btn:disabled { opacity: 0.45; cursor: not-allowed; }

    /* ===== REQ-003: Full Comment Panel ===== */
    .comment-panel-overlay {
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      z-index: 1600;
      display: none;
      align-items: center;
      justify-content: center;
      background: transparent;
      pointer-events: none;
      padding: 20px;
    }
    .comment-panel-overlay.show { display: flex; }
    .comment-panel-inner {
      display: flex;
      gap: 16px;
      width: 100%;
      max-width: 1040px;
      max-height: 90vh;
      align-items: flex-start;
      justify-content: flex-end;
      pointer-events: none;
    }
    /* When comment panel is open, shift the detail modal left and show both side by side */
    .proj-detail-overlay.comment-open,
    .skill-detail-overlay.comment-open {
      justify-content: center;
    }
    /* 2026-04-24 buglist #21: 评论面板打开时, 把详情弹窗的遮罩(黑底+模糊)透明化,
       这样视觉上"没有遮罩盖住详情弹窗", 详情卡片与评论面板并列展示 */
    .proj-detail-overlay.comment-open,
    .skill-detail-overlay.comment-open {
      background: transparent !important;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      pointer-events: none;
    }
    .proj-detail-overlay.comment-open .proj-detail-box,
    .skill-detail-overlay.comment-open .skill-detail-box {
      pointer-events: auto;
      transform: translateX(-240px);
      transition: transform 0.35s cubic-bezier(0.22,1,0.36,1);
    }
    /* Position comment panel fixed to the right side of the shifted detail modal */
    .comment-panel-overlay {
      pointer-events: none;
    }
    .comment-panel-overlay.show {
      pointer-events: none;
    }
    .comment-full-panel {
      position: fixed;
      top: 50%;
      left: calc(50% + 158px);
      transform: translateY(-50%);
      width: 420px;
      min-width: 320px;
      max-height: 85vh;
      background: #1a1a35;
      border: 1px solid rgba(255,255,255,0.12);
      border-radius: 20px;
      display: flex;
      flex-direction: column;
      animation: slideInRight 0.35s cubic-bezier(0.22,1,0.36,1);
      overflow: hidden;
      pointer-events: auto;
      box-shadow: 0 8px 32px rgba(0,0,0,0.5);
      z-index: 1650;
    }
    @keyframes slideInRight {
      from { opacity: 0; transform: translateX(60px); }
      to { opacity: 1; transform: translateX(0); }
    }
    .comment-panel-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 16px 20px 12px;
      border-bottom: 1px solid rgba(255,255,255,0.07);
      flex-shrink: 0;
    }
    .comment-panel-title {
      font-size: 15px;
      font-weight: 700;
      color: var(--text);
    }
    .comment-panel-close {
      width: 28px; height: 28px;
      border-radius: 50%;
      border: none;
      background: rgba(255,255,255,0.08);
      color: var(--text);
      font-size: 16px;
      cursor: pointer;
      display: flex; align-items: center; justify-content: center;
      transition: background 0.2s;
    }
    .comment-panel-close:hover { background: rgba(255,255,255,0.15); }
    .comment-panel-list {
      flex: 1;
      overflow-y: auto;
      padding: 12px 16px;
      display: flex;
      flex-direction: column;
      gap: 12px;
    }
    .comment-panel-list::-webkit-scrollbar { width: 4px; }
    .comment-panel-list::-webkit-scrollbar-track { background: transparent; }
    .comment-panel-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 2px; }
    .comment-full-item {
      display: flex;
      gap: 10px;
      align-items: flex-start;
    }
    .comment-full-body {
      flex: 1;
      min-width: 0;
    }
    .comment-full-author-row {
      display: flex;
      align-items: center;
      gap: 8px;
      margin-bottom: 4px;
    }
    .comment-full-author {
      font-size: 13px;
      font-weight: 600;
      color: var(--text);
    }
    .comment-full-time {
      font-size: 11px;
      color: rgba(255,255,255,0.3);
      margin-left: auto;
    }
    .comment-full-text {
      font-size: 13px;
      color: var(--text-muted);
      line-height: 1.6;
      word-break: break-word;
    }
    .comment-full-actions {
      display: flex;
      gap: 8px;
      margin-top: 6px;
    }
    .comment-reply-btn,
    .comment-delete-btn {
      font-size: 11px;
      background: none;
      border: none;
      cursor: pointer;
      padding: 2px 6px;
      border-radius: 5px;
      transition: background 0.2s;
    }
    .comment-reply-btn { color: var(--primary); }
    .comment-reply-btn:hover { background: rgba(142,68,173,0.15); }
    .comment-delete-btn { color: #e74c3c; }
    .comment-delete-btn:hover { background: rgba(231,76,60,0.12); }
    .comment-replies {
      margin-top: 8px;
      padding-left: 38px;
      display: flex;
      flex-direction: column;
      gap: 8px;
    }
    .comment-reply-item {
      display: flex;
      gap: 8px;
      background: rgba(255,255,255,0.03);
      border-radius: 10px;
      padding: 8px 10px;
    }
    .reply-avatar {
      width: 22px; height: 22px;
      border-radius: 50%;
      background: linear-gradient(135deg, #3498db, #9b59b6);
      display: flex; align-items: center; justify-content: center;
      font-size: 10px;
      font-weight: 700;
      color: #fff;
      flex-shrink: 0;
    }
    .reply-body { flex: 1; min-width: 0; }
    .reply-author-row {
      display: flex;
      align-items: center;
      gap: 6px;
      margin-bottom: 3px;
    }
    .reply-author { font-size: 12px; font-weight: 600; color: var(--text); }
    .reply-time { font-size: 11px; color: rgba(255,255,255,0.3); margin-left: auto; }
    .reply-text { font-size: 12px; color: var(--text-muted); line-height: 1.5; word-break: break-word; }
    .reply-actions { display: flex; gap: 6px; margin-top: 4px; }
    .comment-inline-reply {
      margin-top: 8px;
      display: flex;
      gap: 8px;
      padding-left: 38px;
    }
    .comment-inline-reply-input {
      flex: 1;
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 8px;
      padding: 6px 10px;
      font-size: 12px;
      color: var(--text);
      font-family: var(--font-body);
    }
    .comment-inline-reply-input:focus { outline: none; border-color: var(--primary); }
    .comment-inline-reply-send {
      padding: 6px 12px;
      border-radius: 8px;
      border: none;
      background: var(--gradient-1);
      color: #fff;
      font-size: 12px;
      cursor: pointer;
      white-space: nowrap;
    }
    .comment-inline-reply-send:hover { opacity: 0.85; }
    .comment-panel-footer {
      padding: 12px 16px;
      border-top: 1px solid rgba(255,255,255,0.07);
      display: flex;
      gap: 8px;
      align-items: center;
      flex-shrink: 0;
    }
    .comment-panel-input {
      flex: 1;
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 10px;
      padding: 8px 12px;
      font-size: 13px;
      color: var(--text);
      font-family: var(--font-body);
    }
    .comment-panel-input:focus { outline: none; border-color: var(--primary); }
    .comment-panel-input::placeholder { color: rgba(255,255,255,0.25); }
    .comment-panel-send {
      padding: 8px 16px;
      border-radius: 10px;
      border: none;
      background: var(--gradient-1);
      color: #fff;
      font-size: 13px;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
    }
    .comment-panel-send:hover { opacity: 0.85; }
    .comment-panel-send:disabled { opacity: 0.45; cursor: not-allowed; }
    @media (max-width: 1200px) {
      .comment-panel-inner { flex-direction: column; }
      .comment-full-panel {
        /* 2026-04-23 buglist #14: 移动端评论面板不再当"底部抽屉"盖在详情弹窗上,
           而是与详情弹窗分层: 评论全屏、详情隐藏, 避免评论弹窗盖在详情弹窗上 */
        position: fixed;
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
        width: 100%;
        max-width: 100%;
        max-height: 100vh;
        border-radius: 0;
        transform: none;
        animation: slideInRightMobile 0.3s cubic-bezier(0.22,1,0.36,1);
      }
      @keyframes slideInRightMobile {
        from { opacity: 0; transform: translateX(40%); }
        to { opacity: 1; transform: translateX(0); }
      }
      .proj-detail-overlay.comment-open .proj-detail-box,
      .skill-detail-overlay.comment-open .skill-detail-box {
        transform: none;
      }
      /* 移动端: 评论面板打开时, 把项目/SKILL详情弹窗藏起来, 避免两层弹窗叠加 */
      .proj-detail-overlay.comment-open,
      .skill-detail-overlay.comment-open {
        visibility: hidden;
      }
      /* prd4ai-011: iPhone 底部 Home Indicator 横线会遮挡评论输入框，
         使用 safe-area-inset-bottom 抬高输入区域 */
      .comment-panel-footer {
        padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
      }
    }
    /* ===== Lucide Icons 基础样式 ===== */
    svg[data-lucide], svg.lucide-icon {
      vertical-align: -0.125em;
      flex-shrink: 0;
      width: 1em;
      height: 1em;
    }

    /* ============================================================ */
    /* Commit-2 · 视觉升级: 背景 + Header + Hero + Primary Tabs     */
    /* 对齐 docs/UI示例代码 Figma Demo (深色 + 毛玻璃 + 紫青渐变)    */
    /* 原则: 仅追加新规则, 不改旧选择器 class 名, 保持 JS 零影响    */
    /* ============================================================ */

    /* ── 全局深色基底 + 三团光斑 + 网格 overlay ── */
    body {
      background:
        radial-gradient(ellipse 80% 60% at 15% 20%, var(--ds-glow-purple), transparent 60%),
        radial-gradient(ellipse 70% 55% at 85% 80%, var(--ds-glow-blue), transparent 60%),
        radial-gradient(ellipse 60% 50% at 50% 50%, var(--ds-glow-cyan), transparent 60%),
        linear-gradient(180deg, var(--ds-bg-base) 0%, var(--ds-bg-surface) 50%, var(--ds-bg-base) 100%);
      background-attachment: fixed;
    }

    /* 全局网格线叠加 (固定层, 不随 body 滚动; z-index:-1 让正常内容无需显式提层) */
    body::before {
      content: '';
      position: fixed;
      inset: 0;
      background-image:
        linear-gradient(var(--ds-grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--ds-grid-line) 1px, transparent 1px);
      background-size: 50px 50px;
      pointer-events: none;
      z-index: -1;
    }

    /* 三团大尺寸模糊光斑 (固定在视口, 缓慢呼吸) */
    body::after {
      content: '';
      position: fixed;
      inset: 0;
      background:
        radial-gradient(circle 400px at 20% 30%, var(--ds-glow-purple), transparent 70%),
        radial-gradient(circle 360px at 80% 70%, var(--ds-glow-blue), transparent 70%),
        radial-gradient(circle 320px at 50% 90%, var(--ds-glow-cyan), transparent 70%);
      filter: blur(40px);
      pointer-events: none;
      z-index: -1;
      opacity: 0.9;
      animation: dsGlowBreath 12s ease-in-out infinite;
    }

    @keyframes dsGlowBreath {
      0%, 100% { opacity: 0.7; }
      50% { opacity: 1; }
    }

    /* 给 html/body 一个不透明兜底, 防止 z-index:-1 的伪元素被视作背景外层时透底 */
    html {
      background: var(--ds-bg-base);
    }
    body {
      /* body 自身保留渐变 + 光斑 mix; 关键: 不要给 body 设为 position:relative, 否则 ::before/::after 的 z-index:-1 会被裁到 body 下方导致消失 */
      position: static;
    }

    /* 注: 不再强制 .hero / .primary-tabs / .modal-overlay 等位于上层
       (原规则会把 primary-tabs 的 absolute、modal-overlay 的 fixed 改成 relative, 导致 Bug 1/2/3) */

    /* ── Hero 背景重绘 (保留 Canvas 粒子, 更贴 Demo 风) ── */
    .hero {
      background: linear-gradient(135deg, var(--ds-bg-base) 0%, var(--ds-bg-surface) 50%, var(--ds-bg-base) 100%);
      animation: none; /* 停用旧的 heroBgAnim, 改由 body::after 做呼吸光斑 */
    }

    /* Hero 内部光斑 (在 canvas 之下, 文字之上的装饰) */
    .hero::after {
      content: '';
      position: absolute;
      inset: 0;
      background:
        radial-gradient(circle 300px at 25% 40%, var(--ds-glow-purple), transparent 70%),
        radial-gradient(circle 280px at 75% 60%, var(--ds-glow-cyan), transparent 70%);
      pointer-events: none;
      z-index: 0;
    }

    /* ── Primary Tabs 升级: Demo CategoryTabs 风格 ── */
    .primary-tab {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      border-radius: var(--ds-radius-lg);
      padding: 10px 28px;
      color: var(--ds-text-tertiary);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
      box-shadow: var(--ds-shadow-md);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
    }
    .primary-tab:hover {
      background: var(--ds-bg-raised);
      border-color: var(--ds-border-default);
      color: var(--ds-text-primary);
      transform: translateY(-1px);
      box-shadow: var(--ds-shadow-lg);
    }
    .primary-tab.active {
      background:
        linear-gradient(135deg, rgba(168, 85, 247, 0.25), rgba(34, 211, 238, 0.18));
      border-color: var(--ds-border-brand);
      color: var(--ds-text-primary);
      box-shadow: var(--ds-shadow-glow-brand);
    }
    .primary-tab.active .primary-tab-label {
      background: var(--ds-gradient-brand);
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
      color: transparent;
    }
    .primary-tab-count {
      display: inline-flex;
      align-items: center;
      padding: 1px 8px;
      border-radius: var(--ds-radius-pill);
      background: rgba(255, 255, 255, 0.08);
      color: var(--ds-text-tertiary);
      font-size: 11px;
      font-weight: 600;
      opacity: 1;
    }
    .primary-tab.active .primary-tab-count {
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.3), rgba(34, 211, 238, 0.25));
      color: var(--ds-text-primary);
      opacity: 1;
    }

    /* ── 顶栏登录按钮: 2026-04-23 弱化版
       之前是满色紫青渐变 CTA + glow, 在 header 上视觉重量过大
       现在: 低饱和毛玻璃底 + 紫色细边 + 紫色文字; hover 才显品牌渐变
       圆角与 deploy-tool-btn / my-projects-btn 统一为胶囊 */
    .header-login-btn {
      background: rgba(168, 85, 247, 0.08);
      border: 1px solid rgba(168, 85, 247, 0.28);
      border-radius: var(--ds-radius-pill);
      color: var(--ds-brand-purple-hover);
      font-weight: 600;
      box-shadow: none;
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .header-login-btn:hover {
      background: rgba(168, 85, 247, 0.15);
      border-color: rgba(168, 85, 247, 0.5);
      color: var(--ds-text-primary);
      transform: translateY(-1px);
      box-shadow: 0 4px 14px rgba(168, 85, 247, 0.22);
    }

    /* ── My Projects 按钮 → 与登录按钮形成主次对比 (次按钮风格)
       2026-04-23 修复圆角: 与旁边 deploy-tool-btn / header-login-btn 统一胶囊风 (20px),
       不再被 Commit-2 的 --ds-radius-sm (8px) 覆盖 */
    .my-projects-btn {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      border-radius: var(--ds-radius-pill);
      color: var(--ds-text-secondary);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
    }
    .my-projects-btn:hover {
      background: var(--ds-bg-raised);
      color: var(--ds-text-primary);
    }

    /* ── Navbar 二级分类 (sticky 毛玻璃栏) 轻度对齐 Demo ── */
    .navbar {
      background:
        linear-gradient(180deg,
          rgba(2, 6, 23, 0.75) 0%,
          rgba(15, 23, 42, 0.85) 100%);
      backdrop-filter: var(--ds-blur-heavy);
      -webkit-backdrop-filter: var(--ds-blur-heavy);
      border-bottom: 1px solid var(--ds-border-subtle);
      box-shadow: var(--ds-shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.04);
    }
    .nav-item::after {
      background: var(--ds-gradient-brand);
      box-shadow: 0 -2px 8px rgba(168, 85, 247, 0.5);
    }
    .nav-item.active {
      text-shadow: 0 0 16px rgba(168, 85, 247, 0.6);
    }

    /* ── 针对 prefers-reduced-motion 关掉光斑呼吸 (Commit-7 会做完整降级) ── */
    @media (prefers-reduced-motion: reduce) {
      body::after {
        animation: none;
      }
    }

    /* ── Hero 标题文字渐变小幅对齐 Demo (保持不破坏粒子汇聚动效) ── */
    /* 注: 粒子汇聚后的标题由 JS 渲染为 canvas, 此规则仅影响副标题与 fallback */

    /* ============================================================ */
    /* Commit-3 · 视觉升级: 二级分类 navbar + 卡片 + 浮动上传按钮   */
    /* ============================================================ */

    /* ── 二级分类导航条 (nav-item) 更贴 Demo CategoryTabs ── */
    .nav-item {
      color: var(--ds-text-tertiary);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .nav-item:hover {
      color: var(--ds-text-primary);
      background: var(--ds-bg-elevated);
    }
    .nav-item.active {
      color: var(--ds-text-primary);
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.18), rgba(34, 211, 238, 0.12));
      text-shadow: 0 0 16px rgba(168, 85, 247, 0.55);
    }
    .nav-count {
      background: var(--ds-bg-elevated) !important;
      color: var(--ds-text-tertiary) !important;
      border: 1px solid var(--ds-border-subtle);
    }
    .nav-item.active .nav-count {
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.35), rgba(34, 211, 238, 0.25)) !important;
      color: var(--ds-text-primary) !important;
      border-color: var(--ds-border-brand);
    }

    /* ── Module Title (分类大标题 "生活健康 (55)") ── */
    .module-title {
      color: var(--ds-text-primary);
    }
    .module-title .dot {
      box-shadow: 0 0 16px currentColor;
    }
    .module-title .module-count {
      color: var(--ds-text-tertiary);
    }

    /* ── 卡片 (Card) Demo AppCard 风格: 毛玻璃 + hover 光晕 + 圆角 ── */
    .card {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      border-radius: var(--ds-radius-xl);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
      box-shadow: var(--ds-shadow-md);
      transition: transform var(--ds-duration-base) var(--ds-ease-out),
                  border-color var(--ds-duration-base) var(--ds-ease-out),
                  box-shadow var(--ds-duration-base) var(--ds-ease-out),
                  background var(--ds-duration-base) var(--ds-ease-out);
      overflow: hidden; /* 保证 ::before 光晕被圆角裁剪 */
    }
    .card::before {
      content: '';
      position: absolute;
      inset: -1px;
      border-radius: inherit;
      padding: 1px;
      background: linear-gradient(135deg, rgba(168, 85, 247, 0) 0%, rgba(168, 85, 247, 0) 100%);
      pointer-events: none;
      transition: background var(--ds-duration-base) var(--ds-ease-out);
      z-index: 0;
    }
    .card:hover {
      background: var(--ds-bg-raised);
      border-color: var(--ds-border-default);
      transform: translateY(-4px) scale(1.01);
      box-shadow: var(--ds-shadow-lg), 0 0 32px rgba(168, 85, 247, 0.18);
    }
    .card:hover::before {
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.25) 0%, rgba(34, 211, 238, 0.18) 100%);
    }
    /* 2026-04-23 修复: 原先写 .card > * { position: relative; z-index: 1 }
       会把 .card-admin-actions / .card-user-actions 的 absolute 强改为 relative,
       导致编辑/删除按钮脱离右上角. 改为让 .card 本身承担 stacking context,
       ::before 已是 .card 的伪元素 + inset:-1, z-index 不设时默认 auto,
       只需保证 ::before 在 z:0, 主内容自然在 z:auto 的上方即可.
       同时给 card-head (主信息流) 单独提 z-index, 不触碰 absolute 子元素. */
    .card {
      isolation: isolate;
    }
    .card > .card-head,
    .card > .card-body,
    .card > .card-text,
    .card > .card-footer {
      position: relative;
      z-index: 1;
    }
    /* absolute 按钮组保持在最上层 (原 inline CSS 已设 z-index:10, 再保险一次) */
    .card > .card-admin-actions,
    .card > .card-user-actions {
      z-index: 20;
    }

    /* ============================================================ */
    /* 2026-04-23 bugfix: 卡片编辑/删除按钮 UI 对齐新视觉           */
    /* 原按钮: 硬编码 #3498db 蓝 + #e74c3c 红, 与新品牌色不符     */
    /* 新按钮: 毛玻璃底 + 品牌色图标; 删除按钮 hover 才红化       */
    /* ============================================================ */
    .card-admin-actions,
    .card-user-actions {
      top: 10px;
      right: 10px;
      gap: 6px;
    }
    .card-admin-btn {
      width: 30px;
      height: 30px;
      border-radius: var(--ds-radius-sm);
      background: rgba(15, 23, 42, 0.72);
      border: 1px solid var(--ds-border-subtle);
      color: var(--ds-text-secondary);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
      box-shadow: var(--ds-shadow-md);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
      opacity: 0;                     /* 默认隐藏, hover 卡片时显现 */
      transform: translateY(-2px);
    }
    .card:hover .card-admin-btn {
      opacity: 1;
      transform: translateY(0);
    }
    .card-admin-btn:hover {
      transform: translateY(-1px) scale(1.05);
    }
    /* 编辑: 品牌紫青渐变 hover */
    .card-admin-btn.edit-btn {
      background: rgba(15, 23, 42, 0.72);
      color: var(--ds-brand-purple-hover);
    }
    .card-admin-btn.edit-btn:hover {
      background: var(--ds-gradient-brand);
      border-color: transparent;
      color: var(--ds-text-primary);
      box-shadow: var(--ds-shadow-glow-brand);
    }
    /* 删除: 常态为中性, hover 红色警示 */
    .card-admin-btn.delete-btn {
      background: rgba(15, 23, 42, 0.72);
      color: var(--ds-text-tertiary);
    }
    .card-admin-btn.delete-btn:hover {
      background: linear-gradient(135deg, #ef4444, #dc2626);
      border-color: transparent;
      color: var(--ds-text-primary);
      box-shadow: 0 8px 24px rgba(239, 68, 68, 0.35);
    }
    .card-admin-btn svg[data-lucide] {
      width: 14px;
      height: 14px;
    }
    /* 移动端: 常显 (无 hover 场景), 避免用户看不到入口 */
    @media (max-width: 768px) {
      .card-admin-btn {
        opacity: 1;
        transform: none;
      }
    }
    /* list-mode: 也常显 (列表行信息稠密, 按钮尺寸小, 不用 hover 隐藏) */
    .cards-grid.list-mode .card-admin-btn {
      opacity: 1;
      transform: none;
      width: 26px;
      height: 26px;
    }
    .cards-grid.list-mode .card-admin-btn svg[data-lucide] {
      width: 12px;
      height: 12px;
    }

    /* ── 卡片图标方块: 加渐变发光 ── */
    .card-icon-wrap {
      border-radius: var(--ds-radius-lg);
      background: var(--ds-bg-elevated);
      box-shadow: inset 0 0 0 1px var(--ds-border-subtle),
                  0 4px 16px rgba(0, 0, 0, 0.25);
      transition: box-shadow var(--ds-duration-base) var(--ds-ease-out),
                  transform var(--ds-duration-base) var(--ds-ease-out);
    }
    .card:hover .card-icon-wrap {
      box-shadow: inset 0 0 0 1px var(--ds-border-brand),
                  0 8px 24px rgba(168, 85, 247, 0.35);
      transform: scale(1.05);
    }

    /* 卡片描述文字取色更柔和 */
    .card-desc {
      color: var(--ds-text-tertiary);
    }

    /* ── 浮动上传按钮: Demo 风格渐变胶囊 ── */
    .upload-btn {
      background: var(--ds-gradient-brand);
      box-shadow: var(--ds-shadow-glow-brand), 0 12px 32px rgba(34, 211, 238, 0.25);
      border: 1px solid rgba(255, 255, 255, 0.15);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
      transition: transform var(--ds-duration-base) var(--ds-ease-spring),
                  box-shadow var(--ds-duration-base) var(--ds-ease-out),
                  background var(--ds-duration-base) var(--ds-ease-out);
    }
    .upload-btn:hover {
      background: var(--ds-gradient-brand-hover);
      transform: scale(1.05) translateY(-2px);
      box-shadow: 0 16px 40px rgba(168, 85, 247, 0.5),
                  0 8px 24px rgba(34, 211, 238, 0.35);
    }

    /* ── View Mode Toggle (list / grid 切换) 贴 Demo 色调 ── */
    .view-mode-toggle {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      border-radius: var(--ds-radius-sm);
    }
    .view-mode-btn {
      color: var(--ds-text-tertiary);
    }
    .view-mode-btn:hover {
      color: var(--ds-text-primary);
    }
    .view-mode-btn.active {
      background: var(--ds-gradient-brand);
      color: var(--ds-text-primary);
    }

    /* ── Empty / Skeleton 状态 (与主题新背景协调) ── */
    .empty-state {
      color: var(--ds-text-tertiary);
    }
    .empty-state a {
      color: var(--ds-brand-purple-hover);
    }
    .skeleton-card {
      background: var(--ds-bg-elevated);
      border-color: var(--ds-border-subtle);
      border-radius: var(--ds-radius-xl);
    }
    .skeleton-card-list {
      background: var(--ds-bg-elevated);
      border-color: var(--ds-border-subtle);
      border-radius: var(--ds-radius-xl);
    }
    .skeleton-img, .skeleton-text {
      background: linear-gradient(90deg,
        rgba(255, 255, 255, 0.04) 25%,
        rgba(255, 255, 255, 0.08) 50%,
        rgba(255, 255, 255, 0.04) 75%);
      background-size: 200% 100%;
    }

    /* ============================================================ */
    /* Commit-4 · 视觉升级: 榜单 Sidebar 三套统一 (应用/游戏/Skills) */
    /* ============================================================ */

    .ranking-sidebar {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      border-radius: var(--ds-radius-xl);
      backdrop-filter: var(--ds-blur-heavy);
      -webkit-backdrop-filter: var(--ds-blur-heavy);
      box-shadow:
        var(--ds-shadow-lg),
        0 0 40px rgba(168, 85, 247, 0.08),
        inset 0 1px 0 rgba(255, 255, 255, 0.06);
      animation: dsSidebarGlow 6s ease-in-out infinite alternate;
    }
    @keyframes dsSidebarGlow {
      0% {
        box-shadow:
          var(--ds-shadow-lg),
          0 0 40px rgba(168, 85, 247, 0.08),
          inset 0 1px 0 rgba(255, 255, 255, 0.06);
      }
      100% {
        box-shadow:
          var(--ds-shadow-xl),
          0 0 60px rgba(34, 211, 238, 0.12),
          inset 0 1px 0 rgba(255, 255, 255, 0.08);
      }
    }
    .ranking-sidebar::-webkit-scrollbar-thumb {
      background: rgba(168, 85, 247, 0.3);
    }
    /* 2026-04-23 bugfix: .ranking-sidebar-title 里同时含 <i data-lucide>
       图标和文字. 上方旧规则用 background-clip:text + text-fill-color:transparent
       做文字渐变, 会把 SVG 图标也裁透明. 这里显式覆盖三个属性, icon + 文字
       统一用可见色, 保证榜单标题及其前缀图标都能展示. */
    .ranking-sidebar-title {
      background: none;
      -webkit-background-clip: border-box;
      background-clip: border-box;
      -webkit-text-fill-color: currentColor;
      color: var(--ds-text-primary);
      display: inline-flex;
      align-items: center;
      gap: 6px;
    }
    .ranking-sidebar-title svg[data-lucide] {
      width: 16px;
      height: 16px;
      color: var(--ds-brand-purple-hover);
      flex-shrink: 0;
    }
    /* 榜单弹窗标题行 H5 下允许换行, 避免小屏溢出 */
    .ranking-modal .ranking-header h2 {
      display: inline-flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 6px;
    }
    .ranking-sidebar-cat {
      background: var(--ds-bg-elevated);
      border-color: var(--ds-border-subtle);
      color: var(--ds-text-tertiary);
      border-radius: var(--ds-radius-sm);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .ranking-sidebar-cat:hover {
      background: var(--ds-bg-raised);
      color: var(--ds-text-primary);
    }
    .ranking-sidebar-cat.active {
      background: var(--ds-gradient-brand);
      color: var(--ds-text-primary);
      border-color: transparent;
      box-shadow: 0 4px 12px rgba(168, 85, 247, 0.35);
    }
    .ranking-sidebar-dims {
      border-bottom-color: var(--ds-border-subtle);
    }
    .ranking-sidebar-dim {
      color: var(--ds-text-tertiary);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .ranking-sidebar-dim:hover {
      color: var(--ds-text-primary);
    }
    .ranking-sidebar-dim.active {
      color: var(--ds-text-primary);
      border-bottom-color: var(--ds-brand-purple);
    }
    .ranking-sidebar-item {
      border-radius: var(--ds-radius-sm);
      transition: background var(--ds-duration-fast) var(--ds-ease-out),
                  transform var(--ds-duration-fast) var(--ds-ease-out);
    }
    .ranking-sidebar-item:hover {
      background: linear-gradient(90deg,
        rgba(168, 85, 247, 0.12),
        rgba(34, 211, 238, 0.05));
      transform: translateX(2px);
    }
    .ranking-sidebar-rank {
      background: var(--ds-bg-elevated);
      color: var(--ds-text-tertiary);
      border-radius: var(--ds-radius-sm);
    }
    /* Top1/2/3 金银铜保留原设计, 与新色调共存 */
    .ranking-sidebar-icon {
      border-radius: var(--ds-radius-sm);
      background: var(--ds-bg-elevated);
      box-shadow: inset 0 0 0 1px var(--ds-border-subtle);
    }
    .ranking-sidebar-name {
      color: var(--ds-text-primary);
    }
    .ranking-sidebar-meta {
      color: var(--ds-text-tertiary);
    }
    .ranking-sidebar-empty {
      color: var(--ds-text-tertiary);
    }

    /* ============================================================ */
    /* 2026-04-23: 榜单字号统一上调, 对齐项目卡片 17/13 的字号尺度   */
    /* 原配: title 15 / tab 11 / rank 11 / name 12 / meta 10         */
    /* 新配: title 17 / tab 13 / rank 13 / name 14 / meta 12         */
    /* icon 尺寸 32→36, item padding 放大, 避免字号变大后压得太挤    */
    /* ============================================================ */
    .ranking-sidebar-title {
      font-size: 17px;
      font-weight: 700;
    }
    .ranking-sidebar-title svg[data-lucide] {
      width: 18px;
      height: 18px;
    }
    .ranking-sidebar-cat {
      font-size: 13px;
      padding: 6px 12px;
    }
    .ranking-sidebar-dim {
      font-size: 13px;
      padding: 8px 14px;
    }
    .ranking-sidebar-item {
      padding: 10px 8px;
      gap: 10px;
    }
    .ranking-sidebar-rank {
      width: 26px;
      height: 26px;
      font-size: 13px;
    }
    .ranking-sidebar-icon {
      width: 36px;
      height: 36px;
    }
    .ranking-sidebar-name {
      font-size: 14px;
      font-weight: 600;
    }
    .ranking-sidebar-meta {
      font-size: 12px;
      margin-top: 2px;
    }
    .ranking-sidebar-empty {
      font-size: 13px;
      padding: 36px 0;
    }

    /* ============================================================ */
    /* 2026-04-23: 榜单字号统一上调, 对齐项目卡片 17/13 的字号尺度   */
    /* 原配: title 15 / tab 11 / rank 11 / name 12 / meta 10         */
    /* 新配: title 17 / tab 13 / rank 13 / name 14 / meta 12         */
    /* icon 尺寸 32→36, item padding 放大, 避免字号变大后压得太挤    */
    /* ============================================================ */
    .ranking-sidebar-title {
      font-size: 17px;
      font-weight: 700;
    }
    .ranking-sidebar-title svg[data-lucide] {
      width: 18px;
      height: 18px;
    }
    .ranking-sidebar-cat {
      font-size: 13px;
      padding: 6px 12px;
    }
    .ranking-sidebar-dim {
      font-size: 13px;
      padding: 8px 14px;
    }
    .ranking-sidebar-item {
      padding: 10px 8px;
      gap: 10px;
    }
    .ranking-sidebar-rank {
      width: 26px;
      height: 26px;
      font-size: 13px;
    }
    .ranking-sidebar-icon {
      width: 36px;
      height: 36px;
    }
    .ranking-sidebar-name {
      font-size: 14px;
      font-weight: 600;
    }
    .ranking-sidebar-meta {
      font-size: 12px;
      margin-top: 2px;
    }
    .ranking-sidebar-empty {
      font-size: 13px;
      padding: 36px 0;
    }

    /* ============================================================ */
    /* Commit-5 · 视觉升级: 七类 Modal + 表单 + 骨架/错误/空态        */
    /* 覆盖: modal-overlay, proj-detail-overlay, skill-detail-overlay,*/
    /*       my-projects-overlay, cms-box, notif-panel, user-login-box */
    /* 以及通用表单控件 .form-input/.form-textarea/.btn-submit/.btn-cancel */
    /* ============================================================ */

    /* ── Modal 遮罩统一深色毛玻璃 ── */
    .modal-overlay,
    .my-projects-overlay,
    .proj-detail-overlay,
    .skill-detail-overlay,
    .ranking-overlay,
    .comment-panel-overlay,
    .ch-transition-overlay,
    .qr-modal-overlay {
      background: var(--ds-bg-modal);
      backdrop-filter: var(--ds-blur-light);
      -webkit-backdrop-filter: var(--ds-blur-light);
    }

    /* ── Modal 容器统一升级: 毛玻璃 + 新圆角 + 阴影 ── */
    .modal,
    .my-projects-box,
    .proj-detail-box,
    .skill-detail-box,
    .cms-box,
    .user-login-box,
    .qr-modal-box,
    .ch-transition-modal {
      background:
        linear-gradient(135deg, rgba(15, 23, 42, 0.95) 0%, rgba(2, 6, 23, 0.92) 100%);
      border: 1px solid var(--ds-border-default);
      border-radius: var(--ds-radius-xl);
      box-shadow: var(--ds-shadow-xl), 0 0 80px rgba(168, 85, 247, 0.12);
      backdrop-filter: var(--ds-blur-heavy);
      -webkit-backdrop-filter: var(--ds-blur-heavy);
    }

    /* ── Modal 标题 ── */
    .modal-title {
      color: var(--ds-text-primary);
    }

    /* ── 表单 label / 输入框 ── */
    .form-label {
      color: var(--ds-text-secondary);
    }
    .form-label .required {
      color: var(--ds-brand-cyan);
    }
    .form-input,
    .form-textarea,
    .form-select {
      background: var(--ds-bg-input);
      border: 1px solid var(--ds-border-default);
      border-radius: var(--ds-radius-sm);
      color: var(--ds-text-primary);
      transition: border-color var(--ds-duration-base) var(--ds-ease-out),
                  box-shadow var(--ds-duration-base) var(--ds-ease-out),
                  background var(--ds-duration-base) var(--ds-ease-out);
    }
    .form-input::placeholder,
    .form-textarea::placeholder {
      color: var(--ds-text-dim);
    }
    .form-input:focus,
    .form-textarea:focus,
    .form-select:focus {
      border-color: var(--ds-brand-purple);
      box-shadow: var(--ds-ring-focus);
      background: var(--ds-bg-elevated);
    }

    /* 2026-04-27 buglist: Skill 上传 / 编辑弹窗中的 <select class="form-input"> 与主站对齐
       放在此处（所有 .form-input 规则之后）以避免被上方的 background 简写重置掉箭头图
       - 去掉浏览器原生下拉箭头 (webkit/moz/ms)
       - 用 background-color + background-image 分开写, 避免 background 简写覆盖
       - SVG data URL 用 %23 表示 # (HEX 颜色), 兼容 Safari */
    select.form-input,
    select.form-select {
      -webkit-appearance: none !important;
      -moz-appearance: none !important;
      appearance: none !important;
      padding-right: 40px !important;
      background-color: var(--ds-bg-input);
      background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23bdc3c7' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") !important;
      background-repeat: no-repeat !important;
      background-position: right 14px center !important;
      background-size: 14px 14px !important;
      cursor: pointer;
      line-height: 1.4;
    }
    select.form-input::-ms-expand,
    select.form-select::-ms-expand { display: none; }
    select.form-input:focus,
    select.form-select:focus {
      background-color: var(--ds-bg-elevated);
      background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238e44ad' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") !important;
    }
    select.form-input option,
    select.form-select option {
      background: #1e1b3a;
      color: var(--ds-text-primary, #ecf0f1);
    }
    .form-hint {
      color: var(--ds-text-tertiary);
    }

    /* ── 分类选择器 chip ── */
    .category-option {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      color: var(--ds-text-tertiary);
      border-radius: var(--ds-radius-pill);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .category-option:hover {
      border-color: var(--ds-border-brand);
      color: var(--ds-text-primary);
      background: var(--ds-bg-raised);
    }
    .category-option.selected {
      background: var(--ds-gradient-brand);
      border-color: transparent;
      color: var(--ds-text-primary);
      box-shadow: 0 4px 12px rgba(168, 85, 247, 0.35);
    }

    /* ── 上传图片区 (虚线框) ── */
    .upload-area {
      background: var(--ds-bg-input);
      border: 2px dashed var(--ds-border-default);
      color: var(--ds-text-tertiary);
      border-radius: var(--ds-radius-md);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .upload-area:hover {
      border-color: var(--ds-brand-purple);
      background: rgba(168, 85, 247, 0.06);
      color: var(--ds-text-primary);
    }

    /* ── Modal 主次按钮 ── */
    .btn-cancel {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      color: var(--ds-text-secondary);
      border-radius: var(--ds-radius-sm);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .btn-cancel:hover {
      background: var(--ds-bg-raised);
      border-color: var(--ds-border-default);
      color: var(--ds-text-primary);
    }
    .btn-submit {
      background: var(--ds-gradient-brand);
      border-radius: var(--ds-radius-sm);
      box-shadow: var(--ds-shadow-md);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .btn-submit:hover {
      background: var(--ds-gradient-brand-hover);
      box-shadow: var(--ds-shadow-glow-brand);
      transform: translateY(-1px);
    }

    /* ── 通知面板 ── */
    .notif-panel {
      background:
        linear-gradient(135deg, rgba(15, 23, 42, 0.96) 0%, rgba(2, 6, 23, 0.92) 100%);
      border-left: 1px solid var(--ds-border-default);
      box-shadow: var(--ds-shadow-xl);
      backdrop-filter: var(--ds-blur-heavy);
      -webkit-backdrop-filter: var(--ds-blur-heavy);
    }
    .notif-panel-header {
      border-bottom-color: var(--ds-border-subtle);
    }
    .notif-panel-title {
      color: var(--ds-text-primary);
    }
    .notif-tab {
      color: var(--ds-text-tertiary);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .notif-tab:hover {
      color: var(--ds-text-primary);
      background: var(--ds-bg-elevated);
    }
    .notif-tab.active {
      color: var(--ds-text-primary);
      background: linear-gradient(135deg, rgba(168, 85, 247, 0.15), rgba(34, 211, 238, 0.08));
      border-bottom-color: var(--ds-brand-purple);
    }
    .notif-tab-badge {
      background: var(--ds-brand-red);
      color: var(--ds-text-primary);
    }

    /* ── 评论面板 ── */
    .comment-panel-input,
    .comment-inline-reply-input {
      background: var(--ds-bg-input);
      border-color: var(--ds-border-default);
      color: var(--ds-text-primary);
    }
    .comment-panel-input:focus,
    .comment-inline-reply-input:focus {
      border-color: var(--ds-brand-purple);
      box-shadow: var(--ds-ring-focus);
    }
    .comment-panel-input::placeholder {
      color: var(--ds-text-dim);
    }
    .comment-panel-send,
    .comment-inline-reply-send {
      background: var(--ds-gradient-brand);
    }
    .comment-panel-send:hover,
    .comment-inline-reply-send:hover {
      background: var(--ds-gradient-brand-hover);
    }

    /* ── CMS 后台相关 ── */
    .cms-tab {
      color: var(--ds-text-tertiary);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .cms-tab:hover {
      color: var(--ds-text-primary);
      background: var(--ds-bg-elevated);
    }
    .cms-tab.active {
      background: var(--ds-gradient-brand);
      color: var(--ds-text-primary);
      border-radius: var(--ds-radius-sm);
    }

    /* ── Toast 新色调 ── */
    .toast {
      border-radius: var(--ds-radius-sm);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
      box-shadow: var(--ds-shadow-lg);
    }
    .toast.success {
      background: linear-gradient(135deg, rgba(16, 185, 129, 0.95), rgba(5, 150, 105, 0.9));
    }
    .toast.error {
      background: linear-gradient(135deg, rgba(239, 68, 68, 0.95), rgba(220, 38, 38, 0.9));
    }
    .toast.info {
      background: linear-gradient(135deg, rgba(59, 130, 246, 0.95), rgba(37, 99, 235, 0.9));
    }

    /* ── 二维码弹窗 ── */
    .qr-modal-title {
      color: var(--ds-text-primary);
    }
    .qr-modal-url {
      color: var(--ds-text-tertiary);
    }
    .qr-modal-close {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      color: var(--ds-text-secondary);
    }
    .qr-modal-close:hover {
      background: var(--ds-bg-raised);
      color: var(--ds-text-primary);
    }

    /* ── 项目状态筛选条 ── */
    .project-status-filter {
      background: linear-gradient(180deg, rgba(15, 23, 42, 0.7), rgba(2, 6, 23, 0.55));
      border-bottom: 1px solid var(--ds-border-subtle);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
    }

    /* ============================================================ */
    /* Commit-6 · 视觉升级: 游戏 Tab + Skills 独立容器               */
    /* 主要: skill-cat-tabs / skill-card / game module-title        */
    /* ============================================================ */

    /* ── Skills 分类 tabs (与 nav-item 风格一致) ── */
    .skill-cat-tab {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      color: var(--ds-text-tertiary);
      border-radius: var(--ds-radius-pill);
      transition: all var(--ds-duration-base) var(--ds-ease-out);
    }
    .skill-cat-tab:hover {
      background: var(--ds-bg-raised);
      border-color: var(--ds-border-default);
      color: var(--ds-text-primary);
    }
    .skill-cat-tab.active {
      background: var(--ds-gradient-brand);
      border-color: transparent;
      color: var(--ds-text-primary);
      box-shadow: 0 4px 12px rgba(168, 85, 247, 0.3);
    }
    .skill-cat-tabs {
      border-bottom-color: var(--ds-border-subtle);
    }

    /* ── Skill Card (与 .card 风格统一) ── */
    .skill-card {
      background: var(--ds-bg-elevated);
      border: 1px solid var(--ds-border-subtle);
      border-radius: var(--ds-radius-xl);
      backdrop-filter: var(--ds-blur-glass);
      -webkit-backdrop-filter: var(--ds-blur-glass);
      box-shadow: var(--ds-shadow-md);
      transition: transform var(--ds-duration-base) var(--ds-ease-out),
                  border-color var(--ds-duration-base) var(--ds-ease-out),
                  box-shadow var(--ds-duration-base) var(--ds-ease-out),
                  background var(--ds-duration-base) var(--ds-ease-out);
    }
    .skill-card:hover {
      background: var(--ds-bg-raised);
      border-color: var(--ds-border-brand);
      transform: translateY(-4px) scale(1.01);
      box-shadow: var(--ds-shadow-lg), 0 0 32px rgba(168, 85, 247, 0.2);
    }

    /* Skill Card 封面默认占位渐变升级 */
    .skill-card-cover {
      background: linear-gradient(135deg,
        rgba(168, 85, 247, 0.22),
        rgba(34, 211, 238, 0.15));
    }

    /* Skill Card 文字 */
    .skill-card-name {
      color: var(--ds-text-primary);
    }
    .skill-card-desc {
      color: var(--ds-text-tertiary);
    }
    .skill-card-meta {
      color: var(--ds-text-tertiary);
    }

    /* ── 游戏 Tab 的 module-title dot 保留区分色, 仅增加发光 ── */
    /* 已在 Commit-3 的 .module-title .dot 生效 (box-shadow currentColor) */

    /* ── Skill 详情弹窗 header ── */
    .skill-detail-header {
      border-bottom-color: var(--ds-border-subtle);
    }
    .skill-detail-title {
      color: var(--ds-text-primary);
    }
    .skill-detail-desc-short {
      color: var(--ds-text-secondary);
    }
    .skill-detail-close {
      background: var(--ds-bg-elevated);
      color: var(--ds-text-secondary);
      border-radius: var(--ds-radius-sm);
    }
    .skill-detail-close:hover {
      background: var(--ds-bg-raised);
      color: var(--ds-text-primary);
    }

    /* 项目详情弹窗 header 同步 */
    .proj-detail-header {
      color: var(--ds-text-primary);
    }

    /* ============================================================ */
    /* Commit-7 · A11y 与性能降级                                    */
    /* 1. prefers-reduced-motion: 关粒子 / 光斑 / 卡片 hover 动画   */
    /* 2. html.ds-low-end: 低端设备降级 (JS 在启动时打类)           */
    /* 3. 小字对比度补强                                            */
    /* ============================================================ */

    /* ── prefers-reduced-motion: 系统级减少动画 ── */
    @media (prefers-reduced-motion: reduce) {
      body::after,
      .ranking-sidebar,
      .hero {
        animation: none !important;
      }
      #particle-canvas {
        display: none !important;  /* 粒子 canvas 也关掉 (JS 侧同步短路) */
      }
      .card,
      .skill-card,
      .primary-tab,
      .upload-btn {
        transition: none !important;
      }
      .card:hover,
      .skill-card:hover {
        transform: none !important;
      }
      * {
        scroll-behavior: auto !important;
      }
    }

    /* ── 低端设备 (JS 会在 body 加 ds-low-end 类): 关 backdrop-filter 与光斑 ── */
    html.ds-low-end body::before,
    html.ds-low-end body::after,
    html.ds-low-end .hero::after {
      display: none !important;
    }
    html.ds-low-end body {
      background: linear-gradient(180deg, var(--ds-bg-base) 0%, var(--ds-bg-surface) 100%);
      background-attachment: scroll;
    }
    html.ds-low-end .navbar,
    html.ds-low-end .primary-tab,
    html.ds-low-end .ranking-sidebar,
    html.ds-low-end .modal,
    html.ds-low-end .proj-detail-box,
    html.ds-low-end .skill-detail-box,
    html.ds-low-end .my-projects-box,
    html.ds-low-end .cms-box,
    html.ds-low-end .user-login-box,
    html.ds-low-end .card,
    html.ds-low-end .skill-card,
    html.ds-low-end .notif-panel,
    html.ds-low-end .upload-btn {
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
    }
    html.ds-low-end .ranking-sidebar {
      animation: none !important;
    }
    html.ds-low-end #particle-canvas {
      display: none !important;
    }

    /* ── 对比度补强: 弱文字场景最低 4.5:1 ── */
    /* slate-400 (#94a3b8) on slate-950 (#020617) 实测对比度 ≈ 7.8 → 通过; */
    /* slate-500 (#64748b) on slate-950 ≈ 5.3 → 通过; 无需改动           */

    /* ── focus-visible 增强 (键盘导航可见性) ── */
    button:focus-visible,
    .primary-tab:focus-visible,
    .nav-item:focus-visible,
    .card:focus-visible,
    .skill-card:focus-visible,
    .ranking-sidebar-cat:focus-visible {
      outline: 2px solid var(--ds-brand-purple);
      outline-offset: 2px;
      border-radius: var(--ds-radius-sm);
    }

/* ===== Tag Multi-Select Chips ===== */
.tag-chip {
  padding: 4px 12px;
  border-radius: 16px;
  border: 1px solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.06);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  transition: all 0.15s;
}
.tag-chip:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.tag-chip.selected {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* 主站标签筛选下拉 */
.tag-filter-select {
  padding: 4px 10px;
  border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.15);
  background: rgba(255,255,255,0.06);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
  outline: none;
  min-width: 80px;
}
.tag-filter-select:focus {
  border-color: var(--accent);
}
