/* ============================================================
   前台样式 · 深紫渐变暗色主题
   ============================================================ */

:root {
    --bg-deep: #120823;
    --bg-mid: #1c0f36;
    --bg-card: rgba(46, 25, 82, 0.55);
    --bg-card-hover: rgba(66, 35, 116, 0.72);
    --line: rgba(160, 118, 255, 0.22);
    --line-strong: rgba(186, 148, 255, 0.45);
    --text: #ece7fb;
    --text-dim: #a294c9;
    --text-mute: #7b6ba3;
    --grad-hot: linear-gradient(120deg, #ff7a45 0%, #ff4f8b 45%, #a855f7 100%);
    --grad-cool: linear-gradient(120deg, #7c5cff 0%, #b06cff 100%);
    --radius-lg: 20px;
    --radius-md: 14px;
    --shadow-card: 0 18px 40px -18px rgba(0, 0, 0, 0.75);

    /* 顶部三行（页头 / 横幅 / 公告）共用的堆叠间距与卡片底色，
       统一在这里定义，保证三行视觉语言一致 */
    --stack-gap: 12px;
    --panel-bg: rgba(26, 14, 48, 0.72);
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
}

body {
    min-height: 100vh;
    font-family: "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    color: var(--text);
    background: radial-gradient(1200px 700px at 15% -10%, #34195e 0%, transparent 60%),
                radial-gradient(1000px 600px at 90% 0%, #3d1a63 0%, transparent 55%),
                linear-gradient(180deg, var(--bg-deep) 0%, #0d0518 100%);
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    position: relative;
    overflow-x: hidden;
    /* iPhone 刘海屏：底部内容不被横条遮挡 */
    padding-bottom: env(safe-area-inset-bottom, 0);
}

a { text-decoration: none; color: inherit; }

.wrap {
    width: 100%;
    max-width: 1240px;
    margin: 0 auto;
    padding: 0 20px;
}

/* ---------- 背景装饰 ---------- */

.bg-decor {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
}

.orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(90px);
    opacity: 0.5;
}

.orb-1 { width: 420px; height: 420px; top: -120px; left: -80px; background: #7c3aed; }
.orb-2 { width: 360px; height: 360px; top: 20%; right: -100px; background: #db2777; opacity: 0.32; }
.orb-3 { width: 480px; height: 480px; bottom: -200px; left: 35%; background: #4c1d95; opacity: 0.45; }

.grid-mask {
    position: absolute;
    inset: 0;
    background-image: linear-gradient(rgba(255, 255, 255, 0.028) 1px, transparent 1px),
                      linear-gradient(90deg, rgba(255, 255, 255, 0.028) 1px, transparent 1px);
    background-size: 56px 56px;
    mask-image: radial-gradient(circle at 50% 0%, #000 0%, transparent 75%);
    -webkit-mask-image: radial-gradient(circle at 50% 0%, #000 0%, transparent 75%);
}

/* ---------- 顶部 ---------- */

.site-header {
    position: relative;
    z-index: 2;
    padding: 18px 0 0;
    padding-top: max(18px, env(safe-area-inset-top, 0px));
}

/* 页头做成卡片，与下方横幅、公告等宽同款，三行才能对齐成一组 */
.header-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 22px;
    border-radius: var(--radius-lg);
    background: var(--panel-bg);
    border: 1px solid var(--line);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
}

.brand-mark {
    width: 46px;
    height: 46px;
    flex: 0 0 46px;
    border-radius: 14px;
    background: var(--grad-hot);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 17px;
    letter-spacing: 0.5px;
    color: #fff;
    box-shadow: 0 10px 24px -10px rgba(255, 79, 139, 0.85);
}

/* 上传了页头 LOGO 时，整块品牌区域交给图片，不再显示文字方块 */
.brand.has-logo { gap: 0; }

.brand-logo {
    display: block;
    height: 52px;
    width: auto;
    max-width: min(420px, 62vw);
    object-fit: contain;
}

.brand-text { display: flex; flex-direction: column; line-height: 1.35; }
.brand-text strong { font-size: 19px; letter-spacing: 0.5px; }
.brand-text small { font-size: 12px; color: var(--text-mute); }

/* ---------- 页头游戏分类导航条 ---------- */

.game-cats-nav {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-left: 10px;
    overflow: hidden;
}

.game-cats-nav img {
    display: block;
    height: 62px;
    width: auto;
    max-width: 100%;
    object-fit: contain;
    filter: drop-shadow(0 6px 16px rgba(124, 92, 255, .35));
    -webkit-user-drag: none;
}

@media (max-width: 900px) {
    .game-cats-nav img { height: 50px; }
}

@media (max-width: 760px) {
    /* 移动端导航条太长，改为横向滚动，保留完整展示 */
    .game-cats-nav {
        justify-content: flex-start;
        overflow-x: auto;
        margin-left: 6px;
        scrollbar-width: none;          /* Firefox */
        -ms-overflow-style: none;       /* IE/Edge */
    }
    .game-cats-nav::-webkit-scrollbar { display: none; }
    .game-cats-nav img {
        height: 46px;
        max-width: none;
        flex: 0 0 auto;
    }
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

/* ---------- 首页横幅 ---------- */

.banner-slider {
    position: relative;
    z-index: 2;
    margin-top: var(--stack-gap);
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--line);
    background: var(--panel-bg);
    line-height: 0;
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

a.banner-slider:hover {
    transform: translateY(-2px);
    box-shadow: 0 18px 40px -18px rgba(124, 58, 237, 0.7);
}

.banner-track {
    position: relative;
}

.banner-slide {
    display: block;
    line-height: 0;
}

.banner-slide img {
    display: block;
    width: 100%;
    height: auto;
}

/* 单图模式直接显示 */

/* 多图轮播模式：track 横向排列所有 slide，整体平移实现左右滑动 */
.banner-slider.is-slider .banner-track {
    display: flex;
    transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.banner-slider.is-slider .banner-slide {
    flex: 0 0 100%;
    width: 100%;
}

/* 指示点 */
.banner-dots {
    position: absolute;
    bottom: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 3;
    display: flex;
    gap: 6px;
}

.banner-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.38);
    cursor: pointer;
    transition: width 0.3s ease, background 0.3s ease;
}

.banner-dot.is-active {
    width: 22px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.9);
}

/* ---------- 公告 ---------- */

.notice-bar {
    position: relative;
    z-index: 2;
    margin-top: var(--stack-gap);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 18px;
    border-radius: var(--radius-lg);
    background: var(--panel-bg);
    border: 1px solid var(--line);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    overflow: hidden;
}

/* 只留一个呼吸小圆点做「实时」提示，不再显示「公告」二字 */
.notice-dot {
    flex: 0 0 auto;
    width: 7px;
    height: 7px;
    margin-left: 2px;
    border-radius: 50%;
    background: #34d399;
    box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.16);
    animation: pulse 1.8s ease-in-out infinite;
}

.notice-track {
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

.notice-track p {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.3px;
    color: #f0e9ff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 公告分段：每段文字 + 间隔竖线 */
.notice-seg {
    display: inline;
}

.notice-sep {
    display: inline-block;
    width: 4px;
    height: 4px;
    margin: 0 10px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.35);
    vertical-align: middle;
}

/* 不滚动时文字居中，避免右侧留出一大片空白显得失衡 */
.notice-track:not(.is-scroll) p { text-align: center; }

/* 跑马灯：单条内容从右侧进入、向左移出，走完立刻从右侧重新开始。
   关键是 padding-left:100% —— 百分比 padding 以「轨道宽度」为基准，
   于是元素总宽 = 轨道宽 + 文字宽，起始时文字正好停在右边缘之外；
   再 translateX(-100%)（以元素自身总宽为基准）即可把文字完整推出左边缘。 */
.notice-track.is-scroll { overflow: hidden; }

.notice-marquee {
    display: inline-block;
    padding-left: 100%;
    white-space: nowrap;
    animation: notice-scroll var(--notice-duration, 24s) linear infinite;
}

.notice-marquee p {
    display: inline;
    overflow: visible;
    text-overflow: clip;
}

@keyframes notice-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-100%); }
}

/* 鼠标悬停暂停，方便看清完整内容 */
.notice-bar:hover .notice-marquee { animation-play-state: paused; }

/* 尊重系统「减弱动态效果」设置 */
@media (prefers-reduced-motion: reduce) {
    .notice-marquee { animation: none; }
    .notice-marquee p:last-child { display: none; }
}

/* ============================================================
   平台 logo 横向滚动条
   位于公告下方、平台卡片网格上方，复用同一份平台数据。
   平台数量足够时整条向左匀速滚动，鼠标悬停暂停；数量少时静态排列。
   ============================================================ */

.logo-marquee {
    position: relative;
    z-index: 2;
    margin-top: var(--stack-gap);
    margin-bottom: 6px;
    padding: 14px 18px;
    border-radius: var(--radius-lg);
    background: var(--panel-bg);
    border: 1px solid var(--line);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    overflow: hidden;
}

/* 左右边缘做淡出遮罩，让滚动进出更柔和 */
.logo-marquee::before,
.logo-marquee::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    width: 40px;
    z-index: 2;
    pointer-events: none;
}
.logo-marquee::before {
    left: 0;
    background: linear-gradient(90deg, var(--bg-deep), transparent);
}
.logo-marquee::after {
    right: 0;
    background: linear-gradient(270deg, var(--bg-deep), transparent);
}

.logo-marquee-rail {
    display: flex;
    align-items: center;
    gap: 22px;
    width: max-content;
    min-width: 100%;
}

/* 静态模式（平台少不滚动）时整条居中，避免左对齐留大片空白 */
.logo-marquee:not(.is-anim) .logo-marquee-rail {
    margin: 0 auto;
    width: fit-content;
}

/* 数量足够时整条向左匀速滚动；动画时长按平台数量自适应，避免多时太快 */
.logo-marquee.is-anim .logo-marquee-rail {
    animation: logo-marquee-scroll var(--lmq-duration, 28s) linear infinite;
}

@keyframes logo-marquee-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* 鼠标悬停时暂停，方便看清单个图标 */
.logo-marquee:hover .logo-marquee-rail { animation-play-state: paused; }

/* 尊重系统「减弱动态效果」：关闭动画，回退为静态居中排列 */
@media (prefers-reduced-motion: reduce) {
    .logo-marquee.is-anim .logo-marquee-rail { animation: none; }
}

/* 单个图标芯片：圆形 logo + 名称，可点击跳转 */
.logo-chip {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    color: inherit;
    transition: transform 0.25s ease, filter 0.25s ease;
}

.logo-chip:hover {
    transform: translateY(-3px);
    filter: brightness(1.08);
}

.logo-chip-logo {
    position: relative;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    transition: box-shadow 0.3s ease, border-color 0.3s ease;
}

.logo-chip:hover .logo-chip-logo {
    border-color: rgba(196, 152, 255, 0.7);
    box-shadow: 0 8px 22px -8px rgba(168, 85, 247, 0.85);
}

.logo-chip-logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    position: relative;
    z-index: 1;
}

/* 无 logo 或图片加载失败时显示首字占位 */
.logo-chip-logo .logo-fallback {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 700;
    color: #fff;
    background: var(--grad-cool);
    z-index: 0;
}

.logo-chip-logo.no-logo .logo-fallback,
.logo-chip-logo.logo-failed .logo-fallback { display: flex; }

.logo-chip-name {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-dim);
    white-space: nowrap;
    max-width: 72px;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.25s ease;
}

.logo-chip:hover .logo-chip-name { color: var(--text); }

/* ---------- 响应式：移动端缩小图标、缩短动画时长 ---------- */

@media (max-width: 760px) {
    .logo-marquee { padding: 10px 14px; border-radius: var(--radius-md); margin-bottom: 4px; }
    .logo-chip-logo { width: 44px; height: 44px; }
    .logo-chip-logo .logo-fallback { font-size: 18px; }
    .logo-chip-name { font-size: 11px; max-width: 56px; }
    .logo-marquee-rail { gap: 16px; }
    .logo-marquee::before,
    .logo-marquee::after { width: 24px; }
    /* 窄屏轨道短，按比例压缩时长 */
    .logo-marquee.is-anim .logo-marquee-rail {
        animation-duration: calc(var(--lmq-duration, 28s) * 0.6);
    }
}

@media (max-width: 420px) {
    .logo-chip-logo { width: 36px; height: 36px; }
    .logo-chip-logo .logo-fallback { font-size: 15px; }
    .logo-chip-name { font-size: 9.5px; max-width: 44px; }
    .logo-marquee { padding: 8px 12px; }
    .logo-marquee-rail { gap: 12px; }
}

/* ---------- 区块标题 ---------- */

.main-area {
    position: relative;
    z-index: 2;
    padding: 34px 20px 60px;
}

.section-head {
    margin-bottom: 22px;
    text-align: center;
}

/* 居中模式：标题、色条、描述共享同一条中轴 */
.section-title {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 0 0 10px;
    font-size: 22px;
    letter-spacing: 1px;
}

/* 主标题与色条同列。
   两者若是并列的兄弟节点，各自按整行宽度居中，挂上右侧副标后
   主标题中心会左移、色条却不动，看着就是色条偏右；
   包成一列后色条只跟主标题对齐，副标加不加都不影响。 */
.section-title .title-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 9px;
}

