/* ===================================================================
   东方钟鼎铭例会 · THO 幻想乡展会官网 — 主题样式 v4
   「雾与河」· 直角编辑风（no radii）· 日式底纹 · 硬边框硬投影 ·
   动画系统：启动遮罩 / 滚动显现 / 走马灯 / 幕移
   配色严守需求方色值表
   =================================================================== */

/* ---------- 色板（色值方案表） ---------- */
:root {
    /* 主色 A  荷取水蓝 */
    --lc-blue: #4899CB;
    --lc-blue-dark: #3A7FAE;
    --lc-blue-deep: #2A5F85;
    /* 主色 B  贝子蜃紫 */
    --lc-purple: #9482BC;
    --lc-purple-dark: #7C6BA6;
    /* 辅助色 */
    --lc-green: #579966;
    --lc-gold: #E8D4A8;
    --lc-gold-deep: #9B7B3F;
    --lc-pink: #D8A8BC;
    /* 基底 */
    --lc-mist: #F7F8FB;
    --lc-card: #EEF4F9;
    --lc-white: #FFFFFF;
    /* 文字 */
    --lc-ink: #2C3544;
    --lc-ink-2: #69687C;
    /* 线 / 投影（直角编辑风） */
    --lc-line: rgba(42, 95, 133, 0.20);
    --lc-line-strong: rgba(42, 95, 133, 0.40);
    --lc-hard: 4px 4px 0 rgba(42, 95, 133, 0.16);
    --lc-hard-lg: 7px 7px 0 rgba(42, 95, 133, 0.13);
    --lc-hard-ink: 5px 5px 0 rgba(44, 53, 68, 0.14);
    /* 字体 */
    --lc-serif: 'STSong', 'SimSun', 'Songti SC', 'Noto Serif CJK SC', 'Source Han Serif SC', 'serif';
    --lc-sans: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'Noto Sans CJK SC', 'Source Han Sans SC', 'sans-serif';
    /* 运动 */
    --lc-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

    /* ---- 旧主题变量重映射（兼容既有模板/游戏页） ---- */
    --touhou-red: #C96B84;
    --touhou-dark-red: #A94F68;
    --touhou-deep: #3A4A5E;
    --touhou-gold: #C9A95C;
    --touhou-bright-gold: #9B7B3F;
    --touhou-purple: #9482BC;
    --touhou-cyan: #4899CB;
    --touhou-amber: #E8D4A8;
    --touhou-dark: #132430;
    --touhou-card: #EEF4F9;
    --touhou-card-border: rgba(72, 153, 203, 0.28);
    --touhou-text: #2C3544;
    --touhou-text-dim: #69687C;
    --touhou-category-bg: rgba(148, 130, 188, 0.16);
    --touhou-card-hover-glow: rgba(72, 153, 203, 0.3);
    --touhou-img-overlay: linear-gradient(0deg, rgba(44,53,68,.35) 0%, transparent 45%);
    --touhou-serif: var(--lc-serif);
    --touhou-sans: var(--lc-sans);
    --ease-spring: var(--lc-ease);
    --ease-out-expo: var(--lc-ease);
    --ease-bounce: var(--lc-ease);
}

/* ---------- 全站禁圆角（硬规则：不许用圆角） ---------- */
* { border-radius: 0 !important; }

/* ---------- Bootstrap 语义色 ---------- */
:root {
    --bs-body-bg: #F7F8FB;
    --bs-body-color: #2C3544;
    --bs-primary: #4899CB;
    --bs-primary-rgb: 72, 153, 203;
    --bs-secondary: #69687C;
    --bs-success: #579966;
    --bs-success-rgb: 87, 153, 102;
    --bs-info: #9482BC;
    --bs-warning: #E8D4A8;
    --bs-danger: #A94F68;
    --bs-danger-rgb: 169, 79, 104;
    --bs-light: #EEF4F9;
    --bs-dark: #132430;
    --bs-link-color: #3A7FAE;
    --bs-link-hover-color: #6A6FAE;
}

/* ---------- 基础 ---------- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
    font-family: var(--lc-sans);
    background: var(--lc-blue-deep);
    color: var(--lc-ink);
    min-height: 100vh;
    line-height: 1.75;
    overflow-x: hidden;
}

/* 整页背景 = 原 tho-hero 的深蓝紫渐变（常驻、不随滚动位移） */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -2;
    background-image: linear-gradient(125deg, #2A5F85 0%, #3A7FAE 38%, #6A70B0 74%, #7C6BA6 100%);
}

/* 顶部雾渐隐（mask 点睛，参考 fantasyguide 纹理手法） */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 12% 6%, rgba(72, 153, 203, 0.10) 0%, transparent 55%),
        radial-gradient(ellipse at 88% 20%, rgba(148, 130, 188, 0.12) 0%, transparent 50%),
        radial-gradient(ellipse at 76% 84%, rgba(216, 168, 188, 0.10) 0%, transparent 46%);
    -webkit-mask-image: linear-gradient(to bottom, black 62%, transparent 100%);
    mask-image: linear-gradient(to bottom, black 62%, transparent 100%);
}

::selection { background: rgba(72, 153, 203, 0.26); }
a { color: var(--bs-link-color); text-decoration: none; transition: color .18s var(--lc-ease); }
a:hover { color: var(--bs-link-hover-color); }
h1, h2, h3, h4, h5, h6 {
    font-family: var(--lc-serif);
    color: var(--lc-blue-deep);
    letter-spacing: 2px;
}

/* 漂浮水片/雾粒（直角小方块 · 环境动效） */
.mist-orb-wrap { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.mist-orb {
    position: absolute;
    width: 7px; height: 7px;
    background: linear-gradient(135deg, rgba(72,153,203,0.55), rgba(148,130,188,0.45));
    border: 1px solid rgba(72,153,203,0.35);
    animation: flakeRise var(--t, 26s) linear infinite;
    animation-delay: var(--delay, 0s);
    opacity: 0;
}
.mist-orb.o1 { left: 7%;  bottom: -16px; --t: 30s; --dx: 46px; --delay: 0s;  width: 8px; height: 8px; }
.mist-orb.o2 { left: 28%; bottom: -12px; --t: 23s; --dx: -30px; --delay: 3s; }
.mist-orb.o3 { left: 55%; bottom: -20px; --t: 34s; --dx: 52px; --delay: 7s;  width: 10px; height: 10px; }
.mist-orb.o4 { left: 76%; bottom: -10px; --t: 19s; --dx: -24px; --delay: 5s; background: linear-gradient(135deg, rgba(216,168,188,0.55), rgba(148,130,188,0.4)); }
.mist-orb.o5 { left: 92%; bottom: -18px; --t: 27s; --dx: -38px; --delay: 2s; background: linear-gradient(135deg, rgba(232,212,168,0.6), rgba(72,153,203,0.35)); }
@keyframes flakeRise {
    0%   { transform: translate(0, 0) rotate(0deg); opacity: 0; }
    14%  { opacity: 0.75; }
    88%  { opacity: 0.35; }
    100% { transform: translate(var(--dx, 24px), -108vh) rotate(160deg); opacity: 0; }
}

/* ===================================================================
   背景线条 · 从下到上的光线扰动（全站，位于斜格底纹之上）
   =================================================================== */
/* 斜格底纹平时隐藏；光扫到哪，哪里的底纹显现（头部亮 → 拖尾渐隐） */
/* 缓慢上扫的光带（15s 一道）：斜格纹只在光带里显现。
   写法沿用最初版本（动 mask-position）——按你的要求保留原样。 */
.bg-light-riser {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        /* ① 日式斜格底纹（白色线条 · 被光扫的部分显现） */
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='72' viewBox='0 0 120 72' fill='none'%3E%3Cg stroke='%23FFFFFF' stroke-width='1' opacity='0.46'%3E%3Cpath d='M0,0L120,72'/%3E%3Cpath d='M120,0L0,72'/%3E%3Cpath d='M60,0L60,72'/%3E%3Cpath d='M0,36H120'/%3E%3Cpath d='M2,2H14L20,8H8Z'/%3E%3Cpath d='M108,62H96L90,56H102Z'/%3E%3Cpath d='M52,30H64L70,36H58Z' opacity='0.5'/%3E%3C/g%3E%3Cg stroke='%23FFFFFF' stroke-width='1' opacity='0.28'%3E%3Cpath d='M30,0L30,72'/%3E%3Cpath d='M90,0L90,72'/%3E%3C/g%3E%3C/svg%3E"),
        /* ② 白光罩：全底白光（光束形状由遮罩决定） */
        linear-gradient(180deg, rgba(255,255,255,0.14), rgba(255,255,255,0.22));
    background-repeat: repeat, no-repeat;
    background-size: 120px 72px, 100% 100%;
    /* 扫过式遮罩：更宽的光束 + 更长的间隔（平铺 260vh → 隔约两屏一道） */
    -webkit-mask-image: linear-gradient(to top,
        transparent 0,
        transparent 40%,
        rgba(0, 0, 0, 0.95) 48%,
        rgba(0, 0, 0, 0.60) 62%,
        transparent 74%,
        transparent 100%);
    mask-image: linear-gradient(to top,
        transparent 0,
        transparent 40%,
        rgba(0, 0, 0, 0.95) 48%,
        rgba(0, 0, 0, 0.60) 62%,
        transparent 74%,
        transparent 100%);
    -webkit-mask-size: 100% 260vh;
    mask-size: 100% 260vh;
    -webkit-mask-repeat: repeat;
    mask-repeat: repeat;
    animation: lightScan 15s linear infinite;
    opacity: 1;
}
@keyframes lightScan {
    from { -webkit-mask-position: 0 0; mask-position: 0 0; }
    to   { -webkit-mask-position: 0 -260vh; mask-position: 0 -260vh; }
}

@media (prefers-reduced-motion: reduce) {
    .bg-light-riser { animation: none; display: none; }
}


/* ===================================================================
   启动遮罩（丝滑切换核心，参考 https://fantasyguide.cn/）
   =================================================================== */
.page-veil {
    position: fixed;
    inset: 0;
    z-index: 3000;
    background:
        linear-gradient(120deg, rgba(42,95,133,0.55), rgba(122,104,186,0.55)),
        var(--lc-blue-deep);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    animation: veilOut 2.0s var(--lc-ease) 0.45s forwards;
}
.page-veil .veil-word {
    color: var(--lc-gold);
    letter-spacing: 6px;
    font-family: var(--lc-serif);
    border: 1px solid var(--lc-gold);
    padding: 0.5em 1.6em;
    box-shadow: var(--lc-hard);
    animation: veilWordIn .6s var(--lc-ease) both;
}
@keyframes veilWordIn {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}
@keyframes veilOut {
    to { transform: translateY(-101%); }
}

/* ===================================================================
   滚动显现动画（IntersectionObserver 驱动 .in）
   =================================================================== */
.rev {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity .7s var(--lc-ease), transform .7s var(--lc-ease);
    transition-delay: var(--d, 0s);
    will-change: opacity, transform;
}
.rev.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    .rev { opacity: 1; transform: none; transition: none; }
}

/* 幕移（hero 入场） */
@keyframes curtainIn {
    from { clip-path: inset(0 0 100% 0); }
    to   { clip-path: inset(0 0 0 0); }
}

/* 水纹分隔（流动的高光分隔线） */
.tho-flow-divider {
    position: relative;
    height: 3px;
    margin: 26px auto;
    max-width: 900px;
    overflow: hidden;                     /* 把 200% 宽的渐变压在这一条里 */
}
/* 原为 animation: flowDivide（动 background-position）—— 每帧重绘该元素。
   改成「200% 宽的渐变层平移」：只有 transform，走合成器，不重绘。 */