/* 标题下方的装饰线：细、长、两端渐隐。
   之前是 36×4 的实心圆角块，居中放在标题下方显得墩实、像个小按钮；
   压薄拉长后更像一条分隔线，而不是与标题争视觉的色块。
   两端用 mask 淡出，避免线头在深色底上硬生生截断；
   拉长后渐隐区间也相应放宽，否则纯色段过长会显得像根实心杠。 */
.section-title .title-bar {
    width: 96px;
    height: 3px;
    border-radius: 2px;
    background: var(--grad-hot);
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 22%, #000 78%, transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 22%, #000 78%, transparent 100%);
}

/* 主标题 + 小字副标同排。
   两段文字若同字号同字重，分隔符就成了噪点、整块头部也显得头重，
   所以副标按主标题字号等比缩小（em）并降低对比度，只做补充说明。
   baseline 对齐取 .title-stack 首行（即主标题）的基线，副标因此与主标题齐脚。 */
.section-title .title-main {
    display: flex;
    align-items: baseline;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.5em;
}

.section-title .title-sub {
    position: relative;
    padding-left: 0.66em;
    font-size: 0.62em;
    font-weight: 400;
    letter-spacing: 2px;
    color: var(--text-dim);
    white-space: nowrap;
}

/* 一根细竖线代替「/」：分隔感够用，又不会跟标题抢视觉。
   颜色取 currentColor（即副标自身的字色）再降透明度，
   比借用卡片描边色 --line 明显得多，且以后改副标颜色时会自动跟着走。
   尺寸用 em，随标题字号缩放，手机端不必单独适配。 */
.section-title .title-sub::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 2px;
    height: 1em;
    border-radius: 1px;
    transform: translateY(-50%);
    background: currentColor;
    opacity: 0.55;
}

/* 窄屏字号本就小，副标再拉宽字距会显得散，收紧一点 */
@media (max-width: 480px) {
    .section-title .title-sub { letter-spacing: 1px; }
}

.section-desc {
    margin: 0 auto;
    font-size: 13.5px;
    color: var(--text-mute);
}

/* ---------- 平台卡片网格 ---------- */

.platform-grid {
    display: grid;
    gap: 18px;

    /* 老浏览器回退：直接按后台配置的列数平分 */
    grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));

    /* 横向卡片需要足够宽度才放得下「logo + 两行文字 + 按钮」。
       这里以后台列数算出理想列宽，但强制不窄于 300px；
       一旦配置的列数会让列宽低于该值，auto-fit 会自动少排几列。 */
    --col-ideal: calc((100% - (var(--cols, 4) - 1) * 18px) / var(--cols, 4));
    grid-template-columns: repeat(auto-fit, minmax(max(300px, var(--col-ideal)), 1fr));
}

/* 横向布局：logo 在左、文字居中、按钮靠右，卡片矮而宽 */
.platform-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-card);
    backdrop-filter: blur(10px);
    overflow: hidden;
    /* 卡片自身不再做位移动画，只让边框和底色轻微提亮，动效交给 logo */
    transition: border-color 0.25s ease, background 0.25s ease;
}