.tho-flow-divider::before {
    content: '';
    position: absolute; top: 0; bottom: 0; left: 0;
    width: 200%;
    background: linear-gradient(90deg, transparent, var(--lc-blue), var(--lc-purple), var(--lc-pink), transparent);
    animation: flowSlide 6s linear infinite;
}
@keyframes flowSlide { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes flowDivide {
    from { background-position: 0% 0; }
    to   { background-position: 200% 0; }
}

/* ===================================================================
   导航栏（直角 · 描边 · 水蓝）
   =================================================================== */
.navbar {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: var(--lc-blue-deep);
    border-bottom: 3px solid var(--lc-gold);
    box-shadow: 0 4px 0 rgba(42, 95, 133, 0.18);
}
.navbar-brand {
    font-family: var(--lc-serif);
    font-size: 1.26rem;
    font-weight: 800;
    letter-spacing: 3px;
    color: #FFFFFF !important;
    text-shadow: 1px 1px 0 rgba(0,0,0,0.2), 0 0 18px rgba(232,212,168,0.25);
}
.navbar-brand .brand-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; margin-right: 10px;
    background: var(--lc-gold);
    border: 1px solid #fff;
    color: var(--lc-blue-deep);
    font-size: 1rem;
    line-height: 1;
}
.navbar-dark .navbar-nav .nav-link {
    color: rgba(255,255,255,0.90);
    letter-spacing: 1.5px;
    padding: 0.5rem 0.8rem;
    position: relative;
    transition: color .22s var(--lc-ease);
}
/* 导航下划线用的是 ::before，不是 ::after —— 这里踩过坑，别改回去：
   Bootstrap 的下拉箭头正是画在 .dropdown-toggle::after 上的，而这条规则的选择器
   特异性（0,3,1）高于 Bootstrap 的 .dropdown-toggle::after（0,1,1），两者的声明会
   合并到同一个伪元素上：箭头被强行改成 position:absolute + left/right/bottom，
   还继承了这里的 background:var(--lc-pink)。默认 background-clip 是 border-box，
   粉色会从箭头的透明左右边框透出来，于是「游戏与比赛」下方渲染出一块 10x5px 的
   粉色小方块（实测 #D8A8BC 210 设备px + 淡粉白三角 210 设备px），位置还跑到文字左下角。
   换成 ::before 后下划线与箭头各用各的伪元素，互不干扰。 */