.platform-card::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--grad-hot);
    opacity: 0;
    transition: opacity 0.25s ease;
    pointer-events: none;
    mix-blend-mode: soft-light;
}

.platform-card:hover {
    border-color: var(--line-strong);
    background: var(--bg-card-hover);
}

.platform-card:hover::before { opacity: 0.28; }

.platform-card.is-featured {
    border-color: rgba(255, 138, 96, 0.55);
    background: linear-gradient(150deg, rgba(255, 122, 69, 0.2), rgba(168, 85, 247, 0.22));
}

/* 横向布局下角标压到右上角，并缩小尺寸，避免与右侧按钮抢空间 */
.card-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 8px;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 1.6;
    border-radius: 999px;
    background: var(--grad-hot);
    color: #fff;
    box-shadow: 0 6px 16px -6px rgba(255, 79, 139, 0.9);
}

/* 图标用内联 SVG 做背景，纯白单色，跨平台渲染一致（不用 emoji） */
.card-badge.is-hot::before,
.card-badge.is-rec::before,
.card-badge.is-official::before {
    content: "";
    flex: 0 0 auto;
    width: 11px;
    height: 11px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}

/* 热门：橙红渐变 + 火焰。
   火焰在导航/榜单场景已是「热度」的默认符号，语义无歧义。
   与大拇指、盾牌同为实心闭合图形，三个角标视觉重量一致。 */
.card-badge.is-hot {
    background: linear-gradient(135deg, #ff7a45, #ff2d55);
    box-shadow: 0 6px 16px -6px rgba(255, 77, 85, 0.95);
}

.card-badge.is-hot::before {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z'/%3E%3C/svg%3E");
}

/* 推荐：紫色渐变 + 大拇指。
   「点赞」的动作语义直白，一眼就懂，比抽象符号更好认。
   原图形左侧袖口与手掌之间留有空隙，11px 下那道缝会糊成脏点，
   这里改用袖口与手掌相连的整体轮廓，缩到手机端 7px 仍是完整一块。 */
.card-badge.is-rec {
    background: linear-gradient(135deg, #8b5cf6, #d946ef);
    box-shadow: 0 6px 16px -6px rgba(168, 85, 247, 0.95);
}

.card-badge.is-rec::before {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M2 20.5V10a1 1 0 0 1 1-1h3.2a1 1 0 0 0 .83-.44l4.3-6.32a1 1 0 0 1 1.35-.3l.5.29a2.6 2.6 0 0 1 1.16 2.9L13.6 8.2a.6.6 0 0 0 .58.76h5.09a2.2 2.2 0 0 1 2.15 2.7l-1.72 7.6A2.6 2.6 0 0 1 17.16 21.5H3a1 1 0 0 1-1-1z'/%3E%3C/svg%3E");
}

/* 官方：蓝色渐变 + 盾牌对勾。
   单独一个对勾在别处也表示「完成 / 已选中」，撑不起「官方」的含义；
   盾牌带「认证、担保」的语义，是平台认证标识的通用做法。
   未选锯齿花边的认证徽章：那种图形细节多，11px 下会糊成一团。 */
.card-badge.is-official {
    background: linear-gradient(135deg, #2563eb, #22d3ee);
    box-shadow: 0 6px 16px -6px rgba(37, 99, 235, 0.95);
}

.card-badge.is-official::before {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M12 1 3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z'/%3E%3C/svg%3E");
}

.card-logo {
    position: relative;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex: 0 0 auto;
    /* 唯一的悬停动效落在这里 */
    transition: transform 0.3s cubic-bezier(0.34, 1.4, 0.64, 1), box-shadow 0.3s ease, border-color 0.3s ease;
}

/* 鼠标滑过卡片时只有 logo 放大并发光，卡片整体保持不动 */
.platform-card:hover .card-logo {
    transform: scale(1.12);
    border-color: rgba(196, 152, 255, 0.7);
    box-shadow: 0 8px 22px -8px rgba(168, 85, 247, 0.85);
}

/* 圆形容器里用 cover 铺满，方形 logo 的四角会被圆形裁掉，
   视觉上比「小图标居中留一圈空白」更饱满 */
.card-logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    position: relative;
    z-index: 1;
}

.logo-fallback {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    font-weight: 700;
    color: #fff;
    background: var(--grad-cool);
    z-index: 0;
}

/* 无 logo 或图片加载失败时，显示首字占位 */
.card-logo.no-logo .logo-fallback,
.card-logo.logo-failed .logo-fallback { display: flex; }

/* 名称 / 描述 / 评分三行紧凑堆叠 */
.card-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: flex-start;
}

.card-name {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0.4px;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 卡片矮了，描述限一行，超出用省略号
   （避免有人把长网址填进描述栏时把卡片撑高） */
.card-desc {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--text-dim);
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.card-host {
    font-size: 11.5px;
    color: var(--text-mute);
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---------- 卡片评分 ---------- */

.card-rating {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

/* 五颗星用同一段文字画两层：底层暗色铺满，
   上层金色用 --fill 百分比裁切，因此支持半颗星 */
.stars {
    position: relative;
    flex: 0 0 auto;
    font-size: 13px;
    line-height: 1;
    letter-spacing: 1px;
    color: rgba(160, 118, 255, 0.28);
}

.stars::before,
.stars::after {
    content: "★★★★★";
}

.stars::after {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--fill, 0%);
    overflow: hidden;
    color: #fbbf24;
    white-space: nowrap;
}

.rating-num {
    font-size: 12.5px;
    font-weight: 600;
    color: #e9c97a;
    white-space: nowrap;
}

/* 右侧按钮：横向布局里垂直居中，宽度固定不被文字挤压。
   卡片区域不可点击，跳转入口只有这个按钮，所以它自己带手型光标 */
.card-enter {
    position: relative;
    overflow: hidden;
    flex: 0 0 auto;
    align-self: center;
    cursor: pointer;
    padding: 8px 15px;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
    border-radius: 999px;
    color: #fff;
    /* 始终保持紫色渐变，滑过卡片不再变红 */
    background: var(--grad-cool);
    box-shadow: 0 6px 16px -8px rgba(124, 92, 255, 0.9);
    transition: box-shadow 0.25s ease, transform 0.15s ease, filter 0.2s ease;
    /* 去掉移动端点击时系统自带的半透明灰块，只保留下面自定义的按压反馈 */
    -webkit-tap-highlight-color: transparent;
}

/* 一道斜向白色高光条，平时停在按钮左侧外面 */
.card-enter::after {
    content: "";
    position: absolute;
    top: 0;
    left: -80%;
    width: 55%;
    height: 100%;
    pointer-events: none;
    background: linear-gradient(100deg,
                rgba(255, 255, 255, 0) 0%,
                rgba(255, 255, 255, 0.55) 50%,
                rgba(255, 255, 255, 0) 100%);
    transform: translateX(0) skewX(-20deg);
}

@keyframes card-enter-shine {
    0%        { transform: translateX(0) skewX(-20deg); }
    60%, 100% { transform: translateX(400%) skewX(-20deg); }
}

/* 鼠标滑到卡片（或按钮）上，高光从左扫到右，循环播放。
   用 transform 位移而非改 left，走 GPU 合成层，不触发重排。
   整块限定在真鼠标设备：触屏上手指点过一次后 :hover 会一直粘着不释放，
   放在外面会让按钮点完就永久扫光。 */
@media (hover: hover) and (pointer: fine) {
    .platform-card:hover .card-enter::after,
    .card-enter:hover::after {
        animation: card-enter-shine 1.1s ease-in-out infinite;
    }

    /* 只提亮一点点作为可点提示，不换配色 */
    .platform-card:hover .card-enter {
        box-shadow: 0 8px 20px -8px rgba(124, 92, 255, 1);
        filter: brightness(1.06);
    }

    .card-enter:hover {
        box-shadow: 0 10px 24px -8px rgba(124, 92, 255, 1);
        filter: brightness(1.12);
    }
}

.card-enter:active { transform: scale(0.96); }

/* ---------- 空状态 ---------- */

.empty-state {
    text-align: center;
    padding: 70px 24px;
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    border: 1px dashed var(--line-strong);
}

.empty-icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 18px;
    border-radius: 20px;
    background: var(--grad-cool);
    opacity: 0.85;
}

.empty-state h1,
.empty-state h2,
.empty-state h3 { margin: 0 0 10px; font-size: 18px; }
.empty-state p { margin: 0 0 22px; font-size: 13.5px; color: var(--text-dim); }

.btn-primary {
    display: inline-block;
    padding: 11px 26px;
    font-size: 14px;
    font-weight: 600;
    border-radius: 999px;
    color: #fff;
    background: var(--grad-hot);
    box-shadow: 0 14px 30px -12px rgba(255, 79, 139, 0.85);
}

/* ---------- 底部 ---------- */

.site-footer {
    position: relative;
    z-index: 2;
    padding: 26px 0 38px;
    text-align: center;
    border-top: 1px solid rgba(160, 118, 255, 0.14);
}

.site-footer p { margin: 4px 0; font-size: 13px; color: var(--text-mute); }
.footer-tip { font-size: 12px !important; opacity: 0.75; }

/* ---------- 响应式 ---------- */

@media (max-width: 1080px) {
    /* 交给 auto-fit 按 300px 下限自行决定列数，不再硬锁 3 列 */
    .platform-grid { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
}

@media (max-width: 760px) {
    /* 手机端整体换成三列竖排卡片：logo 居中在上、名称居中、按钮铺满卡片底部。
       横向布局在窄屏放不下「logo + 文字 + 按钮」，竖排后同屏能看到更多平台。 */
    .platform-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 10px;
    }

    .platform-card {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 8px;
        /* 顶部留多一点，给右上角的角标腾出位置 */
        padding: 18px 6px 8px;
        border-radius: 14px;
    }

    /* 三列宽度只够放一行名称，描述、评分、网址一律隐藏，
       否则文字会把列宽撑开、三列排不齐 */
    .card-desc,
    .card-rating,
    .card-host { display: none; }

    .card-body {
        width: 100%;
        align-items: center;
        gap: 0;
    }

    .card-name { font-size: 13px; letter-spacing: 0.2px; }

    /* 按钮从右侧胶囊改为铺满卡片底部的横条 */
    .card-enter {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 5px;
        width: 100%;
        padding: 8px 4px;
        font-size: 12px;
        border-radius: 10px;
    }

    /* 按钮左侧的高亮小圆点，让窄按钮不至于太空 */
    .card-enter::before {
        content: "";
        flex: 0 0 auto;
        width: 5px;
        height: 5px;
        border-radius: 50%;
        background: #ffe08a;
        box-shadow: 0 0 6px rgba(255, 224, 138, 0.9);
    }

    /* 卡片变窄，角标同步缩小，避免压到 logo */
    .card-badge {
        top: 5px;
        right: 5px;
        gap: 2px;
        padding: 1px 5px;
        font-size: 9px;
    }

    .card-badge.is-hot::before,
    .card-badge.is-rec::before,
    .card-badge.is-official::before { width: 8px; height: 8px; }

    /* 板块标题、公告、footer 在手机端收紧 */
    .main-area { padding: 28px 14px 40px; }
    .notice-marquee { animation-duration: calc(var(--notice-duration, 24s) * 0.5); }
    .wrap { padding: 0 14px; }
    .card-logo { width: 48px; height: 48px; }
    .section-title { font-size: 18px; }
    .section-title .title-stack { gap: 7px; }
    .section-title .title-bar { width: 80px; }
    .section-desc { font-size: 12.5px; }
    .brand-logo { height: 38px; max-width: 68vw; }
    .brand-mark { width: 40px; height: 40px; flex-basis: 40px; font-size: 15px; border-radius: 12px; }
    .brand-text strong { font-size: 17px; }
    .brand-text small { font-size: 11px; }
    .header-card { padding: 9px 14px; border-radius: var(--radius-md); }
    .notice-bar { border-radius: var(--radius-md); }
    .banner-slider { border-radius: var(--radius-md); }
    .banner-dots { bottom: 7px; gap: 5px; }
    .banner-dot { width: 6px; height: 6px; }
    .banner-dot.is-active { width: 16px; }
    .notice-bar { padding: 8px 14px; gap: 10px; }
    .notice-track p { font-size: 13.5px; }
    .site-header { padding: max(10px, env(safe-area-inset-top, 0px)) 0 0; }

    /* footer 在手机端缩小 */
    .site-footer { padding: 20px 0 calc(20px + env(safe-area-inset-bottom, 0px)); }
    .site-footer p { font-size: 12px; }
    .footer-tip { font-size: 11px !important; }
}

/* 小屏手机：收紧尺寸 */
@media (max-width: 420px) {
    .platform-grid { gap: 8px; }
    .platform-card { padding: 14px 5px 7px; gap: 5px; border-radius: 12px; }
    .card-logo { width: 42px; height: 42px; }
    .card-name { font-size: 12px; }
    .logo-fallback { font-size: 18px; }
    .card-enter { gap: 4px; padding: 6px 3px; font-size: 10.5px; border-radius: 9px; }
    .card-enter::before { width: 4px; height: 4px; }
    .card-badge { top: 4px; right: 4px; padding: 1px 4px; font-size: 8.5px; }
    .card-badge.is-hot::before,
    .card-badge.is-rec::before,
    .card-badge.is-official::before { width: 7px; height: 7px; }
    .section-title { font-size: 17px; }
    .notice-track p { font-size: 12.5px; }
    .main-area { padding: 18px 12px 36px; }
    .wrap { padding: 0 12px; }
}

/* 超窄屏（<=360px）：三列卡片太挤，降到两列保证可读性 */
@media (max-width: 360px) {
    .platform-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .platform-card { padding: 16px 6px 8px; }
    .card-logo { width: 46px; height: 46px; }
    .card-name { font-size: 12.5px; }
    .card-enter { font-size: 11px; padding: 7px 4px; }
}

/* 超超大屏（<=320px）：极端窄屏，进一步收紧 */
@media (max-width: 320px) {
    .platform-card { padding: 12px 4px 6px; }
    .card-logo { width: 40px; height: 40px; }
    .card-name { font-size: 11.5px; }
    .card-enter { font-size: 10px; padding: 6px 3px; }
    .brand-text strong { font-size: 15px; }
    .brand-text small { display: none; }
    .section-title { font-size: 16px; }
    .main-area { padding: 16px 10px 30px; }
    .wrap { padding: 0 10px; }
}

/* 触屏设备没有真正的 hover：点过的元素会一直保持悬停态，
   这里禁掉 logo 的悬停放大，改为按压按钮时轻微内缩 */
@media (hover: none) {
    .platform-card:hover .card-logo {
        transform: none;
        border-color: var(--line);
        box-shadow: none;
    }

    /* 高光不做常态循环：一屏十几张卡片同时扫光会满屏乱闪，
       且动画持续占用合成层，低端机滚动会掉帧。
       改成按住按钮时扫过一次，只在有意图操作时才出现 */
    .card-enter:active::after {
        animation: card-enter-shine 0.9s ease-out;
    }

    .card-enter:active { transform: scale(0.96); }
}

/* 尊重系统「减弱动态效果」，直接隐藏高光条 */
@media (prefers-reduced-motion: reduce) {
    .card-enter::after { display: none; }
}

/* ============================================================
   页面容器
   默认情况下页面结构由服务端直接渲染（index.php + lib/home_body.php），
   打开即完整可见。只有开启 HIDE_PAGE_SOURCE 后才存在「等 JS 注入」的
   中间态，下面的加载态与失败兜底样式就是为那种情况准备的。
   ============================================================ */

#app { min-height: 100vh; }

#app.is-loading,
#app.is-failed {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

/* 加载中的转圈占位，避免内容注入前是一片纯粹的空白 */
#app.is-loading::before {
    content: '';
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3px solid rgba(255, 255, 255, .16);
    border-top-color: rgba(58, 46, 46, 0.72);
    animation: app-spin .8s linear infinite;
}

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

/* 尊重系统「减少动态效果」设置：放慢而不是彻底停掉，否则看不出仍在加载 */
@media (prefers-reduced-motion: reduce) {
    #app.is-loading::before { animation-duration: 2.4s; }
}

/* 内容取回失败时的提示，给一个明确的重试出口 */
.app-fallback {
    text-align: center;
    max-width: 340px;
    padding: 28px 24px;
    border-radius: 16px;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .1);
}