.navbar-dark .navbar-nav .nav-link::before {
    content: '';
    position: absolute;
    left: 0.8rem; right: 100%; bottom: 0.32rem;
    height: 2px;
    background: var(--lc-pink);
    transition: right .28s var(--lc-ease);
}
.navbar-dark .navbar-nav .nav-link:hover { color: #FFF; }
.navbar-dark .navbar-nav .nav-link:hover::before { right: 0.8rem; }
.navbar-dark .navbar-nav .nav-link.active {
    color: #FFF;
    background: rgba(232,212,168,0.18);
    outline: 1px solid rgba(255,255,255,0.30);
}
.dropdown-menu {
    background: #FFFFFF;
    border: 1px solid var(--lc-line-strong);
    box-shadow: var(--lc-hard);
}
.dropdown-item { color: var(--lc-ink) !important; }
.dropdown-item:hover { background: rgba(72,153,203,0.10); color: var(--lc-blue-dark) !important; }
.navbar-dark .navbar-toggler { border: 1px solid rgba(255,255,255,0.5); }
.navbar-dark .navbar-toggler-icon { filter: invert(1); }

/* ===================================================================
   按钮（直角 · 平涂 + 硬投影 3D 按压）
   =================================================================== */
.btn {
    font-weight: 600;
    letter-spacing: 0.8px;
    border-radius: 0;
    transition: transform .16s var(--lc-ease), box-shadow .16s var(--lc-ease), background .2s var(--lc-ease), color .2s;
}
.btn-primary {
    background: var(--lc-blue);
    border: 1.5px solid var(--lc-blue-deep);
    color: #FFF;
    box-shadow: var(--lc-hard);
}
.btn-primary:hover, .btn-primary:focus {
    background: var(--lc-blue-dark);
    border-color: var(--lc-blue-deep);
    color: #FFF;
    transform: translate(-2px, -2px);
    box-shadow: 6px 6px 0 rgba(42,95,133,0.20);
}
.btn-primary:active { transform: translate(2px, 2px); box-shadow: 0 0 0 transparent; }
.btn-outline-primary {
    color: var(--lc-blue-dark);
    border: 1.5px solid var(--lc-blue);
    box-shadow: var(--lc-hard);
}
.btn-outline-primary:hover { background: var(--lc-blue); color: #FFF; transform: translate(-2px,-2px); }
.btn-success { background: var(--lc-green); border: 1.5px solid #3F6E49; color: #fff; box-shadow: var(--lc-hard); }
.btn-success:hover { background: #4A8554; color: #fff; transform: translate(-2px,-2px); }
.btn-warning { background: var(--lc-gold); border: 1.5px solid var(--lc-gold-deep); color: var(--lc-ink); }
.btn-outline-secondary { color: var(--lc-ink-2); border: 1.5px solid var(--lc-ink-2); }
.btn-outline-secondary:hover { background: var(--lc-purple); border-color: var(--lc-purple); color: #fff; transform: translate(-2px,-2px); }
.btn-outline-danger { color: var(--lc-dark-red); border: 1.5px solid var(--lc-touhou-red); }
.btn-outline-danger:hover { background: var(--lc-touhou-red); color: #fff; }
.btn-outline-light { color: var(--lc-blue-deep); border: 1.5px solid var(--lc-blue-dark); }
.btn-outline-light:hover { background: rgba(72,153,203,0.12); color: var(--lc-blue-deep); }
.btn-outline-light:hover { transform: translate(-2px,-2px); }

/* 文章描边按钮 */
.btn-touhou-outline {
    display: inline-block;
    padding: 0.55rem 1.4rem;
    border: 1.5px solid var(--lc-blue);
    color: var(--lc-blue-dark) !important;
    background: transparent;
    font-weight: 600;
    box-shadow: var(--lc-hard);
    transition: all .2s var(--lc-ease);
}
.btn-touhou-outline:hover {
    background: var(--lc-blue);
    color: #FFF !important;
    transform: translate(-2px,-2px);
    box-shadow: 5px 5px 0 rgba(42,95,133,0.22);
}

/* ===================================================================
   卡片 · 表 · 表单（直角硬框）
   =================================================================== */
.card {
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-top: 4px solid var(--lc-blue);
    box-shadow: none;
    transition: transform .22s var(--lc-ease), box-shadow .22s var(--lc-ease);
}
.card:hover { transform: translateY(-2px); box-shadow: var(--lc-hard); }
.card-body { color: var(--lc-ink); }
.card-title { color: var(--lc-blue-deep); font-weight: 800; }

.form-label { color: var(--lc-ink); font-weight: 700; letter-spacing: 1px; }
.form-control {
    background: #FFF;
    border: 1.5px solid var(--lc-line-strong);
    color: var(--lc-ink);
    transition: border-color .2s, box-shadow .2s;
}
.form-control:focus {
    border-color: var(--lc-blue);
    box-shadow: var(--lc-hard);
    color: var(--lc-ink);
}
.form-control::placeholder { color: #A9B0BD; }
.form-text { color: var(--lc-ink-2); }
.input-group-text {
    background: rgba(72,153,203,0.12);
    border: 1.5px solid var(--lc-line-strong);
    color: var(--lc-blue-deep);
}

.table { color: var(--lc-ink); }
.table thead th {
    background: var(--lc-blue-deep);
    color: #FFF;
    letter-spacing: 1px;
    border-bottom: 2px solid var(--lc-gold);
}
.table-hover tbody tr:hover { background: rgba(148,130,188,0.10) !important; }
.table-striped tbody tr:nth-of-type(odd) { background: rgba(72,153,203,0.05); }

.badge { letter-spacing: 1px; font-weight: 600; }
.bg-primary { background: var(--lc-blue-dark) !important; }
.bg-success { background: var(--lc-green) !important; }
.bg-info { background: var(--lc-purple) !important; color: #FFF !important; }
.bg-warning { background: var(--lc-gold) !important; color: var(--lc-ink) !important; }
.bg-danger { background: var(--lc-touhou-red) !important; }

.alert { border-left: 5px solid; }
.alert-primary { background: rgba(72,153,203,0.12); color: var(--lc-blue-deep); border-color: rgba(72,153,203,0.4); border-left-color: var(--lc-blue); }
.alert-success { background: rgba(87,153,102,0.12); color: #3F7148; border-left-color: var(--lc-green); }
.alert-warning  { background: rgba(232,212,168,0.28); color: #7A6633; border-left-color: var(--lc-gold-deep); }
.alert-danger   { background: rgba(201,107,132,0.12); color: #8E3F52; border-left-color: var(--lc-touhou-red); }
.alert-info     { background: rgba(148,130,188,0.14); color: #6A5A96; border-left-color: var(--lc-purple); }

.list-group-item { background: #FFFFFF; color: var(--lc-ink); border-color: var(--lc-line); }
.progress { background: #E4ECF4; }
.progress-bar { background: var(--lc-blue); }

/* ===================================================================
   页面共件
   =================================================================== */
.tho-page-head { text-align: center; padding: 34px 0 20px; position: relative; }
.tho-page-head .tho-kicker {
    display: inline-block; padding: 0.3rem 1.3rem;
    background: #FFFFFF; color: var(--lc-blue-deep);
    border: 1px solid var(--lc-gold);
    letter-spacing: 3px; font-size: 0.85rem;
    box-shadow: var(--lc-hard);
}
.tho-page-head h2 {
    font-size: 2.1rem; font-weight: 900; color: #FFFFFF;
    text-shadow: 0 2px 0 rgba(42,95,133,0.55), 0 0 18px rgba(232,212,168,0.28);
    letter-spacing: 4px; margin: 14px 0 6px;
    font-family: var(--lc-serif);
}
.tho-page-head h2::after {
    content: '';
    display: block; width: 90px; height: 4px; margin: 10px auto 0;
    background: linear-gradient(90deg, var(--lc-blue), var(--lc-purple), var(--lc-pink));
    animation: flowDivide 4s linear infinite;
    background-size: 200% 100%;
}
.tho-page-head p { color: rgba(255,255,255,0.82); letter-spacing: 1px; }

/* ---- 编辑式区块（重叠标题 + 直角帧） ---- */
.tho-frame {
    position: relative;
    border: 1px solid var(--lc-line);
    background: rgba(255,255,255,0.94);
    margin-top: 40px;
    padding: 30px 22px 26px;
}
.tho-frame-hl { border-top: 5px solid var(--lc-blue); }
.tho-frame-pl { border-top: 5px solid var(--lc-purple); }
.tho-frame-gl { border-top: 5px solid var(--lc-green); }
.tho-frame-gl2 { border-top: 5px solid var(--lc-gold); }
.tho-frame .ns-tag {
    position: absolute;
    top: -24px; left: 12px;
    background: var(--lc-blue-deep);
    color: var(--lc-gold);
    padding: 8px 16px;
    border: 1px solid var(--lc-gold);
    letter-spacing: 3px;
    font-weight: 800;
    font-family: var(--lc-serif);
    box-shadow: var(--lc-hard);
    display: inline-flex; align-items: center; gap: 8px;
    white-space: nowrap;
}
.tho-frame .ns-tag .ns-en { color: rgba(232,212,168,0.75); font-size: 0.68rem; letter-spacing: 2px; }
.tho-frame .ns-corner::before, .tho-frame .ns-corner::after {
    content: '';
    position: absolute; width: 10px; height: 10px;
}
.tho-frame .ns-corner::before { border-top: 2px solid var(--lc-blue); border-left: 2px solid var(--lc-blue); top: 4px; left: 4px; }
.tho-frame .ns-corner::after { border-bottom: 2px solid var(--lc-pink); border-right: 2px solid var(--lc-pink); bottom: 4px; right: 4px; }

/* 竖排点缀文字（神社意境） */
.tho-vtext {
    writing-mode: vertical-rl;
    text-orientation: upright;
    font-family: var(--lc-serif);
    letter-spacing: 6px;
    color: var(--lc-purple-dark);
    opacity: 0.6;
    user-select: none;
}

/* ===================================================================
   首页 Hero（直角编辑 banner · 底纹 + 幕移）
   =================================================================== */
.tho-hero {
    position: relative;
    margin-top: 26px;
    padding: 64px 38px 56px;
    text-align: center;
    color: var(--lc-ink);
    background:
        linear-gradient(180deg, #FFFFFF 0%, #F7F8FB 55%, #EEF4F9 100%);
    border: 2px solid var(--lc-blue-deep);
    box-shadow: 9px 9px 0 rgba(0,0,0,0.30);
    overflow: hidden;
    animation: curtainIn 1.2s var(--lc-ease) both;
}
/* 斜向格线：原本铺满整个 hero，会糊在两侧角色身上（格线画在 z-index:auto 的伪元素上，
   比 z-index:-1 的人物更高，等于压在人物表面）。改成两件事：
   1) z-index:-1 —— 退到人物之下，人物区域永远不再有格线；
   2) clip-path: circle() —— 只在「以标题为圆心、逐渐放大的圆」里显示格线，圆外就是原本的
      白底（“正常是白色”）；一圈放大完淡出再从零开始，形成缓慢的呼吸/涟漪。
   圆心取 50% 40%（实测标题中心 x 恒为 50%，y 在 42.6%（笔记本档）到 34.9%（会场屏）之间，
   取 40% 两边都照顾到）；半径上限 33%：clip-path 百分比半径的参考长度是
   sqrt(w²+h²)/√2，实测「圆刚好碰到人物实画内缘」的极限是 35.1%~38.7%，33% 留了余量。
   注意别用会过冲的 easing（--lc-ease 带回弹），半径过冲就会压到人物，这里用 ease-out。 */
.tho-hero::before {
    content: '';
    position: absolute; inset: 0;
    z-index: -1;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='72' viewBox='0 0 120 72' fill='none'%3E%3Cg stroke='%234899CB' stroke-width='1' opacity='0.08'%3E%3Cpath d='M0,0L120,72'/%3E%3Cpath d='M120,0L0,72'/%3E%3Cpath d='M60,0L60,72'/%3E%3Cpath d='M0,36H120'/%3E%3C/g%3E%3C/svg%3E");
    background-repeat: repeat;
    /* 原还有 heroPatternDrift（动 background-position）——hero 区域每帧重绘；
       格线只是淡淡一层，缓慢斜移看不出来，故只保留 heroGridBloom 的圆环放大。 */
    animation: heroGridBloom 16s ease-out infinite;
}
@keyframes heroPatternDrift { from { background-position: 0 0; } to { background-position: 120px 72px; } }
@keyframes heroGridBloom {
    0%   { clip-path: circle(0% at 50% 40%);  opacity: 0; }
    8%   { opacity: .95; }
    55%  { clip-path: circle(20% at 50% 40%); opacity: .95; }
    82%  { clip-path: circle(30% at 50% 40%); opacity: .6; }
    100% { clip-path: circle(33% at 50% 40%); opacity: 0; }
}
.tho-hero::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 20% 18%, rgba(72,153,203,0.10) 0%, transparent 45%),
        radial-gradient(ellipse at 84% 20%, rgba(148,130,188,0.12) 0%, transparent 42%),
        radial-gradient(ellipse at 52% 84%, rgba(216,168,188,0.10) 0%, transparent 46%);
    -webkit-mask-image: linear-gradient(to bottom, black, transparent 130%);
    mask-image: linear-gradient(to bottom, black, transparent 130%);
    animation: heroMistDrift 12s ease-in-out infinite alternate;
}
@keyframes heroMistDrift {
    from { transform: translateX(-1.5%); opacity: 0.85; }
    to   { transform: translateX(1.5%); opacity: 1; }
}

/* ===================================================================
   Hero 两侧角色装饰（右：渡里贝子 / 左：河城荷取，左侧水平翻转）
   -------------------------------------------------------------------
   1) 为什么用背景图而不是 <img>：
      hecheng.svg 原始 1.28MB（gzip 后 68KB）。<img> 即使被 CSS 隐藏，浏览器仍会
      把资源下载下来；background-image 挂在 display:none 的元素上则完全不发请求
      —— 手机端因此既不显示也不耗流量（已用 Playwright 统计网络请求验证）。
   2) 为什么尺寸用百分比：装饰要跟着 hero 宽度走，从 1200px 笔记本到 4160px 会场
      大屏成比例放大，不需要为每档分辨率写死像素。
   3) 为什么 z-index:-1：装饰是绝对定位元素，会盖在静态定位的标题文字之上；
      配合 .tho-hero 的 isolation:isolate，-1 让它落在 hero 背景之上、所有文字之下。
   4) 两侧 SVG 画布留白不同（贝子内容约占画布 52%，荷取约 78%），所以给宽一点的
      画布配小一号的尺寸，使两个角色「实际画出来的大小」接近。
   5) 显示门槛 992px（Bootstrap lg）：992–1199 时 hero 宽 856px、文字两侧各余 ~232px，
      装饰实画 ~148/142px，留 80px 以上间隙；低于 992 则余量不足，整块隐藏
      （手机、竖屏平板全部落在此档，且不会发起任何图片请求）。
   6) 浮动：hero-emblem 用的是 emblemBob / 5s（-6px + 旋转），这里刻意错开——
      左右各自 7s 与 9s，且用负 animation-delay 错相位，三者周期两两不同，
      不会出现「一起上下点头」的机械感。振幅写成元素自身高度的百分比，
      于是从笔记本到会场大屏，浮动幅度跟着角色一起等比放大。 */
.tho-hero { isolation: isolate; }
.tho-hero-deco {
    position: absolute;
    z-index: -1;
    top: 50%;
    transform: translateY(-50%);
    aspect-ratio: 1 / 1;                  /* 画面等比，具体缩放交给 .deco-canvas */
    pointer-events: none;
    opacity: 0.92;
}
/* 两侧角色的尺寸/位置：基准档按 hero 宽度百分比；超过 2000px 的宽屏改成
   以「居中文字块」为锚点（--stage-half 是文字块半宽），并且尺寸同时受视口高度约束，
   免得大屏上人被推到画面最边上、还越放越大（用户反馈「有点靠两边了」）。 */
.tho-hero { --stage-half: 430px; --deco-gap: 26px; }
.tho-hero-deco-left {                     /* 河城荷取：水平翻转后放左侧 */
    left: -2%;
    width: min(23%, 41vh);
    --eye-sx: -1;                         /* 镜像侧：注视横向分量取反 */
    transform: translateY(-50%) scaleX(-1);
    animation: heroDecoFloatLeft 7s ease-in-out infinite;
    animation-delay: -2.1s;
}
.tho-hero-deco-right {                    /* 渡里贝子：放右侧 */
    right: -4%;                           /* 加宽后往外让一点，避免压到文字 */
    width: min(33%, 53vh);
    animation: heroDecoFloatRight 9s ease-in-out infinite;
    animation-delay: -3.4s;
}

/* ---------------- 会动的装饰：分件 Live2D 式摆动 ----------------
   性能取舍（这套写法存在的唯一原因）：
   整张 SVG + SMIL 动画 → 浏览器每帧都要重新光栅化整幅图，DevTools 里是刷屏的
   Paint / Update the rendering / RefreshDriver tick。
   现在按部件（头/头发/手臂/裙摆…）切成独立 SVG，各挂一个 <span>，动画只用
   rotate / translate 两个「独立变换属性」→ 全程由合成器算矩阵，不再重绘（Paint 归零）。
   分件的好处：各部分绕自己的关节各摆各的（头发晚半拍、手臂更活、裙摆拖尾），
   而不是整只人一起摇 —— 这是「像 Live2D」的关键。
   注：这些 <span> 落在 display:none 的父元素里，手机端依然一发请求都不发。
   部件几何 / 关节 / 幅度由 .migration-staging/svg_partition.js 生成：
   改完重跑 `node svg_partition.js <char> --write`，把标记段整段贴回，勿手改。 */
.deco-canvas {                            /* 画面坐标系：与原 SVG viewBox 等比、居中留边 */
    position: absolute;
    left: 0;
    top: 50%;
    width: 100%;
    aspect-ratio: var(--canvas-ar, 1);
    transform: translateY(-50%);
}
.tho-hero-deco .p {
    position: absolute;
    background-repeat: no-repeat;
    background-size: 100% 100%;           /* 每份 SVG 的 viewBox 已收紧到该部件包围盒 */
    transform-origin: var(--ox, 50%) var(--oy, 50%);
    will-change: transform;               /* 提示浏览器提升为独立合成层 */
    rotate: 0deg;
    animation: partSway var(--d, 5s) ease-in-out infinite alternate,
               partBob var(--bd, 7s) ease-in-out infinite alternate;
    animation-delay: var(--dl, 0s), var(--dl2, 0s);
}
@keyframes partSway {                     /* 0 → var(--sw) → 0（alternate 折返，近似正弦） */
    from { rotate: 0deg; }
    to   { rotate: var(--sw, 0.5deg); }
}
@keyframes partSwaySym {                  /* 对称摆动：±sw/2（一半向内一半向外） */
    from { rotate: calc(var(--sw, 0.5deg) / -2); }
    to   { rotate: calc(var(--sw, 0.5deg) / 2); }
}
.tho-hero-deco .p.g-sym { animation-name: partSwaySym, partBob; }
@keyframes partBob {                      /* 与摆动不同周期 → 合成出不成环的飘动 */
    from { translate: 0 0; }
    to   { translate: 0 var(--bob, 0%); }
}
/* 注视偏移只挂在眼睛层（--eye-nx/--eye-ny 由 gaze.js 写在容器上，取值 -1~1）。
   translate 是独立属性，正好与眼睛层自己的 rotate 互不干扰；
   --eye-sx：左侧角色整体做过 scaleX(-1)，镜像会把 translate 的横向分量也翻过去。 */
.tho-hero-deco .p-eyes {
    translate: calc(var(--eye-nx, 0) * var(--eye-sx, 1) * var(--emx, 2%))
               calc(var(--eye-ny, 0) * var(--emy, 4%));
}
/* 眨眼：眼睛层内层 .eye-art 做「上下往中间缩放」(scaleY)，
   轴 = 横向眼角(--blink-ox) + 竖向中线(--blink-oy)。纯竖向缩放与轴的横向位置无关，
   但写眼角更贴合「以眼角为轴」；外层 .p-eyes 仍负责几何/摆动/注视，互不干扰。 */
@keyframes eyeBlink {
    0%, 93.5%, 100% { scale: 1 1; }
    95%, 97.5%      { scale: 1 0.08; }
}
.tho-hero-deco .p-eyes {
    animation: partSway var(--d, 5s) ease-in-out infinite alternate;
    animation-delay: var(--dl, 0s);
}
.tho-hero-deco .p-eyes > .eye-art {
    position: absolute;
    inset: 0;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    transform-origin: var(--blink-ox, 50%) var(--blink-oy, 50%);
    animation: eyeBlink var(--blink-d, 4.6s) linear infinite;
    animation-delay: var(--blink-dl, 0s);
}
/* 收敛轴的竖向位置：荷取 51.2%（眼睛在框内偏中）、贝子 59% */
.tho-hero-deco-left  .p-eyes { --blink-ox: 50%; --blink-oy: 51.2%; --blink-d: 4.6s; --blink-dl: -0.4s; }
.tho-hero-deco-right .p-eyes { --blink-ox: 84%; --blink-oy: 59%;   --blink-d: 5.3s; --blink-dl: -2.6s; }
.tho-hero-deco .g-head-track {
    position: absolute; inset: 0;
    /* 左侧角色整体 scaleX(-1) 镜像过，横向分量要跟着翻（用 --eye-sx，和注视同一套） */
    translate: calc(var(--head-nx, 0) * var(--eye-sx, 1) * 0.55%) calc(var(--head-ny, 0) * 0.35%);
    rotate: calc(var(--head-nx, 0) * var(--eye-sx, 1) * 1.8deg);
    transition: translate .18s var(--lc-ease), rotate .18s var(--lc-ease);
    will-change: transform;
}
.tho-hero-deco-left  .g-head-track { transform-origin: 48% 47%; }
.tho-hero-deco-right .g-head-track { transform-origin: 47% 46%; }
.tho-hero-deco .p-eyehappy { opacity: 0; }
.tho-hero-deco.is-hover .p-eyes { opacity: 0 !important; }
.tho-hero-deco.is-hover .p-eyehappy { opacity: 1; }
.tho-hero-deco-left  .p-eyehappy { background-image: url("../img/live2d/hc-eyes-happy.svg?v=ae8b075b4e"); }
.tho-hero-deco-right .p-eyehappy { background-image: url("../img/live2d/bz-eyes-happy.svg?v=ba5ae260aa"); }
.tho-hero-deco-left  { --blink-d: 4.6s; --blink-dl: -0.4s; }
.tho-hero-deco-right { --blink-d: 5.3s; --blink-dl: -2.6s; }
@media (prefers-reduced-motion: reduce) {
    .tho-hero-deco .g-head-track { translate: none; rotate: none; transition: none; }
}
/* >>> live2d-parts: generated by .migration-staging/svg_partition.js --write >>> */
/* 荷取（左）：chibi，动作更活；每件幅度/周期/相位都不同 */
.tho-hero-deco-left .p-hair-l.g-sym { left: 9.99%; top: 19.96%; width: 38.86%; height: 37.96%; --ox: 97.81%; --oy: 15.91%; --sw: 1.42deg; --d: 2.89s; --dl: -1.01s; --bob: 0.47%; --bd: 4.13s; --dl2: -0.94s; }
.tho-hero-deco-left .p-hair-r.g-sym { left: 42.67%; top: 19.92%; width: 43.62%; height: 38.52%; --ox: 12.22%; --oy: 15.8%; --sw: 2.85deg; --d: 2.89s; --dl: -1.01s; --bob: 0.94%; --bd: 4.13s; --dl2: -0.94s; }
.tho-hero-deco-left .p-body { left: 11.47%; top: 12.67%; width: 74.82%; height: 52.45%; --ox: 50.16%; --oy: 94.05%; --sw: 0.96deg; --d: 4.21s; --dl: -0.23s; --bob: 0.38%; --bd: 6.08s; --dl2: -0.4s; }
.tho-hero-deco-left .p-skirt { left: 22.89%; top: 55.13%; width: 49.31%; height: 31.09%; --ox: 50.92%; --oy: 9.23%; --sw: 1.5deg; --d: 3.59s; --dl: -1.17s; --bob: 0.9%; --bd: 5.15s; --dl2: -1.05s; }
.tho-hero-deco-left .p-legs { left: 44.11%; top: 78.9%; width: 21.04%; height: 15.24%; --ox: 27.97%; --oy: -5.89%; --sw: 1.2deg; --d: 2.96s; --dl: -0.78s; --bob: 1.32%; --bd: 4.21s; --dl2: -0.78s; }
.tho-hero-deco-left .p-arm-front { left: 25.74%; top: 43.88%; width: 26.86%; height: 22.59%; --ox: 64.25%; --oy: 22.66%; --sw: 2.25deg; --d: 3.43s; --dl: -2.03s; --bob: 1.06%; --bd: 4.84s; --dl2: -1.65s; }
.tho-hero-deco-left .p-head { left: 29.17%; top: 24.84%; width: 33.14%; height: 26.21%; --ox: 56.83%; --oy: 84.53%; --sw: 1.65deg; --d: 3.28s; --dl: -0.55s; --bob: 0.92%; --bd: 4.6s; --dl2: -0.62s; }
.tho-hero-deco-left .p-hand { left: 56.48%; top: 39.43%; width: 11.94%; height: 11.84%; --ox: 12.75%; --oy: 38.62%; --sw: 4.05deg; --d: 2.65s; --dl: -0.86s; --bob: 2.2%; --bd: 3.67s; --dl2: -0.83s; }
.tho-hero-deco-left .p-flask { left: 62.14%; top: 22.15%; width: 16.88%; height: 20.72%; --ox: -24.55%; --oy: 105.46%; --sw: 1.35deg; --d: 2.81s; --dl: -0.98s; --bob: 0.48%; --bd: 3.74s; --dl2: -0.92s; }
.tho-hero-deco-left .p-hat.g-sym { left: 32.21%; top: 10.67%; width: 41.74%; height: 16.59%; --ox: 37.82%; --oy: 92.4%; --sw: 2.85deg; --d: 2.89s; --dl: -1.01s; --bob: 2.16%; --bd: 4.13s; --dl2: -0.94s; }
.tho-hero-deco-left .p-eyes > .eye-art { background-image: url("../img/live2d/hc-eyes-l.svg?v=7b1946f01f"); }
.tho-hero-deco-left .p-hair-l.g-b { background-image: url("../img/live2d/hc-hair-l-b.svg?v=af14218332"); }
.tho-hero-deco-left .p-hair-l.g-l { background-image: url("../img/live2d/hc-hair-l-l.svg?v=fd6f4bceb3"); }
.tho-hero-deco-left .p-hair-r.g-b { background-image: url("../img/live2d/hc-hair-r-b.svg?v=27f7389cd3"); }
.tho-hero-deco-left .p-hair-r.g-l { background-image: url("../img/live2d/hc-hair-r-l.svg?v=bcd97c344b"); }
.tho-hero-deco-left .p-body.g-b { background-image: url("../img/live2d/hc-body-b.svg?v=2ab75647ee"); }
.tho-hero-deco-left .p-body.g-l { background-image: url("../img/live2d/hc-body-l.svg?v=5943f333d7"); }
.tho-hero-deco-left .p-skirt.g-b { background-image: url("../img/live2d/hc-skirt-b.svg?v=fa58714437"); }
.tho-hero-deco-left .p-skirt.g-l { background-image: url("../img/live2d/hc-skirt-l.svg?v=7ba522bd98"); }
.tho-hero-deco-left .p-legs.g-b { background-image: url("../img/live2d/hc-legs-b.svg?v=5445bee6b4"); }
.tho-hero-deco-left .p-legs.g-l { background-image: url("../img/live2d/hc-legs-l.svg?v=1b04eb5398"); }
.tho-hero-deco-left .p-arm-front.g-b { background-image: url("../img/live2d/hc-arm-front-b.svg?v=e512acd597"); }
.tho-hero-deco-left .p-arm-front.g-l { background-image: url("../img/live2d/hc-arm-front-l.svg?v=e5259d233f"); }
.tho-hero-deco-left .p-head.g-b { background-image: url("../img/live2d/hc-head-b.svg?v=32b5ebc6cb"); }
.tho-hero-deco-left .p-head.g-l { background-image: url("../img/live2d/hc-head-l.svg?v=e26a4c8d53"); }
.tho-hero-deco-left .p-hand.g-b { background-image: url("../img/live2d/hc-hand-b.svg?v=26877fb096"); }
.tho-hero-deco-left .p-hand.g-l { background-image: url("../img/live2d/hc-hand-l.svg?v=2eb427849c"); }
.tho-hero-deco-left .p-flask.g-b { background-image: url("../img/live2d/hc-flask-b.svg?v=3dc17b9a48"); }
.tho-hero-deco-left .p-flask.g-l { background-image: url("../img/live2d/hc-flask-l.svg?v=ee4911a8a7"); }
.tho-hero-deco-left .p-hat.g-b { background-image: url("../img/live2d/hc-hat-b.svg?v=e96afa5c03"); }
.tho-hero-deco-left .p-hat.g-l { background-image: url("../img/live2d/hc-hat-l.svg?v=5977659e59"); }
/* 贝子（右）：整体更安静，但头发与呆毛已经各摆各的 */
.tho-hero-deco-right .p-hair { left: 35.75%; top: 25.56%; width: 37.91%; height: 47.61%; --ox: 56.03%; --oy: 11.42%; --sw: 1.27deg; --d: 3.04s; --dl: -1.64s; --bob: 0.34%; --bd: 4.37s; --dl2: -1.38s; }
.tho-hero-deco-right .p-body { left: 39%; top: 47.55%; width: 21.53%; height: 15.26%; --ox: 51.09%; --oy: 101.21%; --sw: 0.39deg; --d: 4.68s; --dl: -0.31s; --bob: 0.66%; --bd: 6.55s; --dl2: -0.45s; }
.tho-hero-deco-right .p-skirt { left: 37.26%; top: 59.81%; width: 22.42%; height: 14.93%; --ox: 43.46%; --oy: 14.67%; --sw: 0.51deg; --d: 4.21s; --dl: -1.33s; --bob: 0.8%; --bd: 5.62s; --dl2: -1.16s; }
.tho-hero-deco-right .p-arm-front { left: 44.29%; top: 45.41%; width: 23.63%; height: 19.48%; --ox: 83.41%; --oy: 18.43%; --sw: 0.83deg; --d: 3.9s; --dl: -0.86s; --bob: 0.51%; --bd: 5.3s; --dl2: -0.83s; }
.tho-hero-deco-right .p-arm-raise { left: 21.05%; top: 20.61%; width: 17.43%; height: 35.49%; --ox: 51.35%; --oy: 68.72%; --sw: 2.7deg; --d: 3.28s; --dl: -1.95s; --bob: 0.78%; --bd: 4.6s; --dl2: -1.6s; }
.tho-hero-deco-right .p-head { left: 39.33%; top: 28.5%; width: 16.12%; height: 24.18%; --ox: 47.61%; --oy: 72.39%; --sw: 0.63deg; --d: 3.59s; --dl: -0.7s; --bob: 0.5%; --bd: 4.99s; --dl2: -0.73s; }
.tho-hero-deco-right .p-ahoge { left: 40.87%; top: 30.54%; width: 3.59%; height: 2.09%; --ox: -135.75%; --oy: 548.49%; --sw: 1.58deg; --d: 2.57s; --dl: -0.47s; --bob: 8.61%; --bd: 3.67s; --dl2: -0.56s; }
.tho-hero-deco-right .p-bow { left: 48.97%; top: 23.79%; width: 11.16%; height: 11.28%; --ox: 54.06%; --oy: 55.08%; --sw: 1.13deg; --d: 2.73s; --dl: -1.09s; --bob: 1.06%; --bd: 3.98s; --dl2: -1s; }
.tho-hero-deco-right .p-eyes > .eye-art { background-image: url("../img/live2d/bz-eyes-l.svg?v=7bf54b2dcc"); }
.tho-hero-deco-right .p-hair.g-b { background-image: url("../img/live2d/bz-hair-b.svg?v=a33df3fd84"); }
.tho-hero-deco-right .p-hair.g-l { background-image: url("../img/live2d/bz-hair-l.svg?v=4091314939"); }
.tho-hero-deco-right .p-body.g-b { background-image: url("../img/live2d/bz-body-b.svg?v=8ad029053e"); }
.tho-hero-deco-right .p-body.g-l { background-image: url("../img/live2d/bz-body-l.svg?v=b6f2e729ca"); }
.tho-hero-deco-right .p-skirt.g-b { background-image: url("../img/live2d/bz-skirt-b.svg?v=d9b6614ea4"); }
.tho-hero-deco-right .p-skirt.g-l { background-image: url("../img/live2d/bz-skirt-l.svg?v=dbf77da797"); }
.tho-hero-deco-right .p-arm-front.g-l { background-image: url("../img/live2d/bz-arm-front-l.svg?v=340d9605f8"); }
.tho-hero-deco-right .p-arm-raise.g-b { background-image: url("../img/live2d/bz-arm-raise-b.svg?v=df2a961587"); }
.tho-hero-deco-right .p-arm-raise.g-l { background-image: url("../img/live2d/bz-arm-raise-l.svg?v=a5cf06ddcf"); }
.tho-hero-deco-right .p-head.g-b { background-image: url("../img/live2d/bz-head-b.svg?v=5290acd1ea"); }
.tho-hero-deco-right .p-head.g-l { background-image: url("../img/live2d/bz-head-l.svg?v=d1758d301a"); }
.tho-hero-deco-right .p-ahoge.g-b { background-image: url("../img/live2d/bz-ahoge-b.svg?v=dd3215f5e6"); }
.tho-hero-deco-right .p-bow.g-b { background-image: url("../img/live2d/bz-bow-b.svg?v=9b10c47395"); }
.tho-hero-deco-right .p-bow.g-l { background-image: url("../img/live2d/bz-bow-l.svg?v=b13830c98a"); }
/* <<< live2d-parts <<< */
/* 关键帧里必须带完整的 transform（居中 + 左侧翻转），否则动画一跑就把定位/翻转冲掉 */
@keyframes heroDecoFloatLeft {
    0%, 100% { transform: translateY(-50%) scaleX(-1); }
    50%      { transform: translateY(calc(-50% - 2.6%)) scaleX(-1); }
}
@keyframes heroDecoFloatRight {
    0%, 100% { transform: translateY(-50%); }
    50%      { transform: translateY(calc(-50% - 2.4%)); }
}
@media (min-width: 2000px) {              /* 超宽屏：收到文字两侧，不再贴画面边缘 */
    .tho-hero-deco-left  { left: auto; right: calc(50% + var(--stage-half) + var(--deco-gap)); }
    .tho-hero-deco-right { right: auto; left:  calc(50% + var(--stage-half) + var(--deco-gap)); }
}
@media (max-width: 991.98px) {
    .tho-hero-deco { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .tho-hero-deco, .tho-hero-deco .p { animation: none; }
    /* 不做呼吸式放大：固定一个中等大小的圆，格线仍在但完全静止 */
    .tho-hero::before { animation: none; clip-path: circle(22% at 50% 40%); opacity: 1; }
}
.tho-hero .hero-emblem {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 76px; height: 76px;
    background: var(--lc-gold);
    border: 2px solid var(--lc-blue-deep);
    color: var(--lc-blue-deep);
    font-size: 2rem;
    box-shadow: 0 12px 0 -4px rgba(42,95,133,0.22);
    animation: emblemBob 5s ease-in-out infinite;
    margin-bottom: 16px;
}
@keyframes emblemBob {
    0%, 100% { transform: translateY(0) rotate(-1deg); }
    50%      { transform: translateY(-6px) rotate(1deg); }
}
.tho-hero h1 {
    position: relative;
    font-size: 3rem;
    font-weight: 900;
    letter-spacing: 8px;
    color: var(--lc-blue-deep);
    font-family: var(--lc-serif);
    text-shadow: 0 2px 0 rgba(255,255,255,0.6);
    margin-bottom: 12px;
    animation: heroTitleIn 0.7s var(--lc-ease) 0.15s both;
}
@keyframes heroTitleIn { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
.tho-hero .hero-sub {
    position: relative;
    font-size: 1.12rem;
    letter-spacing: 4px;
    color: var(--lc-purple-dark);
    margin-bottom: 22px;
    animation: heroTitleIn 0.7s var(--lc-ease) 0.28s both;
}
.tho-hero .hero-host {
    position: relative;
    display: inline-block;
    margin-bottom: 22px;
    padding: 0.3rem 1.6rem;
    background: rgba(72,153,203,0.10);
    border: 1px solid rgba(42,95,133,0.35);
    color: var(--lc-blue-deep);
    font-size: 0.92rem; letter-spacing: 3px;
    box-shadow: 2px 2px 0 rgba(42,95,133,0.18);
    animation: heroTitleIn 0.7s var(--lc-ease) 0.32s both;
}
.tho-hero .hero-rule {
    position: relative;
    display: flex; align-items: center; gap: 10px;
    justify-content: center;
    margin-bottom: 22px;
    color: var(--lc-purple);
    animation: heroTitleIn 0.7s var(--lc-ease) 0.36s both;
}
.tho-hero .hero-rule::before, .tho-hero .hero-rule::after {
    content: ''; height: 1px; width: 120px;
    background: linear-gradient(90deg, transparent, rgba(72,153,203,0.5));
}
.tho-hero .hero-rule::after { background: linear-gradient(90deg, rgba(72,153,203,0.5), transparent); }
.tho-hero .hero-tags {
    position: relative;
    display: flex; justify-content: center; gap: 2px; flex-wrap: wrap;
    margin-bottom: 30px;
}
.tho-hero .hero-tag {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 0.4rem 1.1rem;
    background: rgba(72,153,203,0.07);
    border: 1px solid rgba(42,95,133,0.40);
    font-size: 0.86rem; color: var(--lc-blue-deep); letter-spacing: 1px;
    transition: background .2s, transform .2s;
}
.tho-hero .hero-tag:hover { background: rgba(72,153,203,0.16); transform: translateY(-2px); }
.tho-hero .hero-actions { position: relative; display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; }
.tho-hero .btn-hero-primary {
    padding: 0.72rem 2.1rem;
    background: var(--lc-gold);
    border: 2px solid var(--lc-gold-deep);
    color: var(--lc-blue-deep);
    font-weight: 800; letter-spacing: 2px;
    box-shadow: 4px 4px 0 rgba(42,95,133,0.35);
    transition: transform .16s var(--lc-ease), box-shadow .16s var(--lc-ease);
}
.tho-hero .btn-hero-primary:hover { transform: translate(-2px,-2px); box-shadow: 6px 6px 0 rgba(42,95,133,0.40); color: var(--lc-blue-deep); }
.tho-hero .btn-hero-primary:active { transform: translate(2px,2px); box-shadow: 0 0 0; }
.tho-hero .btn-hero-ghost {
    padding: 0.72rem 1.9rem;
    background: transparent;
    border: 2px solid var(--lc-blue);
    color: var(--lc-blue-dark); font-weight: 700; letter-spacing: 2px;
    box-shadow: 4px 4px 0 rgba(42,95,133,0.22);
    transition: transform .16s var(--lc-ease), background .2s;
}
.tho-hero .btn-hero-ghost:hover { background: rgba(72,153,203,0.12); color: var(--lc-blue-deep); transform: translate(-2px,-2px); }
.tho-hero .hero-welcome {
    position: relative; margin-top: 22px;
    color: var(--lc-ink-2); font-size: 0.95rem; letter-spacing: 1px;
}
.tho-hero .hero-welcome strong { color: var(--lc-purple-dark); }

/* 展会信息条（硬直角块） */
.tho-info-strip { display: grid; gap: 0; margin-top: 26px; }
@media (min-width: 768px) { .tho-info-strip { grid-template-columns: repeat(3, 1fr); } }
.tho-info-card {
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-left: none;
    padding: 20px 22px;
    text-align: center;
    box-shadow: var(--lc-hard);
    transition: transform .22s var(--lc-ease);
}
.tho-info-card:first-child { border-left: 1px solid var(--lc-line); }
.tho-info-card:hover { transform: translateY(-3px); }
.tho-info-card .ic {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px;
    background: var(--lc-blue-deep);
    color: var(--lc-gold);
    font-size: 1.3rem;
    margin-bottom: 8px;
}
.tho-info-card h5 { font-size: 1.02rem; font-weight: 800; color: var(--lc-blue-deep); margin-bottom: 2px; }
.tho-info-card p { margin: 0; color: var(--lc-ink-2); font-size: 0.9rem; }

/* ===================================================================
   例会日程（直角时间线）
   =================================================================== */
.tho-timeline { position: relative; margin-left: 4px; }
.tho-timeline::before {
    content: '';
    position: absolute; left: 7px; top: 4px; bottom: 4px; width: 1px;
    background: var(--lc-blue);
}
.tho-timeline-item {
    position: relative;
    display: flex; gap: 14px; align-items: flex-start;
    padding: 14px 18px;
    margin-bottom: 12px;
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    transition: transform .22s var(--lc-ease), box-shadow .22s;
}
.tho-timeline-item:hover { transform: translateX(4px); box-shadow: var(--lc-hard); }
.tho-timeline-item .t-dot {
    position: absolute; left: -14px; top: 20px;
    width: 15px; height: 15px;
    background: var(--lc-blue);
    border: 1px solid var(--lc-blue-deep);
}
/* 原来是 animation: dotPulse（动 box-shadow）—— 每帧都要重绘，首页 8 个时间线圆点
   = 每帧 8 次 Paint（实测 2 秒 970 次，是页面上最大的 Paint 来源）。
   改成 ::after 上的「扩散圆环」：只动 transform + opacity，走合成器，不重绘。 */
.tho-timeline-item .t-dot::after {
    content: '';
    position: absolute; inset: -2px;
    border-radius: 2px;                    /* 跟随站点的直角设计（原来 box-shadow 也是方的） */
    border: 2px solid rgba(72, 153, 203, 0.55);
    animation: dotPing 3s ease-out infinite;
    pointer-events: none;
}
@keyframes dotPing {
    0%        { transform: scale(0.5); opacity: 0.9; }
    70%, 100% { transform: scale(2.1); opacity: 0; }
}
@keyframes dotPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(72,153,203,0.5);} 50% { box-shadow: 0 0 0 7px rgba(72,153,203,0); } }
.tho-timeline-item .t-date {
    flex-shrink: 0; min-width: 92px;
    font-family: var(--lc-serif);
    font-weight: 800; color: var(--lc-purple-dark);
    background: rgba(148,130,188,0.10);
    border: 1px solid var(--lc-purple);
    padding: 2px 10px; height: fit-content;
    text-align: center; font-size: 0.95rem; letter-spacing: 1px;
}
.tho-timeline-item .t-body h5 { margin: 0; font-size: 1.05rem; font-weight: 800; color: var(--lc-blue-deep); }
.tho-timeline-item .t-body p { margin: 4px 0 0; color: var(--lc-ink-2); font-size: 0.88rem; }
.tho-timeline-item .t-badge { display: inline-block; margin-left: 8px; padding: 2px 9px;
    font-size: 0.74rem; letter-spacing: 1px; vertical-align: 1px; border: 1px solid; }
.t-badge.b-open { background: rgba(87,153,102,0.12); color: #3F6E49; border-color: #579966; }
.t-badge.b-soon { background: rgba(148,130,188,0.12); color: #6A5A96; border-color: #9482BC; }
.t-badge.b-live  { background: rgba(72,153,203,0.12); color: #2A5F85; border-color: #4899CB; }
.t-badge.b-done  { background: rgba(105,104,124,0.12); color: #5A5A6A; border-color: #69687C; }

/* ===================================================================
   活动介绍卡片
   =================================================================== */
.tho-act-card {
    position: relative;
    height: 100%;
    padding: 20px 20px 22px;
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-bottom: 4px solid transparent;
    box-shadow: var(--lc-hard);
    transition: transform .22s var(--lc-ease), box-shadow .22s;
    display: flex; flex-direction: column;
    overflow: hidden;
}
.tho-act-card::after {
    content: '';
    position: absolute; bottom: 0; left: 0; width: 28%; height: 4px;
    background: linear-gradient(90deg, var(--lc-blue), var(--lc-purple));
    transition: width .3s var(--lc-ease);
}
.tho-act-card:hover { transform: translateY(-4px); box-shadow: var(--lc-hard-lg); }
.tho-act-card:hover::after { width: 100%; }
.tho-act-card .act-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 50px; height: 50px;
    background: var(--lc-blue-deep);
    border: 1px solid var(--lc-gold);
    color: var(--lc-gold);
    font-size: 1.5rem;
    margin-bottom: 12px;
    transition: transform .3s var(--lc-ease);
}
.tho-act-card:hover .act-icon { transform: rotate(-4deg) scale(1.06); }
.tho-act-card h5 { font-weight: 800; color: var(--lc-blue-deep); margin-bottom: 6px; }
.tho-act-card p { color: var(--lc-ink-2); font-size: 0.9rem; flex-grow: 1; }
.tho-act-card .act-meta { font-size: 0.8rem; color: var(--lc-purple-dark); margin-top: 8px; letter-spacing: 0.5px; }
.tho-act-card a.act-link {
    display: inline-flex; align-items: center; gap: 6px;
    margin-top: 10px; font-weight: 700; color: var(--lc-blue-dark); font-size: 0.92rem;
    position: relative;
}
.tho-act-card a.act-link::after { content: '→'; transition: transform .22s var(--lc-ease); }
.tho-act-card a.act-link:hover { color: var(--lc-purple-dark); }
.tho-act-card a.act-link:hover::after { transform: translateX(5px); }

/* ===================================================================
   幻想乡新闻（杂志式 · 直角）
   =================================================================== */
.tho-news-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.tho-news-head .tabs { display: flex; gap: 0; flex-wrap: wrap; }
.tho-news-head .tab {
    padding: 0.3rem 1rem;
    background: rgba(72,153,203,0.08); color: var(--lc-ink-2);
    border: 1px solid var(--lc-line);
    font-size: 0.85rem;
}
.tho-news-head .tab.active { background: var(--lc-blue); color: #FFF; border-color: var(--lc-blue-deep); }

.tho-news-hero-card {
    display: grid;
    grid-template-columns: 5fr 4fr;
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-top: 5px solid var(--lc-blue);
    box-shadow: var(--lc-hard);
    overflow: hidden;
    transition: transform .25s var(--lc-ease), box-shadow .25s;
}
.tho-news-hero-card:hover { transform: translate(-2px,-2px); box-shadow: 8px 8px 0 rgba(42,95,133,0.16); }
.tho-news-hero-card .img-wrap { position: relative; min-height: 230px; overflow: hidden; }
.tho-news-hero-card .img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s var(--lc-ease); }
.tho-news-hero-card:hover .img-wrap img { transform: scale(1.05); }
.tho-news-hero-card .img-wrap .banner {
    position: absolute; top: 12px; left: 12px;
    padding: 0.2rem 0.8rem;
    background: var(--lc-blue-deep);
    border: 1px solid var(--lc-gold);
    color: var(--lc-gold); font-size: 0.75rem; letter-spacing: 1px;
}
/* 头条长条不参与遮幕：图 + 文并排常显 */
.tho-news-hero-card .body { padding: 24px 26px; display: flex; flex-direction: column; }
.tho-news-hero-card .body .cat { color: var(--lc-purple-dark); font-size: 0.8rem; letter-spacing: 2px; }
.tho-news-hero-card .body h4 { font-weight: 900; color: var(--lc-blue-deep); margin: 8px 0 10px; line-height: 1.3; }
.tho-news-hero-card .body p.desc { color: var(--lc-ink-2); font-size: 0.92rem; flex-grow: 1; }
.tho-news-hero-card .body .meta { display: flex; gap: 14px; color: var(--lc-ink-2); font-size: 0.8rem;
    border-top: 1px dashed var(--lc-line); padding-top: 10px; }
.tho-news-hero-card .body .meta .src { color: var(--lc-blue-dark); font-weight: 700; }
@media (max-width: 720px) { .tho-news-hero-card { grid-template-columns: 1fr; } .tho-news-hero-card .img-wrap { min-height: 170px; } }

.tho-news-grid { display: grid; gap: 0; margin-top: 24px; }
@media (min-width: 768px) { .tho-news-grid { grid-template-columns: repeat(3, 1fr); gap: 18px 0; } }
.tho-news-card {
    position: relative;
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-left: 5px solid var(--lc-purple);
    box-shadow: var(--lc-hard);
    transition: transform .22s var(--lc-ease), box-shadow .22s;
    height: 250px;
    overflow: hidden;
}
.tho-news-card:hover { transform: translateY(-3px); box-shadow: var(--lc-hard-lg); }
/* 图片铺满整卡，先“遮住”文字 */
.tho-news-card .img-wrap { position: absolute; inset: 0; overflow: hidden; }
.tho-news-card .img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s var(--lc-ease); }
.tho-news-card:hover .img-wrap img { transform: scale(1.06); }
.tho-news-card .img-wrap .ph {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--lc-card);
    font-size: 2rem; color: var(--lc-blue);
}
/* 文字面板：默认藏在底部，悬停时弹出覆盖图片 */
.tho-news-card .body {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 14px 16px;
    background: linear-gradient(to top, #FFFFFF 0%, #EEF4F9 100%);
    border-top: 2px solid var(--lc-purple);
    transform: translateY(101%);
    transition: transform .4s var(--lc-ease);
}
.tho-news-card:hover .body { transform: translateY(0); }
.tho-news-card .body .cat { color: var(--lc-purple-dark); font-size: 0.76rem; letter-spacing: 2px; }
.tho-news-card .body h5 { font-size: 0.98rem; font-weight: 800; color: var(--lc-blue-deep); margin: 7px 0 6px; line-height: 1.4; }
.tho-news-card .body .desc { color: var(--lc-ink-2); font-size: 0.84rem; margin-bottom: 8px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tho-news-card .body .meta { display: flex; gap: 10px; color: var(--lc-ink-2); font-size: 0.78rem;
    border-top: 1px dashed var(--lc-line); padding-top: 8px; }
.tho-news-card .body .meta .src { color: var(--lc-blue-dark); font-weight: 700; }

/* ---- 手机 / 触屏：无悬停，小卡图片与文字直接铺开正常显示（头条长条保持并排） ---- */
@media (hover: none) {
    .tho-news-card { height: auto; }
    .tho-news-card .img-wrap { position: static; }
    .tho-news-card .img-wrap img { height: 160px; }
    .tho-news-card .img-wrap .ph { position: static; height: 160px; width: 100%; border-bottom: 1px solid var(--lc-line); }
    .tho-news-card .body { position: static; transform: none; border-top: none; background: #FFFFFF; }
}

/* ===================================================================
   文章详情页
   =================================================================== */
.reading-progress-container { position: fixed; top: 0; left: 0; right: 0; height: 4px; z-index: 2000; }
.reading-progress-bar {
    height: 100%; width: 0%;
    background: linear-gradient(90deg, var(--lc-blue), var(--lc-purple), var(--lc-pink));
    background-size: 200% 100%;
    animation: flowDivide 4s linear infinite;
}
.news-article-card {
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-top: 6px solid var(--lc-blue);
    box-shadow: var(--lc-hard);
    padding: 34px;
    margin-top: 24px;
}
.news-detail-header { text-align: center; }
.news-detail-header .cat {
    display: inline-block; margin-bottom: 12px; padding: 0.28rem 1.1rem;
    background: var(--lc-blue-deep);
    border: 1px solid var(--lc-gold);
    color: var(--lc-gold);
    font-size: 0.82rem; letter-spacing: 2px;
}
.news-detail-title { font-size: 1.9rem; font-weight: 900; color: var(--lc-blue-deep); letter-spacing: 2px; line-height: 1.35; }
.news-detail-subtitle { color: var(--lc-ink-2); font-size: 1.02rem; margin: 10px auto 16px; max-width: 660px; }
.news-detail-meta { display: flex; justify-content: center; gap: 18px; flex-wrap: wrap; color: var(--lc-ink-2); font-size: 0.85rem;
    border-top: 1px dashed var(--lc-line); border-bottom: 1px dashed var(--lc-line); padding: 10px 0; }
.news-detail-meta span.strong { color: var(--lc-blue-dark); font-weight: 700; }
.news-detail-cover img {
    width: 100%;
    height: auto;          /* 等比缩放：高度随宽度自适应 ✗ */
    max-height: none;      /* 不再限高 ✗（原 380px 会把大图裁掉 ✗） */
    object-fit: contain;   /* 兜底：缩放而非裁剪 ✅ */
    border: 2px solid var(--lc-line-strong);
    box-shadow: var(--lc-hard-lg);
}
.news-detail-body { color: var(--lc-ink); font-size: 1.02rem; line-height: 1.95; }
.news-detail-body p { margin-bottom: 1.1em; }
.news-detail-body strong { color: var(--lc-blue-deep); }
/* 正文插图：自适应栏宽。
   原先没有这条规则，文章里的 1200px 原图会直接撑破栏目（/news/twc2026 即如此）。 */
.news-detail-body img {
    max-width: 100%;
    height: auto;
    display: block;
    margin: 1.2rem auto;
    border-radius: 8px;
}
/* 同一段落里的两张并排插图（twc2026「参赛角色群像」）：宽屏各占一半，窄屏自动堆叠 */
.news-detail-body p > .news-detail-inline-img {
    display: inline-block;
    width: calc(50% - 5px);
    vertical-align: top;
    margin: 1rem 0;
}
.news-detail-body p > .news-detail-inline-img + .news-detail-inline-img { margin-left: 10px; }
.news-detail-footer {
    margin-top: 26px; padding-top: 16px;
    border-top: 1.5px solid var(--lc-line-strong);
    color: var(--lc-ink-2); font-size: 0.88rem;
}

/* ===================================================================
   认证 / 查询（直角硬框）
   =================================================================== */
.tho-auth-card {
    max-width: 580px; margin: 30px auto 0;
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-top: 6px solid var(--lc-blue);
    box-shadow: var(--lc-hard);
    padding: 32px;
}
.tho-auth-card .auth-emblem {
    display: inline-flex; align-items: center; justify-content: center;
    width: 60px; height: 60px;
    background: var(--lc-blue-deep);
    border: 1px solid var(--lc-gold);
    color: var(--lc-gold);
    font-size: 1.8rem;
    box-shadow: var(--lc-hard);
    margin-bottom: 12px;
    animation: emblemBob 6s ease-in-out infinite;
}
.tho-auth-card h3 { font-weight: 900; color: var(--lc-blue-deep); letter-spacing: 2px; font-family: var(--lc-serif); }
.tho-auth-card .sub { color: var(--lc-ink-2); font-size: 0.9rem; }
.tho-auth-card .key-chip {
    font-family: monospace; letter-spacing: 3px;
    color: var(--lc-blue-deep); background: var(--lc-card);
    border: 1px dashed var(--lc-blue);
    padding: 0.3rem 0.8rem;
}
.tho-result-banner { padding: 16px; text-align: center; border-top: 4px solid; }
.tho-result-banner.win  { background: rgba(87,153,102,0.10); border-color: var(--lc-green); color: #3F7148; }
.tho-result-banner.lose { background: rgba(201,107,132,0.08); border-color: var(--lc-touhou-red); }
.tho-result-banner.wait { background: rgba(148,130,188,0.12); border-color: var(--lc-purple); }
.tho-result-banner.info { background: rgba(72,153,203,0.10); border-color: var(--lc-blue); }

.winner-card { border: 1px solid var(--lc-line); border-top: 4px solid #B89B55; overflow: hidden; }
.winner-card .card-body { background: #FFFFFF; }
.winner-card h3 { font-weight: 900; }
.winner-card .prize-emoji { font-size: 3rem; }
.prize-level-0 { border-top-color: #69D2E7; }
.prize-level-1 { border-top-color: #B89B55; }
.prize-level-2 { border-top-color: var(--lc-ink-2); }
.prize-level-3 { border-top-color: #C98A62; }

/* ===================================================================
   页脚 + 走马灯
   =================================================================== */
.tho-footer {
    margin-top: 70px;
    text-align: center;
    color: var(--lc-ink-2);
    position: relative;
    background: var(--lc-card);
    border-top: 1px solid var(--lc-line);
}
.tho-ticker {
    overflow: hidden;
    border-bottom: 1px solid var(--lc-line);
    background: var(--lc-blue-deep);
    color: var(--lc-gold);
    font-size: 0.85rem;
    letter-spacing: 2px;
    white-space: nowrap;
    position: relative;
}
.tho-ticker .track {
    display: inline-block;
    padding: 8px 0;
    white-space: nowrap;
    animation: tickerMove 26s linear infinite;
}
.tho-ticker .track span { margin: 0 3rem; }
@keyframes tickerMove { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.tho-footer .foot-main { padding: 28px 0 22px; }
.tho-footer .foot-brand { font-family: var(--lc-serif); font-weight: 900; color: var(--lc-blue-deep); letter-spacing: 4px; font-size: 1.1rem; }
.tho-footer .foot-note { font-size: 0.84rem; margin-top: 6px; letter-spacing: 1px; }
.tho-footer .foot-host { margin-top: 8px; font-size: 0.88rem; letter-spacing: 3px; color: var(--lc-purple-dark); font-weight: 600; }
.tho-footer small { opacity: 0.82; }

/* 回到顶部 */
.back-top {
    position: fixed; right: 20px; bottom: 20px; z-index: 1060;
    width: 44px; height: 44px;
    background: var(--lc-blue-deep);
    border: 1px solid var(--lc-gold);
    color: var(--lc-gold); font-size: 1.1rem;
    box-shadow: var(--lc-hard);
    opacity: 0; pointer-events: none;
    transition: opacity .3s, transform .2s, box-shadow .2s;
}
.back-top.show { opacity: 1; pointer-events: auto; }
.back-top:hover { transform: translate(-2px,-2px); }

/* ===================================================================
   兼容类
   =================================================================== */
.text-muted { color: var(--lc-ink-2) !important; }
.bg-purple { background: var(--lc-purple) !important; color: #FFF !important; }
.table-dark { --bs-table-bg: #132430; --bs-table-color: #E8F1F8; }

.home-hero { text-align: center; padding: 18px 0 6px; }
.home-hero-emblem {
    display: inline-flex; align-items: center; justify-content: center;
    width: 62px; height: 62px;
    background: var(--lc-gold);
    border: 1px solid var(--lc-blue-deep);
    color: var(--lc-blue-deep);
    font-size: 1.8rem;
    box-shadow: 4px 4px 0 rgba(0,0,0,0.3);
    animation: emblemBob 6s ease-in-out infinite;
}
.home-hero-title {
    font-family: var(--lc-serif);
    font-size: 2rem; font-weight: 900; color: #FFFFFF;
    text-shadow: 0 2px 0 rgba(42,95,133,0.55), 0 0 16px rgba(232,212,168,0.3);
    letter-spacing: 6px; margin: 14px 0 6px;
}
.home-hero-title::after {
    content: ''; display: block; width: 80px; height: 3px; margin: 10px auto 0;
    background: linear-gradient(90deg, var(--lc-gold), var(--lc-pink));
}
.home-hero-subtitle { color: var(--lc-gold); letter-spacing: 3px; font-size: 1rem; text-shadow: 0 1px 0 rgba(0,0,0,0.3); }

/* 响应式微调 */
@media (max-width: 576px) {
    .tho-hero { padding: 44px 18px 42px; }
    .tho-hero h1 { font-size: 1.9rem; letter-spacing: 4px; }
    .tho-page-head h2 { font-size: 1.6rem; }
    .news-article-card { padding: 18px; }
    .tho-frame { padding: 22px 14px 20px; }

    /* 例会日程：窄屏改为「时间在上、正文在下」的上下排版
       （默认是 .t-date(92px) + .t-body 横排，手机上正文被压得过窄） */
    .tho-timeline-item {
        flex-direction: column;
        gap: 8px;
        padding: 12px 14px;
    }
    .tho-timeline-item .t-date {
        min-width: 0;
        align-self: flex-start;
        font-size: 0.86rem;
    }
    .tho-timeline-item:hover { transform: none; }
    .tho-timeline-item .t-body h5 { font-size: 1rem; }
    .tho-timeline-item .t-body p { font-size: 0.86rem; }

    /* 正文并排插图在手机上改为上下堆叠、满宽 */
    .news-detail-body p > .news-detail-inline-img {
        display: block;
        width: 100%;
        margin: 10px 0 0;
    }
    .news-detail-body p > .news-detail-inline-img + .news-detail-inline-img { margin-left: 0; }
}

/* ===================================================================
   管理后台可读性修正（浅底深字主题）
   -------------------------------------------------------------------
   背景：管理页当初按「深色主题」取色——亮金标题、亮绿/亮青数字、
   深灰小字、浅色描边按钮。站点 v4 改成「浅底深字」后：
     · --lc-touhou-red / --lc-dark-red 两个变量从未定义，导致
       .bg-danger / .btn-outline-danger / .alert-danger 的 !important
       声明在计算值阶段失效 → 红底徽章变「白字 + 透明底」= 白字白底；
     · 亮色数字（#4CAF50 / #00FFFF / #FFD700 …）压在白卡片上对比度仅
       1.2~2.8，基本看不清；
     · 页面标题区直接压在深蓝页面上，深金标题 / 深灰说明同样看不清。
   本区块补齐变量、给出浅底可读强调色，并提供管理页标题面板与
   「深底上的描边按钮」两个组件。
   =================================================================== */

/* 1) 补齐缺失的旧主题变量别名 + 浅底可读强调色 */
:root {
    /* 旧写法别名（.bg-danger/.btn-outline-danger/.alert-danger 依赖） */
    --lc-touhou-red: #A94F68;
    --lc-dark-red: #A94F68;
    /* 浅底（白卡片）上使用的深色强调色，对白底对比度均 ≥ 5 */
    --lc-green-deep: #2E7D32;
    --lc-cyan-deep: #1E6E85;
    --lc-purple-deep: #6E5A9E;
    --lc-gold-ink: #8A6A22;
    --lc-bronze: #8A5522;
    --lc-red-deep: #C62828;
    /* 深色表格里使用的浅色（原 --touhou-text-dim / 亮绿等在深底才好用） */
    --lc-dim-on-dark: #A9B7C6;
    --lc-cyan-on-dark: #8FE0EE;
}

/* 2) 管理页标题面板：把深色标题/说明/描边按钮放到浅底上 */
.admin-hero {
    background: #FFFFFF;
    border: 1px solid var(--lc-line);
    border-top: 4px solid var(--lc-blue);
    box-shadow: var(--lc-hard);
    padding: 18px 20px 16px;
    margin-bottom: 20px;
}
.admin-hero h3 { margin-bottom: 6px; }
.admin-hero .hero-sub { color: var(--lc-ink-2); margin-bottom: 0; }

/* 3) 深蓝页面上的描边按钮（返回后台 / 排名管理 / 重置 等） */
.btn-on-dark {
    color: #EAF3FA;
    background: transparent;
    border: 1.5px solid rgba(255, 255, 255, 0.6);
    box-shadow: none;
}
.btn-on-dark:hover, .btn-on-dark:focus {
    color: #FFFFFF;
    background: rgba(255, 255, 255, 0.16);
    border-color: #FFFFFF;
    transform: translate(-2px, -2px);
}

/* 4) 浅底上的金色描边按钮：Bootstrap 的 #FFC107 在白底几乎看不见 */
.btn-outline-warning {
    color: var(--lc-gold-ink);
    border: 1.5px solid var(--lc-gold-ink);
    box-shadow: var(--lc-hard);
}
.btn-outline-warning:hover, .btn-outline-warning:focus {
    background: var(--lc-gold-ink);
    border-color: var(--lc-gold-ink);
    color: #FFFFFF;
    transform: translate(-2px, -2px);
}

/* 5) 管理页长表格容器（迁移时整块丢失：只剩 max-height，没有 overflow，
      行会溢出压住下一张卡片）——恢复「固定高度 + 内部滚动 + 表头吸顶」 */
.key-table-container {
    max-height: 520px;
    overflow-y: auto;
    overflow-x: auto;
    border: 1px solid var(--lc-line);
}
.key-table-container thead { position: sticky; top: 0; z-index: 2; }
.key-table-container::-webkit-scrollbar { width: 8px; height: 8px; }
.key-table-container::-webkit-scrollbar-track { background: var(--lc-mist); }
.key-table-container::-webkit-scrollbar-thumb { background: var(--lc-line-strong); }
.key-table-container::-webkit-scrollbar-thumb:hover { background: var(--lc-blue); }

/* 4b) 深色表格（.table-dark）里的描边小按钮同样要换浅色 */
.table-dark .btn-outline-danger { color: #F0A0B4; border-color: #F0A0B4; }
.table-dark .btn-outline-danger:hover { background: #F0A0B4; border-color: #F0A0B4; color: #2A1119; }
.table-dark .btn-outline-warning { color: var(--lc-gold); border-color: var(--lc-gold); box-shadow: none; }
.table-dark .btn-outline-warning:hover { background: var(--lc-gold); border-color: var(--lc-gold); color: #3A2E14; }
.table-dark .btn-outline-success { color: #9BD8A8; border-color: #9BD8A8; }
.table-dark .btn-outline-success:hover { background: #9BD8A8; border-color: #9BD8A8; color: #122A18; }

/* ===================================================================
   抽奖页（/admin/draw）样式补齐
   -------------------------------------------------------------------
   迁移时丢掉了整段「抽奖舞台 + 原神风抽卡动画（gacha）」样式（连同
   gachaFadeIn / cometFly / ... 等 10 个 @keyframes），后果是
   .gacha-overlay 没有 display:none —— 遮罩里的提示文字、星域 canvas
   直接以普通块级元素漏在页面上，抽卡动画也完全没效果。
   以下规则逐条取自迁移前基线（.migration-staging/remote../css/style.css），
   颜色均为深底/浅底自成体系，未做改动。
   =================================================================== */
@keyframes orbFloat {
    0%, 100% { transform: translate(0, 0) rotate(0deg); }
    33%      { transform: translate(15px, -10px) rotate(120deg); }
    66%      { transform: translate(-8px, 8px) rotate(240deg); }
}

@keyframes hitodamaFloat {
    0%   { transform: translate(0, 0) scale(0.6); opacity: 0; }
    15%  { opacity: 0.8; }
    30%  { transform: translate(var(--dx1), var(--dy1)) scale(1); opacity: 0.7; }
    60%  { transform: translate(var(--dx2), var(--dy2)) scale(0.8); opacity: 0.5; }
    85%  { opacity: 0.15; }
    100% { transform: translate(var(--dx3), var(--dy3)) scale(0.4); opacity: 0; }
}

@keyframes sakuraDrift {
    0%   { transform: translateY(-5vh) rotate(0deg); opacity: 1; }
    50%  { transform: translateY(2vh) rotate(3deg); opacity: 0.85; }
    100% { transform: translateY(-5vh) rotate(0deg); opacity: 1; }
}

@keyframes petalFall {
    0%   { transform: translateY(0) rotate(0deg) scale(1);   opacity: 0; }
    8%   { transform: translateY(10vh) rotate(45deg) scale(1.05); opacity: 0.7; }
    25%  { transform: translateY(30vh) rotate(120deg) scale(0.9); opacity: 0.5; }
    50%  { transform: translateY(55vh) rotate(240deg) scale(1.1); opacity: 0.35; }
    75%  { transform: translateY(78vh) rotate(330deg) scale(0.85); opacity: 0.2; }
    90%  { transform: translateY(95vh) rotate(400deg) scale(0.6); opacity: 0.05; }
    100% { transform: translateY(105vh) rotate(500deg) scale(0.3); opacity: 0; }
}

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

@keyframes emblem-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-6px); }
}

@keyframes yinYangSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

@keyframes slideDown {
    from { opacity: 0; transform: translateY(-10px); }
    to   { opacity: 1; transform: translateY(0); }
}

.draw-stage {
    min-height: 240px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(ellipse at center, rgba(30, 10, 20, 0.9) 0%, rgba(10, 5, 15, 0.96) 100%) !important;
    border: 2px solid var(--touhou-red);
    border-radius: 18px;
    color: #fff;
    box-shadow:
        inset 0 0 80px rgba(196, 30, 58, 0.06),
        inset 0 0 30px rgba(0, 0, 0, 0.3),
        0 0 40px rgba(196, 30, 58, 0.1),
        0 0 80px rgba(196, 30, 58, 0.04);
    position: relative;
}

.draw-stage::before {
    content: '';
    position: absolute;
    inset: 8px;
    border: 1px solid rgba(218, 165, 32, 0.12);
    border-radius: 12px;
    pointer-events: none;
    z-index: 1;
}

.draw-stage::after {
    content: '';
    position: absolute;
    inset: 10px;
    pointer-events: none;
    z-index: 1;
    background:
        linear-gradient(135deg, rgba(218, 165, 32, 0.15) 0%, transparent 30%, transparent 70%, rgba(218, 165, 32, 0.15) 100%),
        linear-gradient(225deg, rgba(218, 165, 32, 0.06) 0%, transparent 25%, transparent 75%, rgba(218, 165, 32, 0.06) 100%);
    border-radius: 10px;
}

@keyframes namePulse {
    0%   { transform: scale(1);   opacity: 0.5; }
    35%  { transform: scale(1.3); opacity: 1;   text-shadow: 0 0 20px rgba(255,215,0,0.7), 0 0 50px rgba(255,215,0,0.3); }
    100% { transform: scale(1);   opacity: 1; }
}

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

.draw-level-card {
    transition: all 0.4s var(--ease-spring);
    background: var(--touhou-card) !important;
}

.draw-level-card:hover {
    box-shadow:
        0 6px 28px rgba(196, 30, 58, 0.22),
        inset 0 1px 0 rgba(255, 255, 255, 0.02);
    border-color: rgba(218, 165, 32, 0.4);
}

.draw-level-card .draw-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
    filter: grayscale(0.5);
}

.gacha-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: #000;
    overflow: hidden;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
}

.gacha-overlay.active {
    display: block;
    animation: gachaFadeIn 0.3s ease-out;
}

@keyframes gachaFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.gacha-starfield {
    position: absolute;
    inset: 0;
    z-index: 1;
}

.gacha-comet {
    position: absolute;
    z-index: 3;
    pointer-events: none;
    opacity: 0;
    filter: blur(0.5px);
}

.gacha-comet.fly {
    animation: cometFly 1.6s cubic-bezier(0.25, 0.1, 0.1, 1) forwards;
}

@keyframes cometFly {
    0%   { transform: translate(120vw, -30vh) rotate(-35deg) scale(0.3); opacity: 0; }
    15%  { opacity: 1; }
    85%  { opacity: 1; }
    100% { transform: translate(-10vw, 50vh) rotate(-35deg) scale(1.8); opacity: 0; }
}

.gacha-comet-core {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    position: absolute;
    top: 0;
    left: 0;
    box-shadow: 0 0 30px currentColor, 0 0 80px currentColor, 0 0 140px currentColor;
}

.gacha-comet-trail {
    position: absolute;
    top: 50%;
    right: 50%;
    width: 160px;
    height: 3px;
    background: linear-gradient(90deg, transparent, currentColor, #fff);
    transform-origin: right center;
    border-radius: 2px;
    opacity: 0.85;
}

.gacha-comet.rarity-3 .gacha-comet-core { color: #CD7F32; }

.gacha-comet.rarity-3 .gacha-comet-trail { color: #CD7F32; }

.gacha-comet.rarity-2 .gacha-comet-core { color: #C0A0E0; }

.gacha-comet.rarity-2 .gacha-comet-trail { color: #C0A0E0; }

.gacha-comet.rarity-1 .gacha-comet-core { color: #FFD700; }

.gacha-comet.rarity-1 .gacha-comet-trail { color: #FFD700; }

.gacha-comet.rarity-0 .gacha-comet-core { color: #8FE3FF; }

.gacha-comet.rarity-0 .gacha-comet-trail { color: #8FE3FF; }

.gacha-particle {
    position: absolute;
    z-index: 4;
    pointer-events: none;
    border-radius: 50%;
    animation: particleBurst 1.2s ease-out forwards;
}

@keyframes particleBurst {
    0%   { transform: translate(0, 0) scale(1); opacity: 1; }
    100% { transform: translate(var(--dx), var(--dy)) scale(0); opacity: 0; }
}

.gacha-ring {
    position: absolute;
    z-index: 2;
    pointer-events: none;
    border-radius: 50%;
    border: 2px solid;
    opacity: 0;
    animation: ringExpand 1.5s ease-out forwards;
}

@keyframes ringExpand {
    0%   { width: 10px; height: 10px; opacity: 1; transform: translate(-50%, -50%) scale(0); }
    100% { width: 800px; height: 800px; opacity: 0; transform: translate(-50%, -50%) scale(1); }
}

.gacha-flash {
    position: absolute;
    inset: 0;
    z-index: 5;
    pointer-events: none;
    opacity: 0;
    animation: screenFlash 0.6s ease-out forwards;
}

@keyframes screenFlash {
    0%   { opacity: 0.9; }
    100% { opacity: 0; }
}

.gacha-shake {
    animation: screenShake 0.5s ease-out;
}

@keyframes screenShake {
    0%, 100% { transform: translate(0, 0); }
    10%      { transform: translate(-8px, 4px); }
    20%      { transform: translate(7px, -5px); }
    30%      { transform: translate(-5px, 3px); }
    40%      { transform: translate(4px, -2px); }
    50%      { transform: translate(-3px, 2px); }
    60%      { transform: translate(3px, -1px); }
    70%      { transform: translate(-2px, 1px); }
    80%      { transform: translate(1px, 0); }
    90%      { transform: translate(-1px, 0); }
}

.gacha-sparkle {
    position: absolute;
    z-index: 4;
    pointer-events: none;
    width: 4px;
    height: 4px;
    background: #fff;
    border-radius: 50%;
    opacity: 0;
    animation: sparkleFloat 2s ease-out forwards;
}

@keyframes sparkleFloat {
    0%   { opacity: 1; transform: translate(var(--sx), var(--sy)) scale(1); }
    80%  { opacity: 0.5; }
    100% { opacity: 0; transform: translate(var(--ex), var(--ey)) scale(0); }
}

.gacha-winner-reveal {
    position: absolute;
    z-index: 10;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    pointer-events: none;
}

.gacha-winner-name {
    font-family: var(--touhou-serif);
    font-weight: 900;
    letter-spacing: 6px;
    opacity: 0;
    transform: scale(0.4);
    animation: nameReveal 0.8s var(--ease-bounce) forwards;
}

.gacha-winner-name.rarity-3 {
    color: #CD7F32;
    font-size: 2.5rem;
    text-shadow: 0 0 30px rgba(205, 127, 50, 0.6), 0 0 60px rgba(205, 127, 50, 0.3);
}

.gacha-winner-name.rarity-2 {
    color: #D4B8F0;
    font-size: 3rem;
    text-shadow: 0 0 35px rgba(192, 160, 224, 0.6), 0 0 70px rgba(192, 160, 224, 0.3);
}

.gacha-winner-name.rarity-1 {
    color: #FFD700;
    font-size: 3.5rem;
    text-shadow:
        0 0 40px rgba(255, 215, 0, 0.7),
        0 0 80px rgba(255, 215, 0, 0.4),
        0 0 120px rgba(255, 215, 0, 0.2),
        0 0 200px rgba(255, 215, 0, 0.1);
}

@keyframes nameReveal {
    0%   { opacity: 0; transform: scale(0.3) rotate(-3deg); filter: blur(12px); }
    50%  { opacity: 1; transform: scale(1.08); filter: blur(0); }
    70%  { transform: scale(0.96); }
    100% { opacity: 1; transform: scale(1) rotate(0deg); filter: blur(0); }
}

.gacha-winner-title {
    font-family: var(--touhou-serif);
    font-size: 1.3rem;
    letter-spacing: 4px;
    opacity: 0;
    animation: titleReveal 0.6s 0.35s var(--ease-out-expo) forwards;
}

.gacha-winner-title.rarity-3 { color: #CD7F32; }

.gacha-winner-title.rarity-2 { color: #D4B8F0; }

.gacha-winner-title.rarity-1 { color: #FFD700; }

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

.gacha-skip-hint {
    position: absolute;
    bottom: 40px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    color: rgba(255,255,255,0.4);
    font-size: 0.85rem;
    letter-spacing: 2px;
    animation: gachaFadeIn 1s 1s ease-out both;
    pointer-events: none;
}

.gacha-winner-list {
    position: absolute;
    z-index: 10;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 20px 32px;
    max-width: 80vw;
    pointer-events: none;
}

.gacha-winner-card {
    text-align: center;
    opacity: 0;
    animation: winnerCardIn 0.6s var(--delay) cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}

@keyframes winnerCardIn {
    from { opacity: 0; transform: scale(0.3) rotateY(90deg); }
    to   { opacity: 1; transform: scale(1) rotateY(0); }
}

.gacha-winner-card .name {
    font-family: var(--touhou-serif);
    font-weight: 700;
    font-size: 1.8rem;
    letter-spacing: 4px;
}

.gacha-winner-card .label {
    font-size: 0.85rem;
    letter-spacing: 3px;
    opacity: 0.8;
}

.gacha-winner-card.rarity-3 .name { color: #CD7F32; text-shadow: 0 0 20px rgba(205,127,50,0.5); }

.gacha-winner-card.rarity-3 .label { color: #CD7F32; }

.gacha-winner-card.rarity-2 .name { color: #D4B8F0; text-shadow: 0 0 20px rgba(192,160,224,0.5); }

.gacha-winner-card.rarity-2 .label { color: #D4B8F0; }

.gacha-winner-card.rarity-1 .name { color: #FFD700; text-shadow: 0 0 30px rgba(255,215,0,0.7), 0 0 60px rgba(255,215,0,0.3); }

.gacha-winner-card.rarity-1 .label { color: #FFD700; }

.gacha-winner-card.rarity-0 .name { color: #8FE3FF; text-shadow: 0 0 30px rgba(143,227,255,0.9), 0 0 70px rgba(143,227,255,0.45); }

.gacha-winner-card.rarity-0 .label { color: #8FE3FF; }

.gacha-result-bar {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 10;
    background: linear-gradient(180deg, transparent, rgba(0,0,0,0.9));
    padding: 30px 20px 20px;
    text-align: center;
    opacity: 0;
    animation: gachaFadeIn 0.5s 0.5s ease-out forwards;
    pointer-events: auto;
}

.gacha-result-bar .btn {
    margin: 4px;
}

@keyframes game-ad-tag-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.6; }
}

@media (max-width: 768px) {
    .draw-stage {
        min-height: 160px;
        border-radius: 12px;
    }
    .draw-stage::before { inset: 5px; border-radius: 8px; }
}

@media (max-width: 480px) {
    .gacha-winner-name.rarity-1 { font-size: 2rem; }
    .gacha-winner-name.rarity-2 { font-size: 1.8rem; }
    .gacha-winner-name.rarity-3 { font-size: 1.5rem; }
}

@media (prefers-reduced-motion: reduce) {
    .gacha-comet {
        display: none;
    }
}


/* ===========================================================================
   低性能模式（html.lowfx）—— 由 static/js/perf-guard.js 首屏判定并持久化
   （localStorage: tho-lowfx；?lowfx=1|0 可手动覆盖）
   只关"每帧重绘整个视口"的背景流光，其余动画全部保留：
     · .bg-light-riser 的 mask-position 扫光（全屏重绘，最贵）
         =========================================================================== */
/* 低性能模式（html.lowfx）：**只停"背景纹路"的动效**（全屏扫光/流光，属每帧重绘整个视口的贵项）。
   其余一切动画与过渡保持正常（角色摆动、眨眼、卡片悬停、滚动淡入等都不再受影响）。 */
html.lowfx .bg-light-riser { animation: none !important; display: none !important; }


/* 编辑手记：正文之后的小字斜体说明块（如《花果子念报》被迫让版面那段） */
.news-detail-note { font-size: .86em; font-style: italic; line-height: 1.9;
    color: rgba(90,90,106,.92); border-left: 3px solid rgba(148,130,188,.45);
    padding: .2rem 0 .2rem .9rem; margin-top: 1.2rem; }


/* 首页信息条里的链接（会场地点→游客手册 / 参与方式→0 元门票） */
.tho-info-card p a { color: var(--lc-blue-deep, #2f5b8f); text-decoration: underline;
    text-underline-offset: 3px; text-decoration-thickness: 1px; }
.tho-info-card p a:hover { color: var(--lc-touhou-red, #A94F68); }


/* ===========================================================================
   新闻首图：等比缩放完整显示（不裁剪）
   —— 之前 .news-detail-cover-img 没有任何规则，宽高被容器/全局 img 影响，
      大图会被裁掉或溢出。这里统一声明：占满列宽、高度自适应、完整可见。
      所有新闻详情页共用（第一张图 = 封面/首图）。
   =========================================================================== */
.news-detail-cover,
.news-detail-cover-img {
    max-height: none !important;
    overflow: visible !important;
}
.news-detail-cover-img {
    display: block;
    width: 100%;
    height: auto;
    object-fit: contain;   /* 万一外层仍限高，也保证"缩放"而非"裁剪" */
}