.app-fallback-title {
    margin: 0 0 6px;
    font-size: 16px;
    font-weight: 600;
    color: rgba(255, 255, 255, .92);
}

.app-fallback-tip {
    margin: 0 0 18px;
    font-size: 13px;
    line-height: 1.6;
    color: rgba(255, 255, 255, .58);
}

.app-fallback-btn {
    font: inherit;
    font-size: 14px;
    padding: 9px 22px;
    border: 0;
    border-radius: 999px;
    cursor: pointer;
    color: #fff;
    background: linear-gradient(135deg, #6d5bff, #b44bff);
    transition: filter .2s ease;
}

.app-fallback-btn:hover { filter: brightness(1.12); }
.app-fallback-btn:active { filter: brightness(.94); }

/* 关闭了 JavaScript 时显示的纯文字简介 */
.noscript-tip {
    max-width: 640px;
    margin: 18vh auto 0;
    padding: 28px 24px;
    text-align: center;
    border-radius: 16px;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .1);
    color: rgba(255, 255, 255, .78);
}

.noscript-tip strong {
    display: block;
    margin-bottom: 10px;
    font-size: 18px;
    color: #fff;
}

.noscript-tip p {
    margin: 6px 0 0;
    font-size: 14px;
    line-height: 1.7;
}

/* 仅供读屏软件识别、视觉上不可见的文本 */
.seo-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ============================================================
   回到顶部按钮
   ============================================================ */

.back-to-top {
    position: fixed;
    right: 24px;
    bottom: calc(28px + env(safe-area-inset-bottom, 0px));
    z-index: 100;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    color: #fff;
    background: var(--grad-cool);
    box-shadow: 0 8px 24px -6px rgba(124, 92, 255, 0.6);
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px) scale(0.85);
    transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.34, 1.4, 0.64, 1), filter 0.2s ease;
}

.back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
}

.back-to-top:hover {
    filter: brightness(1.12);
    box-shadow: 0 10px 28px -6px rgba(124, 92, 255, 0.85);
}

.back-to-top:active { transform: scale(0.92); }

.back-to-top svg { width: 22px; height: 22px; }

@media (max-width: 760px) {
    .back-to-top { right: 16px; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); width: 40px; height: 40px; }
    .back-to-top svg { width: 20px; height: 20px; }
}

/* ============================================================
   移动端性能优化
   ============================================================ */

@media (max-width: 900px) {
    /*
     * background-attachment: fixed 在移动端代价极高：
     * 页面每滚动一帧，浏览器都要重新合成整个背景层，
     * 中低端机上会出现明显掉帧。移动端改为随页面滚动。
     */
    body { background-attachment: scroll; }

    /* blur(90px) 是像素级开销最大的滤镜之一，窄屏上适度减弱 */
    .orb { filter: blur(60px); opacity: 0.4; }

    /* 三个巨型光球在小屏上视觉收益很低，去掉最大的那个 */
    .orb-3 { display: none; }
}


