/* 活动网设计系统 —— 面向用户的公开站
 *
 * 方向 C「编辑式」：承接 2026-07-26 首页改版已上线的语言并推到全站。
 * 规范见 docs/design-system-2026-08.md，原型见 demo/ds-editorial-*.html。
 *
 * 本文件替代了 style.css / home.css / event.css / event-detail.css /
 * venue.css / venue-detail.css / notice.css 七个文件（原 5,004 行）。
 * admin.css 是后台专用、自包含，不在本系统内，后续另行设计。
 *
 * 分层：token → 基础 → 布局 → 组件 → 页面专属 → 工具类
 * 硬约束：组件层不得出现硬编码色值，一律走 token。
 *
 * 深色模式：默认浅色，不读 prefers-color-scheme（搜索来的新访客一律浅色，
 * 保证品牌呈现一致）。用户手动切换后写 localStorage，由 base.html 的
 * 首绘前内联脚本打 data-theme。
 */

/* ============================================================ 1. TOKEN */

:root {
    /* 间距 —— 4px 基准 */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
    --s5: 20px; --s6: 28px; --s7: 40px; --s8: 56px;

    /* 层级 */
    --z-sticky: 100; --z-overlay: 200; --z-drawer: 300; --z-lightbox: 500;

    /* 动效 */
    --dur-fast: .15s; --dur: .2s; --dur-slow: .45s;
    --ease: cubic-bezier(.4, 0, .2, 1);

    /* 布局 */
    --hdr-h: 58px;
    --container-width: 1180px;

    /* 语义色 —— 浅色
       ------------------------------------------------------------------
       这版对着实际做年轻用户的产品调了一遍（小红书、即刻、大麦、猫眼、
       豆瓣同城、Airbnb、B站），它们的共同点是三条，而之前这版三条全反着：

         1. 底是纯白或极浅「中性」灰，不是暖米。暖米是杂志/editorial 的语言，
            天然读作成熟、慢——「沉」的来源其实在这里，不在深色带的色相。
         2. 强调色一个、暖色系。所以橙 #ff5a1f 原样留着，它从来不是问题。
         3. 圆角大（8–16px）。方角是报纸和政务网站的语言，这条对「年轻」的
            决定性不低于色相，而之前一次都没动过。

       第四条是结构：这些站的界面本身几乎无彩色，颜色由内容图片提供。
       我们整站铺的就是活动海报，条件更好，界面更不该抢。 */
    --paper: #f6f6f8;
    --surface: #ffffff;
    --surface-2: #efeff2;
    --text: #16161a;
    --text-2: #6b6b76;
    --text-3: #a1a1ac;
    --line: #ececef;
    --line-2: #dcdce1;
    --orange: #ff5a1f;
    --orange-ink: #fff;
    /* 浅底上的小号橙字。#ff5a1f 配近白只有 3.0:1——在深色带上它是 6:1，
       所以整站变浅之后，凡是「小字用橙色」的地方都得换这一支（4.6:1）。
       大号粗体（≥18.66px 粗）3:1 即达标，仍用 --orange，颜色才不会两支打架。
       填充、边框、指示条也一律留给 --orange：那是图形，门槛是 3:1。 */
    --orange-text: #c94409;
    /* 数据色。全亮版里日期/场次不再上色，靠字重和等宽数字区分（参考同上：
       它们要么是墨色要么留给价格）。琥珀只剩「图形」用途：来源小点、提示条。 */
    --gold: #f0a828;
    --gold-ink: var(--text);
    /* 全站已无大面积深色。这两个值只留给还需要填充的地方，见 §3/§4/§15。 */
    --band-bg: var(--paper);
    --header-bg: var(--surface);
    --band-text: var(--text);
    --band-sub: var(--text-2);
    --band-line: var(--line-2);
    --danger: #e5484d;
    --r: 10px;                /* 卡片、面板、按钮 */
    --r-sm: 6px;              /* 图片、小控件 */
    --r-pill: 999px;          /* 筛选项、标签 */

    /* 浮起表面：软阴影替代描边（参考产品的卡片语言）。
       --card-border 浅色下透明、深色下实线——阴影在近黑底上读不出来，
       深色模式的「浮起」只能靠边框表达，这是一对必须成套换的值。 */
    --shadow-1: 0 1px 2px rgba(16, 16, 22, .04), 0 4px 14px rgba(16, 16, 22, .06);
    --shadow-2: 0 2px 6px rgba(16, 16, 22, .06), 0 10px 28px rgba(16, 16, 22, .11);
    --card-border: transparent;

    /* 页头/页面带上的线与填充。这些以前是白色半透明（深底专用），
       现在整套跟着变浅；仍然压在图片或灯箱上的那几处另有 --on-image-*。 */
    --band-chip: var(--text-2);
    --band-hairline: var(--line);
    --band-fill: rgba(22, 22, 26, .06);
    --band-fill-soft: rgba(22, 22, 26, .035);
    --band-line-strong: var(--text-3);
    --band-outline: var(--line-2);

    /* 「常暗表面」——灯箱、图上角标在两种主题下都是深色，值不随主题切换 */
    --on-image-fill: rgba(255, 255, 255, .18);
    --on-image-outline: rgba(255, 255, 255, .28);
    --overlay: rgba(0, 0, 0, .5);     /* 弹窗/抽屉遮罩 */
    --scrim: rgba(10, 10, 13, .62);     /* 图上角标 */
    --scrim-strong: rgba(10, 10, 13, .86);
    --lightbox-bg: rgba(12, 12, 14, .95);
    --lightbox-tile: #26262b;

    /* 内联图标（用 mask 上色，跟随 currentColor） */
    --icon-pin: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 22s7-6.2 7-11a7 7 0 10-14 0c0 4.8 7 11 7 11z' fill='none' stroke='black' stroke-width='2'/><circle cx='12' cy='10' r='2.6' fill='none' stroke='black' stroke-width='2'/></svg>");
    --icon-caret: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 9l6 6 6-6' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

:root[data-theme="dark"] {
    --paper: #0f0f11;
    --surface: #17171a;
    --surface-2: #212125;
    --text: #f0f0f3;
    --text-2: #9b9ba5;
    --text-3: #6e6e78;
    --line: #26262b;
    --line-2: #34343b;
    --orange: #ff7a45;
    --orange-ink: #1a1310;
    /* 上一版漏了这支：不写的话深色下 23 处小号橙字会落回浅底用的 #c94409，
       在近黑上只有 ~3.5:1。深底上提亮的品牌橙本身就有 7:1+，直接复用。 */
    --orange-text: var(--orange);
    --gold: #f0a828;
    --gold-ink: var(--text);
    --band-bg: var(--paper);
    --header-bg: var(--surface);
    --band-text: var(--text);
    --band-sub: var(--text-2);
    --band-line: var(--line-2);
    --band-chip: var(--text-2);
    --band-hairline: var(--line);
    --band-fill: rgba(255, 255, 255, .07);
    --band-fill-soft: rgba(255, 255, 255, .04);
    --band-line-strong: var(--text-3);
    --band-outline: var(--line-2);
    --shadow-1: none;
    --shadow-2: 0 12px 40px rgba(0, 0, 0, .5);
    --card-border: var(--line);
    --danger: #ff6b6b;
}

/* ============================================================ 2. 基础 */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--paper);
    color: var(--text);
    /* 中文站必须显式声明中文字体，否则汉字落到系统默认 */
    font-family: -apple-system, BlinkMacSystemFont, "PingFang SC",
        "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

body.lock { overflow: hidden; }

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
h1, h2, h3, h4 { margin: 0; }
ul, ol { margin: 0; padding: 0; }

:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

.container {
    width: min(var(--container-width), 100% - 32px);
    margin-inline: auto;
}

.sr-only {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ============================================================ 3. 页头 */

/* 白页头 + 发丝线，和纸色页面拉开半档。参考的那批产品几乎都是这个做法：
   页头不承担品牌色，品牌色留给「当前在哪」和主按钮。 */
.header {
    position: sticky; top: 0; z-index: var(--z-sticky);
    background: var(--header-bg); color: var(--text);
    border-bottom: 1px solid var(--line);
}

.header-container {
    display: flex; align-items: center; gap: var(--s4);
    height: var(--hdr-h);
}

.logo-container { display: flex; align-items: center; gap: var(--s3); }

/* 频道标签栏要撑满页头高度，底部指示条才落在页头下沿上 */
.header-container > nav { align-self: stretch; display: flex; }

.logo {
    font-weight: 800; font-size: 18px; letter-spacing: -.5px; white-space: nowrap;
}
.logo::after { content: "."; color: var(--orange); }

/* 城市按钮：必须一眼看出可切换。只给个方框会被当成纯展示——
   前缀图钉 + 后缀下拉箭头 + hover 变色，三个信号一起给。 */
.selected-city {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 13px; font-weight: 600; padding: 5px 9px 5px 8px;
    border: 1px solid var(--band-line); border-radius: var(--r);
    background: none; color: inherit; cursor: pointer;
    font-family: inherit; white-space: nowrap;
    transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.selected-city::before {
    content: ""; flex: none; width: 11px; height: 11px;
    background: currentColor; opacity: .75;
    -webkit-mask: var(--icon-pin) center / contain no-repeat;
    mask: var(--icon-pin) center / contain no-repeat;
}
.selected-city::after {
    content: ""; flex: none; width: 9px; height: 9px; margin-left: 1px;
    background: currentColor; opacity: .55;
    -webkit-mask: var(--icon-caret) center / contain no-repeat;
    mask: var(--icon-caret) center / contain no-repeat;
}
/* 详情页城市只读，指向该城市落地页——那里不该出现「可切换」的下拉箭头 */
a.selected-city::after { display: none; }
.selected-city:hover {
    border-color: var(--orange); background: var(--band-fill-soft); color: var(--orange-text);
}

/* 频道切换是本站的主操作，做成标签栏而不是一排文字链接：
   撑满页头高度 + 底部指示条 + hover 背景，三个可点信号一起给。
   只靠「橙色 + 加粗」标当前项不够——那是文本强调的语言，不是导航的语言。 */
.nav-menu {
    display: flex; align-self: stretch; gap: 2px;
    margin: 0 0 0 var(--s2); padding: 0; list-style: none;
}
.nav-item { display: flex; }
.nav-link {
    position: relative; display: flex; align-items: center;
    padding: 0 13px; font-size: 14.5px; font-weight: 600;
    color: var(--band-text); opacity: .84;
    transition: opacity var(--dur-fast) var(--ease),
                background var(--dur-fast) var(--ease);
}
.nav-link::after {
    content: ""; position: absolute; left: 9px; right: 9px; bottom: 0;
    height: 2px; background: transparent;
    transition: background var(--dur-fast) var(--ease);
}
.nav-link:hover { opacity: 1; background: var(--band-fill-soft); }
.nav-link:hover::after { background: var(--band-outline); }
/* 当前项：墨字加粗 + 品牌橙指示条。文字不上橙——14.5px 要过 4.5:1 只能用
   压暗的 #c94409，那支读起来偏红（评审确认）；让指示条独扛品牌色，
   它是图形，可以用纯正的 #ff5a1f。 */
/* 文字用纯正品牌橙（评审定的：要橙不要压暗的那支红棕）。
   #ff5a1f 在白底 14.5px 是 3.1:1，低于 AA 的 4.5:1——已知并接受：
   加粗 + 橙条是冗余信号，色弱用户仍能靠它们定位当前频道。 */
.nav-link.active { opacity: 1; color: var(--orange); font-weight: 700; }
.nav-link.active::after { background: var(--orange); }

.header-spacer { flex: 1; }

.search-box {
    display: flex; align-items: center; gap: 6px;
    padding: 5px 10px; min-width: 210px;
    border: 1px solid var(--band-line); border-radius: var(--r);
    transition: border-color var(--dur) var(--ease);
}
.search-box:focus-within { border-color: var(--orange); }
.search-box select,
.search-box input {
    background: none; border: 0; color: inherit;
    font-family: inherit; font-size: 13px; min-width: 0;
}
.search-box select { flex: none; cursor: pointer; opacity: .75; }
.search-box select option { background: var(--header-bg); color: var(--band-text); }
.search-box input { flex: 1; outline: none; }
.search-box input::placeholder { color: var(--band-sub); opacity: .7; }
.search-box button {
    flex: none; background: none; border: 0; color: inherit;
    cursor: pointer; padding: 2px; display: grid; place-items: center;
    opacity: .75;
}
.search-box button:hover { opacity: 1; color: var(--orange-text); }

.icon-btn {
    display: grid; place-items: center;
    width: 34px; height: 34px; flex: none; cursor: pointer;
    border: 1px solid var(--band-line); border-radius: var(--r);
    background: none; color: inherit;
    transition: border-color var(--dur) var(--ease);
}
.icon-btn:hover { border-color: var(--orange); }

.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }

.hamburger { display: none; }

/* ---- 移动端抽屉：不允许把导航直接 display:none 而不给替代入口 ---- */

.scrim {
    position: fixed; inset: 0; z-index: var(--z-overlay);
    background: var(--overlay);
    opacity: 0; visibility: hidden;
    transition: opacity var(--dur) var(--ease), visibility var(--dur);
}
.scrim.active { opacity: 1; visibility: visible; }

.drawer {
    position: fixed; top: 0; right: 0; bottom: 0;
    width: min(84vw, 300px); z-index: var(--z-drawer);
    background: var(--header-bg); color: var(--text);   /* 抽屉是页头的延伸 */
    border-left: 1px solid var(--line);
    padding: var(--s5);
    display: flex; flex-direction: column; gap: var(--s5);
    overflow-y: auto;
    transform: translateX(100%);
    transition: transform var(--dur) var(--ease);
}
.drawer.active { transform: none; }
.drawer-top { display: flex; align-items: center; justify-content: space-between; }
/* 这几处标签不再叠 opacity（同款还有 .filter-label、.fcat-name）：
   那是深色带时代压浅字亮度用的，现在乘在灰字上会掉到 3:1 以下。
   层次由字号 + 大写字距承担。 */
.drawer h2 {
    font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
    color: var(--band-sub); margin-bottom: var(--s3);
}
.drawer nav { display: flex; flex-direction: column; }
.drawer nav a {
    padding: 12px 0; font-size: 17px; font-weight: 700; letter-spacing: -.3px;
    border-bottom: 1px solid var(--band-line);
}
/* 抽屉里同理：左侧 3px 橙条替代文字上色（抽屉链接本来就是 700，色是唯一信号时会读偏红） */
.drawer nav a.active { color: var(--orange); border-left: 3px solid var(--orange); padding-left: 10px; }

/* ---- 城市弹窗 ----
   注意：显隐由 JS 直接写内联 style.display（'flex' / 'none'），
   这里不得改用 opacity/visibility 控制，否则弹窗打不开。 */

.modal {
    position: fixed; inset: 0; z-index: var(--z-drawer);
    background: var(--overlay);
    align-items: center; justify-content: center; padding: var(--s4);
}
.modal-content {
    background: var(--surface); color: var(--text);
    border-radius: var(--r); padding: var(--s6);
    width: min(520px, 100%); max-height: 80vh; overflow-y: auto;
    position: relative;
}
.modal-content h3 {
    font-size: 19px; font-weight: 800; letter-spacing: -.4px;
    margin-bottom: var(--s5);
}
.modal-close {
    position: absolute; top: var(--s4); right: var(--s4);
    width: 32px; height: 32px; display: grid; place-items: center;
    /* 关闭是可操作控件，不能用最淡的 --text-3（近白底上只有 2.6:1，连图形的 3:1 都不够） */
    border: 0; background: none; color: var(--text-2);
    font-size: 22px; line-height: 1; cursor: pointer;
}
.modal-close:hover { color: var(--orange-text); }
.city-options {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: var(--s2);
}
.city-option {
    padding: 10px 12px; text-align: center; font-size: 14px; font-weight: 600;
    border: 1px solid var(--line); border-radius: var(--r); cursor: pointer;
    transition: border-color var(--dur-fast) var(--ease);
}
.city-option:hover { border-color: var(--orange); color: var(--orange-text); }
.city-option.active {
    background: var(--orange); border-color: var(--orange); color: var(--orange-ink);
}

/* ============================================================ 4. 页头带 */

/* 五类页面的 hero 都在这里。曾经是整幅深色块，是「其它页比首页沉」的主因。
   现在是纸色，底部一条发丝线保住「这里换段了」。 */
.band {
    background: var(--band-bg); color: var(--text);
    padding: 14px 0 22px;
    border-bottom: 1px solid var(--line);
}

/* 不再叠 opacity：那是深色带时代压亮度用的。现在 --band-sub 落在灰字
   #6b6b76，再乘 0.8 会掉到 ~3.6:1，12.5px 小字不达标。 */
.breadcrumb {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    font-size: 12.5px; color: var(--band-sub);
    margin-bottom: var(--s4);
}
.breadcrumb a:hover { color: var(--orange-text); }
.bc-sep { opacity: .5; }

/* 展示型标题 */
.page-title {
    display: inline-block;
    font-size: clamp(26px, 5vw, 44px); font-weight: 800;
    letter-spacing: -.7px; line-height: 1.24;
}
@media (min-width: 600px) { .page-title { letter-spacing: -1.1px; } }

/* 橙色下划线只给首页 hero。它成立的前提是「整页仅此一个标题」——
   频道页和详情页每页都有 h1，一加下划线它就从主视觉降格成到处都有的装饰。
   线用背景画，不占行高。 */
.page-title-mark {
    background-image: linear-gradient(var(--orange), var(--orange));
    background-size: 100% 4px; background-repeat: no-repeat;
    background-position: 0 96%;
}
@media (min-width: 600px) { .page-title-mark { background-size: 100% 6px; } }

.page-stats { font-size: 13px; color: var(--band-sub); margin: 11px 0 0; line-height: 1.75; }
.page-stats b {
    color: var(--gold-ink); font-weight: 800; font-size: 14.5px;
    font-variant-numeric: tabular-nums;
}
.page-subtitle { font-size: 14px; color: var(--band-sub); margin: 11px 0 0; max-width: 68ch; }

/* 页头带内的次级文字与链接 */
.band a:not(.btn):hover { color: var(--orange-text); }

/* ============================================================ 5. 筛选器 */

/* 筛选器要和它上面的标题区分开，否则会被当成标题的一部分。
   带变成纸色后半透明填充已经浮不起来，改用纯白面 + 实线框。 */
.filters, .filter-disclosure {
    margin-top: var(--s5);
    background: var(--surface);
    border: 1px solid var(--card-border);
    border-radius: var(--r);
    box-shadow: var(--shadow-1);
}

.filter-disclosure > summary {
    display: flex; align-items: center; gap: 8px;
    padding: 11px 14px; cursor: pointer; font-size: 14px; font-weight: 700;
    list-style: none; color: var(--band-text);
    transition: background var(--dur-fast) var(--ease);
}
.filter-disclosure > summary:hover { background: var(--band-fill); }
.filter-disclosure > summary::-webkit-details-marker { display: none; }
.filter-toggle-summary {
    flex: 1; font-weight: 400; color: var(--band-sub); font-size: 13px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 折叠态给一枚橙色小点，提示「这里可以展开」——只有一个灰箭头太容易错过 */
.filter-toggle-icon {
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--band-sub); transition: transform var(--dur) var(--ease);
}
.filter-disclosure:not([open]) > summary::before {
    content: ""; flex: none; width: 5px; height: 5px; border-radius: 50%;
    background: var(--orange); order: 3;
}
.filter-disclosure[open] .filter-toggle-icon { transform: rotate(180deg); }
.filter-disclosure[open] > summary { border-bottom: 1px solid var(--band-line); }

.filter-body { padding: var(--s2) 14px 14px; }

/* 选项换行铺开，不横滑——横滑会把后面的选项藏起来，用户不知道还有 */
.filter-group {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 10px 0; border-bottom: 1px dashed var(--band-line);
}
.filter-group:last-child { border-bottom: 0; padding-bottom: 0; }
.filter-label {
    flex: none; width: 34px; padding-top: 5px;
    font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
    color: var(--band-sub);
}
@media (min-width: 600px) { .filter-label { width: 44px; font-size: 11.5px; } }

.filter-options { display: flex; flex-wrap: wrap; gap: 7px; }

/* 场馆分类有 9 个父类、41 个子类，且极不均匀（球类 12 个、水上运动 1 个）。
   拍平成一排没法扫，所以保留父分类分组：每组自成一个带标签的视觉单元，
   整体流式排布。41 个链接全部保持可见可爬——它们是内链资产。 */
.filter-group-block { align-items: flex-start; }
.filter-cats { flex: 1; min-width: 0; }
/* 每个父类占一行：标签在左、子项在右侧换行。
   试过两种更「省地方」的排法都不行——
   grid：行高被同排最高的组撑起，只有 1 项的水上运动下面空一大片；
   columns：阅读顺序变成竖排换列，每列组数还不一致（1/1/3/2/2），扫起来像一条参差的长列。
   一行一父类没有这两个毛病，且与上一层的「城市/分类/区域」是同一个行模式。 */
.filter-cat-groups { margin-top: var(--s3); }
.fcat {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 7px 0;
}
.fcat + .fcat { border-top: 1px dashed var(--band-line); }
.fcat-name {
    flex: none; width: 62px; padding-top: 6px;
    font-size: 11.5px; font-weight: 700; line-height: 1.35;
    color: var(--band-sub);
}
.fcat-items { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
/* 组内有选中项时把该组的标签点亮，便于快速定位当前在哪一类下 */
.fcat:has(.filter-option.active) .fcat-name { color: var(--orange-text); opacity: 1; }
@media (max-width: 599px) {
    /* 窄屏标签移到上方，否则 62px 的标签列会把子项挤成每行两个 */
    .fcat { flex-direction: column; gap: 5px; }
    .fcat-name { width: auto; padding-top: 0; }
}

/* .chip 与 .filter-option 同形：前者是首页时间入口，后者是筛选项，共用一套样式。
   走胶囊形——参考的那批产品筛选项一律是胶囊，方角在这个尺寸上显得旧。 */
.filter-option, .chip {
    flex: 0 0 auto; padding: 6px 14px; font-size: 13px;
    color: var(--band-chip); white-space: nowrap;
    border: 1px solid var(--band-line); border-radius: var(--r-pill);
    transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.filter-option:hover, .chip:hover { border-color: var(--band-line-strong); }
.filter-option.active, .chip-primary {
    background: var(--orange); border-color: var(--orange);
    color: var(--orange-ink); font-weight: 700;
}
.filter-count { opacity: .62; font-size: 11.5px; margin-left: 4px; }
.filter-option.low-stock { opacity: .55; }
.filter-option.unavailable {
    opacity: .3; pointer-events: none; text-decoration: line-through;
}
.org-badge {
    display: inline-block; width: 5px; height: 5px; border-radius: 50%;
    background: var(--gold); margin-right: 5px; vertical-align: middle;
}

/* ============================================================ 6. 正文布局 */

.main-content { padding: var(--s6) 0 var(--s8); }

.content-wrapper { display: grid; grid-template-columns: 1fr; gap: var(--s7); }
@media (min-width: 1000px) {
    .content-wrapper {
        grid-template-columns: minmax(0, 1fr) 288px;
        gap: var(--s8); align-items: start;
    }
}
.main-area { min-width: 0; }

/* ---- 栏目头 ---- */

.section-header { display: flex; align-items: baseline; gap: var(--s3); }
.section-title {
    font-size: 20px; font-weight: 800; letter-spacing: -.4px;
}
@media (min-width: 768px) { .section-title { font-size: 24px; } }
.section-count { font-size: 13px; color: var(--text-2); white-space: nowrap; }
.more-btn {
    margin-left: auto; font-size: 13px; font-weight: 600;
    color: var(--orange); white-space: nowrap;
}
.more-btn:hover { text-decoration: underline; }
.section-sub { font-size: 13px; color: var(--text-2); margin: 9px 0 14px; }

/* 带下边框的栏目头（列表页）。全页只此一条，是结果区的真正起点。 */
.section-head-ruled {
    display: flex; flex-wrap: wrap; align-items: baseline;
    gap: var(--s2) var(--s3);
    padding-bottom: var(--s3); border-bottom: 2px solid var(--text);
}
.section-head-ruled .section-title { white-space: nowrap; }

.sort-options {
    display: flex; gap: 2px; width: 100%; order: 3;
    overflow-x: auto; scrollbar-width: none; margin: 0 -2px;
}
.sort-options::-webkit-scrollbar { display: none; }
@media (min-width: 600px) { .sort-options { width: auto; order: 0; margin-left: auto; } }
.sort-option {
    flex: 0 0 auto; font-size: 13px; padding: 4px 9px;
    color: var(--text-2); white-space: nowrap; border-radius: var(--r-sm);
}
.sort-option:hover { color: var(--text); }
.sort-option.active { color: var(--orange); font-weight: 700; }

/* 日期分组：标题后拖一条延伸到行尾的细线 */
.day-group { margin-top: var(--s5); }
.day-group:first-child { margin-top: var(--s2); }
.day-group h4 {
    display: flex; align-items: center; gap: 10px;
    font-size: 13px; font-weight: 700; color: var(--text); margin: 0 0 10px;
}
.day-group h4::after {
    content: ""; flex: 1; height: 1px; background: var(--line);
}

/* ============================================================ 7. 卡片 */

/* ---- 分隔线行（活动列表 / 首页即将开场）---- */

.activity-list { display: flex; flex-direction: column; gap: var(--s3); }

/* 频道页的活动行是软卡片：白面 + 阴影 + 内边距，不描边。
   内边距同时解决了「价格贴死右缘」——满宽分隔线行没有横向内边距，
   右对齐的价格必然亲到容器边上。首页的 compact 列表保持分隔线行（见下）。 */
.activity-card {
    position: relative; display: grid;
    grid-template-columns: 22px 78px minmax(0, 1fr);
    gap: var(--s3); padding: var(--s4);
    background: var(--surface); border-radius: var(--r);
    border: 1px solid var(--card-border);
    box-shadow: var(--shadow-1);
    transition: box-shadow var(--dur) var(--ease);
}
@media (min-width: 600px) { .activity-card { gap: var(--s4); padding: var(--s5); } }
/* 价格独立成列要到 900px 才成立：更窄时它会浮在行右上角、和内容脱节 */
@media (min-width: 900px) {
    .activity-card {
        grid-template-columns: 38px 112px minmax(0, 1fr) auto;
        gap: var(--s5); align-items: start;
    }
}
.activity-card:hover { box-shadow: var(--shadow-2); }
.activity-card:hover .activity-title { color: var(--orange); }

/* 紧凑变体：用于首页 1.34fr 左栏，价格始终行内 */
/* 首页两栏里的紧凑列表维持分隔线行：那里行高小、密度高，
   一行一张卡会碎成一摞小白块，而且用户已认可首页现在的版式。 */
.activity-list.compact { gap: 0; }
.activity-list.compact .activity-card {
    grid-template-columns: 22px 78px minmax(0, 1fr); gap: var(--s3);
    padding: var(--s4) 0; background: none; border: 0; border-radius: 0;
    box-shadow: none; border-bottom: 1px solid var(--line);
}
.activity-list.compact .activity-card:hover { box-shadow: none; }
@media (min-width: 600px) {
    .activity-list.compact .activity-card { grid-template-columns: 26px 92px minmax(0, 1fr); }
}

.card-index {
    font-size: 11.5px; font-weight: 800; color: var(--gold-ink);
    font-variant-numeric: tabular-nums; padding-top: 3px;
}
/* 图片比例按来源形态分流：自有 CDN 的公众号封面是横图，外链是竖版海报。
   全站硬裁 3:4 会让 2.35:1 的横幅只剩中间三成。 */
.activity-image {
    aspect-ratio: 3 / 4; overflow: hidden; border-radius: var(--r-sm);
    background: var(--surface-2) center / cover no-repeat;
}
.activity-card-wide .activity-image { aspect-ratio: 16 / 9; }
.activity-image img {
    width: 100%; height: 100%; object-fit: cover;
    transition: transform var(--dur-slow) var(--ease);
}
.activity-card:hover .activity-image img { transform: scale(1.04); }
.activity-info { min-width: 0; }

.activity-title {
    font-size: 16px; font-weight: 700; line-height: 1.38; letter-spacing: -.3px;
    transition: color var(--dur-fast) var(--ease);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
@media (min-width: 600px) { .activity-title { font-size: 19px; letter-spacing: -.45px; } }

.activity-meta {
    display: flex; flex-wrap: wrap; align-items: center; gap: 5px;
    margin: 7px 0 0; font-size: 12.5px; color: var(--text-2);
}
@media (min-width: 600px) { .activity-meta { font-size: 13px; gap: 6px; } }
.activity-meta .meta-date { color: var(--gold-ink); font-weight: 700; }
.meta-sep { color: var(--text-3); }
.meta-source { font-size: 12px; color: var(--text-3); }

/* 3 列布局下价格是第 4 个子元素，会换行到第 1 列（序号列）下方，和内容脱节。
   显式落到正文列。900px 起它独立成列，恢复 auto。 */
.activity-price {
    grid-column: 3; margin: 8px 0 0;
    display: flex; align-items: baseline; gap: 8px;
}
@media (min-width: 900px) {
    .activity-price {
        grid-column: auto; margin: 0;
        flex-direction: column; align-items: flex-end;
        min-width: 92px; padding-top: 2px;
    }
}
.activity-list.compact .activity-price {
    grid-column: 3; margin: 8px 0 0;
    flex-direction: row; align-items: baseline;
    min-width: 0; padding-top: 0;
}

/* 墨色价格：价格不喊叫；「待确认」再降一档 */
.price {
    font-size: 16px; font-weight: 800; color: var(--text);
    letter-spacing: -.4px; font-variant-numeric: tabular-nums; white-space: nowrap;
}
@media (min-width: 600px) { .price { font-size: 17px; } }
.price-tbd {
    font-size: 12.5px; font-weight: 400; color: var(--text-3); letter-spacing: 0;
}
.price-value { font-variant-numeric: tabular-nums; }

/* 整卡可点击的覆盖层 */
.card-hit { position: absolute; inset: 0; }

/* ---- 标签 ----
   品类是「这是什么」，用静默灰；橙色只留给「即将开场」这类时效标记。 */

.card-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 6px; }
.tag {
    display: inline-flex; align-items: center; height: 20px; padding: 0 9px;
    font-size: 11px; line-height: 1; border-radius: var(--r-pill);
    background: var(--surface-2); color: var(--text-2); white-space: nowrap;
}
.tag-hot { background: var(--orange); color: var(--orange-ink); font-weight: 700; }
.tag-ghost { background: none; border: 1px solid var(--line); color: var(--text-3); }
.band .tag { background: var(--band-fill); color: var(--band-chip); }
.band .tag-ghost { background: none; border-color: var(--band-line); color: var(--band-sub); }
.band .tag-hot { background: var(--orange); color: var(--orange-ink); }

/* ---- 场馆卡网格 ---- */

/* 固定列数（首页「热门去处」、详情页「周边场馆」都是 6 条）：2 列 → 3 列，
   两行恰好铺满。auto-fill 在 1180 的整幅容器里会排成一行 7 列，
   6 张卡缩成一排小图还剩个空位——改版首版就是这么塌的。 */
.venue-grid {
    display: grid; grid-template-columns: repeat(2, 1fr);
    gap: var(--s5) var(--s4);
}
@media (min-width: 700px) {
    .venue-grid { grid-template-columns: repeat(3, 1fr); gap: var(--s6) var(--s5); }
}
/* 场馆频道的浏览网格另算：容器宽度随筛选栏变化，跟着可用宽度走。
   特异性高于上面的媒体查询，不受源码顺序影响。 */
.venue-grid.venue-grid-lg {
    grid-template-columns: repeat(auto-fill, minmax(216px, 1fr));
    gap: var(--s5);
}

/* 极轻的 hover 抬升。只给图片主导的瓦片卡（venue/poster）：它们本体没有
   阴影面，抬升是唯一的「可点」反馈；软卡片（activity/hero-side）已有
   阴影加深，不再叠位移。 */
.venue-card { display: block; transition: transform var(--dur) var(--ease); }
.venue-card:hover { transform: translateY(-2px); }

.venue-card .venue-img {
    aspect-ratio: 16 / 10; overflow: hidden; border-radius: var(--r-sm); margin-bottom: 9px;
    background: var(--surface-2) center / cover no-repeat;
}
.venue-grid-lg .venue-card .venue-img { aspect-ratio: 4 / 3; }
.venue-card .venue-img img {
    width: 100%; height: 100%; object-fit: cover;
    transition: transform var(--dur-slow) var(--ease);
}
.venue-card:hover .venue-img img { transform: scale(1.04); }
.venue-card:hover .venue-name { color: var(--orange); }
.venue-name {
    font-size: 15px; font-weight: 700; line-height: 1.4; letter-spacing: -.2px;
    transition: color var(--dur-fast) var(--ease);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.venue-grid-lg .venue-name { font-size: 15.5px; }
.card-meta {
    display: flex; flex-wrap: wrap; gap: 5px; align-items: center;
    margin: 4px 0 0; font-size: 12.5px; color: var(--text-2);
}

/* ---- 海报网格（长期在演）---- */

.poster-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s5) var(--s4); }
@media (min-width: 768px)  { .poster-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .poster-grid { grid-template-columns: repeat(2, 1fr); } }

.poster-card { display: block; transition: transform var(--dur) var(--ease); }
.poster-card:hover { transform: translateY(-2px); }

.poster-card .poster-img {
    position: relative; aspect-ratio: 3 / 4; overflow: hidden;
    border-radius: var(--r-sm); margin-bottom: 9px;
    background: var(--surface-2) center / cover no-repeat;
}
.poster-card .poster-img img {
    width: 100%; height: 100%; object-fit: cover;
    transition: transform var(--dur-slow) var(--ease);
}
.poster-card:hover .poster-img img { transform: scale(1.04); }
.poster-card:hover .venue-name { color: var(--orange); }
/* 「展至 …」贴左上角（线上原位，评审确认）：海报的视觉重心和文字
   通常在下半部，角标压上去会盖内容；左上角是海报最少承载信息的区域。 */
.poster-date {
    position: absolute; left: 0; top: 0; padding: 3px 8px;
    font-size: 11px; font-weight: 600;
    border-radius: 0 0 var(--r-sm) 0;
    background: var(--scrim); color: #fff; backdrop-filter: blur(3px);
}

/* ---- 侧栏紧凑卡（promo）---- */

.promo-section + .promo-section { margin-top: var(--s7); }
.promo-header {
    font-size: 12px; font-weight: 800; letter-spacing: .11em; text-transform: uppercase;
    color: var(--text-2); padding-bottom: 9px;
    border-bottom: 1px solid var(--line); margin-bottom: var(--s1);
}
.promo-card {
    display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 11px;
    padding: 11px 0; border-bottom: 1px solid var(--line); align-items: center;
}
.promo-card:hover .promo-title { color: var(--orange); }
.promo-image {
    aspect-ratio: 3 / 4; border-radius: var(--r-sm); overflow: hidden;
    background: var(--surface-2) center / cover no-repeat;
}
.promo-image.square { aspect-ratio: 1; }
.promo-image img { width: 100%; height: 100%; object-fit: cover; }
.promo-title {
    font-size: 13.5px; font-weight: 700; line-height: 1.4; letter-spacing: -.2px;
    transition: color var(--dur-fast) var(--ease);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.promo-meta { font-size: 12px; color: var(--text-2); margin: 3px 0 0; }

/* ---- 侧栏二维码 ----
   白板是刻意的，不是漏改深色模式：二维码要有足够的明暗对比才扫得动，
   把它反色或叠在深色底上会直接扫不出来。 */

.qr-card { padding-top: var(--s4); text-align: center; }
.qr-card img {
    display: block; margin: 0 auto; width: 148px; height: auto;
    background: #fff; padding: 7px;
    border: 1px solid var(--line); border-radius: var(--r);
}
.qr-card figcaption {
    margin-top: 10px; font-size: 12.5px; line-height: 1.5; color: var(--text-2);
}

/* ---- 侧栏链接组 ---- */

.link-pills { display: flex; flex-wrap: wrap; gap: 6px; padding-top: var(--s3); }
.link-pills a {
    font-size: 13px; padding: 4px 12px;
    border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--text-2);
    transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.link-pills a:hover { border-color: var(--orange); color: var(--orange-text); }

.sidebar { display: flex; flex-direction: column; gap: var(--s7); min-width: 0; }
@media (min-width: 1000px) {
    /* 侧栏是全站最有效的二次发现位，吸顶常驻。
       这里的 top 只是装得下时的默认值：装不下时 base.html 会把它改成负值，
       让侧栏先跟着页面往上走、露完最后一屏再钉住。
       （原来挂的是 max-height + overflow-y:auto，但 macOS 一类悬浮滚动条平台上
       那条内层滚动条根本看不见，底部内容会无声消失——评审时二维码就是这么丢的。） */
    .sidebar { position: sticky; top: calc(var(--hdr-h) + var(--s5)); align-self: start; }
}

/* ============================================================ 8. 按钮 */

.btn {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 14px; font-weight: 700; padding: 10px 17px;
    border-radius: var(--r); white-space: nowrap; cursor: pointer;
    font-family: inherit;
    background: var(--orange); color: var(--orange-ink);
    border: 1px solid var(--orange);
    transition: filter var(--dur-fast) var(--ease);
}
.btn:hover { filter: brightness(1.08); }
.btn-primary { /* 与 .btn 同义，保留语义别名 */ }
.btn-outline {
    background: none; color: var(--text); border-color: var(--line-2);
}
.btn-outline:hover { border-color: var(--orange); color: var(--orange-text); filter: none; }
.btn-on-band {
    background: none; color: var(--band-text); border-color: var(--band-line);
}
.btn-on-band:hover { border-color: var(--orange); color: var(--orange-text); filter: none; }
/* 分享是要主动鼓励的动作：橙描边把它从中性按钮里抬出来，
   又不与实心主按钮（导航/报名）抢主次。hover 反转成实心。 */
.btn-share {
    background: none; color: var(--orange-text); border-color: var(--orange);
}
.btn-share:hover { background: var(--orange); color: var(--orange-ink); filter: none; }
.btn[disabled], .btn.disabled {
    opacity: .45; pointer-events: none;
}

/* ============================================================ 9. 空 / 薄状态 */

.thin-notice {
    display: flex; gap: 10px; padding: 13px 15px;
    font-size: 13.5px; color: var(--text-2);
    background: var(--surface); border-left: 3px solid var(--gold);
    margin-bottom: var(--s5);
}
.thin-notice b { color: var(--text); }

.empty-state {
    padding: var(--s8) var(--s4); text-align: center;
    border-top: 2px solid var(--text);
}
.empty-state h2 {
    font-size: 21px; font-weight: 800; letter-spacing: -.5px; margin-bottom: 9px;
}
@media (min-width: 600px) { .empty-state h2 { font-size: 23px; } }
.empty-state p {
    max-width: 46ch; margin: 0 auto; color: var(--text-2);
    font-size: 14.5px; line-height: 1.75;
}
.empty-actions {
    display: flex; flex-wrap: wrap; gap: 9px; justify-content: center;
    margin-top: var(--s6);
}
.section-empty {
    grid-column: 1 / -1; padding: var(--s6) var(--s4); text-align: center;
    font-size: 13.5px; color: var(--text-3);
    border: 1px dashed var(--line); border-radius: var(--r);
}

/* ============================================================ 10. 分页
   两套标记共存：pager_service 已改为返回数据、由宏渲染，两个频道统一到
   .page-item / .page-item.active / .pagination-prev / -next / -ellipsis。
   不得用 :first-child 之类位置选择器区分——第 1 页的首个子元素是页码不是「上一页」。 */

.pagination {
    display: flex; justify-content: center; flex-wrap: wrap; gap: 5px;
    padding: var(--s7) 0 0; font-size: 14px;
}
.page-item {
    min-width: 34px; height: 34px;
    display: grid; place-items: center; padding: 0 9px;
    border-bottom: 2px solid transparent; color: var(--text-2);
    transition: color var(--dur-fast) var(--ease);
}
a.page-item:hover { color: var(--orange-text); }
.page-item.active {
    color: var(--text); font-weight: 800; border-bottom-color: var(--orange);
}
.pagination-ellipsis {
    min-width: 34px; height: 34px; display: grid; place-items: center;
    color: var(--text-3);
}

/* ============================================================ 11. SEO 区块 */

.landing-intro {
    margin-top: var(--s6); max-width: 68ch;
    font-size: 15px; line-height: 1.78; color: var(--text-2);
}

.landing-faq { padding: var(--s7) 0 0; }
.landing-faq h2 { font-size: 19px; font-weight: 800; letter-spacing: -.4px; margin-bottom: var(--s4); }
.faq-item { padding: var(--s4) 0; border-bottom: 1px solid var(--line); max-width: 72ch; }
.faq-item h3 { font-size: 15px; font-weight: 700; margin-bottom: 7px; }
.faq-item p { margin: 0; font-size: 14.5px; line-height: 1.78; color: var(--text-2); }

.landing-links { padding: var(--s7) 0 0; }
.landing-links h2 { font-size: 19px; font-weight: 800; letter-spacing: -.4px; margin-bottom: var(--s4); }
.links-group {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 15px;
    padding: var(--s3) 0; border-bottom: 1px solid var(--line);
}
.links-label {
    flex: none; font-size: 13px; font-weight: 700; color: var(--text-2);
    min-width: 92px;
}
/* 纯文字 + 着重色，不带框（沿用线上的做法）：这个区块是「相关阅读」不是控件，
   描边小块是按钮的语言，会和页顶真正的筛选器抢身份。间距代替边框做分隔。 */
.links-group a {
    font-size: 13px; color: var(--orange-text);
    transition: color var(--dur-fast) var(--ease);
}
.links-group a:hover { text-decoration: underline; text-underline-offset: 3px; }

.landing-ended { padding: var(--s7) 0 0; }
.landing-ended h2 { font-size: 17px; font-weight: 800; letter-spacing: -.3px; margin-bottom: var(--s3); }
.ended-list { display: flex; flex-direction: column; }
.ended-item {
    display: flex; justify-content: space-between; gap: var(--s4);
    padding: 10px 0; border-bottom: 1px solid var(--line);
    font-size: 13.5px; color: var(--text-3);
}
.ended-item:hover { color: var(--text-2); }
.ended-item span { flex: none; }

/* ============================================================ 12. 首页 */

.hero-top { display: block; }
@media (min-width: 768px) {
    .hero-top {
        display: flex; align-items: flex-end; justify-content: space-between;
        gap: var(--s6); flex-wrap: wrap;
    }
    .hero-top .hero-chips { margin-top: 0; overflow-x: visible; }
}

.hero-chips {
    display: flex; gap: 7px; margin-top: var(--s5);
    overflow-x: auto; scrollbar-width: none; padding-bottom: 2px;
}
.hero-chips::-webkit-scrollbar { display: none; }

.hero-grid { display: grid; gap: var(--s4); margin-top: var(--s5); }
@media (min-width: 768px) { .hero-grid { grid-template-columns: 1.6fr 1fr; align-items: stretch; } }

.hero-card {
    position: relative; display: block; overflow: hidden; border-radius: var(--r-sm);
    aspect-ratio: 4 / 3;
    background: var(--surface-2) center / cover no-repeat;
}
@media (min-width: 900px) { .hero-card { aspect-ratio: 16 / 10; } }
.hero-card img {
    width: 100%; height: 100%; object-fit: cover;
    transition: transform var(--dur-slow) var(--ease);
}
.hero-card:hover img { transform: scale(1.03); }
.hero-card-body {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: var(--s5) var(--s4) var(--s4); color: #fff;
    background: linear-gradient(transparent, var(--scrim-strong) 62%);
}
.hero-card-title {
    font-size: 19px; font-weight: 800; line-height: 1.32; letter-spacing: -.4px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
@media (min-width: 600px) { .hero-card-title { font-size: 23px; letter-spacing: -.6px; } }
.hero-card-meta { margin: 7px 0 0; font-size: 13px; opacity: .86; }
.hero-card .tag { background: var(--on-image-fill); color: #fff; }
.hero-card .tag-hot { background: var(--orange); color: var(--orange-ink); }

/* hero 右侧两张，撑满大卡高度 */
.hero-side { display: grid; gap: var(--s3); }
@media (min-width: 768px) { .hero-side { grid-template-rows: repeat(3, 1fr); } }
.hero-side-card {
    display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: var(--s3);
    align-items: center; padding: var(--s3);
    background: var(--surface);
    border: 1px solid var(--card-border); border-radius: var(--r);
    box-shadow: var(--shadow-1);
    transition: box-shadow var(--dur) var(--ease);
}
@media (min-width: 768px) {
    .hero-side-card { grid-template-columns: 76px minmax(0, 1fr); gap: var(--s3); padding: var(--s2) var(--s3); }
}
.hero-side-card:hover { box-shadow: var(--shadow-2); }
.hero-side-card:hover h3 { color: var(--orange); }
.hero-side-img {
    aspect-ratio: 3 / 4; border-radius: var(--r-sm); overflow: hidden;
    background: var(--band-fill-soft) center / cover no-repeat;
}
.hero-side-img img { width: 100%; height: 100%; object-fit: cover; }
.hero-side-date {
    font-size: 11.5px; font-weight: 700; color: var(--gold-ink);
    display: block; margin-bottom: 5px;
}
.hero-side-card h3 {
    font-size: 14.5px; font-weight: 700; line-height: 1.4; letter-spacing: -.2px;
    color: var(--band-text); transition: color var(--dur-fast) var(--ease);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.hero-side-card .card-meta { color: var(--band-sub); margin-top: 6px; }

/* ≥1024px 即将开场与随时可去并排 */
.home-cols { display: grid; gap: 0; }
@media (min-width: 1024px) {
    .home-cols { grid-template-columns: 1.34fr 1fr; gap: var(--s7); align-items: start; }
}
.home-block { padding-top: var(--s6); }

.cat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3); }
@media (min-width: 768px) { .cat-row { grid-template-columns: repeat(6, 1fr); } }
.cat-entry {
    display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
    padding: 13px 14px; border: 1px solid var(--line); border-radius: var(--r);
    transition: border-color var(--dur-fast) var(--ease);
}
.cat-entry:hover { border-color: var(--orange); }
.cat-entry:hover b { color: var(--orange); }
.cat-icon { font-size: 19px; line-height: 1; }
.cat-entry b {
    font-size: 14.5px; font-weight: 700; letter-spacing: -.2px;
    transition: color var(--dur-fast) var(--ease);
}
.cat-entry i {
    font-size: 12px; font-style: normal; color: var(--gold-ink);
    font-weight: 700; font-variant-numeric: tabular-nums;
}

.city-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); }
@media (min-width: 768px) { .city-grid { grid-template-columns: repeat(5, 1fr); gap: var(--s3); } }
.city-cell {
    display: flex; align-items: baseline; gap: 5px; padding: 11px 12px;
    font-size: 14px; font-weight: 700; letter-spacing: -.2px;
    border: 1px solid var(--band-line); border-radius: var(--r);
    color: var(--band-text);
    transition: border-color var(--dur-fast) var(--ease);
}
.city-cell:hover { border-color: var(--orange); color: var(--orange-text); }
.city-cell.active {
    background: var(--orange); border-color: var(--orange); color: var(--orange-ink);
}
.city-cell i {
    font-size: 11.5px; font-style: normal; font-weight: 400; opacity: .6;
    font-variant-numeric: tabular-nums;
}

/* 我附近 */
.nearby-section { padding-top: var(--s6); }
.nearby-scroll {
    display: flex; gap: var(--s4); overflow-x: auto;
    scrollbar-width: none; padding-bottom: var(--s2);
}
.nearby-scroll::-webkit-scrollbar { display: none; }
.nearby-card { flex: 0 0 148px; }
.nearby-card-image {
    aspect-ratio: 4 / 3; overflow: hidden; border-radius: var(--r-sm); margin-bottom: 8px;
    background: var(--surface-2) center / cover no-repeat;
}
.nearby-card-image img { width: 100%; height: 100%; object-fit: cover; }
.nearby-card-title {
    font-size: 14px; font-weight: 700; line-height: 1.4; margin: 0;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.nearby-card:hover .nearby-card-title { color: var(--orange); }
.nearby-card-distance { font-size: 12.5px; color: var(--text-2); }
.location-hint { font-size: 13px; color: var(--text-3); margin: 0 0 var(--s3); }

/* ============================================================ 13. 详情页 */

.detail-hero { display: grid; gap: var(--s5); margin-top: var(--s4); }
@media (min-width: 900px) {
    .detail-hero {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
        gap: var(--s7); align-items: start;
    }
}

/* 纯墨色，不画橙线：见 .page-title-mark 的注释。
   字重 800 是深色带时代定的——浅字压深底需要加重才立得住；换成白底墨字后
   同一档就变成嘶吼，活动详情抓来的长标题（常折两三行）尤其明显。
   降 700、封顶 30px、行高放到 1.3，多行才读得动。列表页 h1 不跟着降：
   那边是「上海活动」这类两三个字的地名标题，一行、短，大而粗是身份不是噪音。 */
.detail-title {
    font-size: clamp(22px, 3.6vw, 30px); font-weight: 700;
    letter-spacing: -.4px; line-height: 1.3;
}
.detail-subtitle { font-size: 14px; color: var(--band-sub); margin: 9px 0 0; letter-spacing: .02em; }
.detail-meta {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin-top: var(--s4); font-size: 13.5px; color: var(--band-sub);
}
.detail-address {
    display: flex; gap: 9px; margin: var(--s4) 0 0;
    font-size: 14px; color: var(--band-text); line-height: 1.6;
}
.detail-address .pin { flex: none; color: var(--orange); }
.detail-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--s5); }

/* 结构化信息表（活动详情） */
.info-list { display: grid; margin-top: var(--s5); }
.info-item {
    display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: var(--s3);
    padding: 10px 0; border-top: 1px solid var(--band-line);
    font-size: 14px; line-height: 1.6;
}
.info-label { color: var(--band-sub); font-size: 13px; }
.info-value { color: var(--band-text); }
/* 票价是全页唯一该上色的数据（参考的票务产品一律如此）。19px/800 属大号文本，
   3:1 即达标，#ff5a1f 在近白上是 3.2:1。日期一类不上色，靠字重区分。 */
.info-value.emphasis {
    font-size: 19px; font-weight: 800; letter-spacing: -.4px;
    color: var(--orange); font-variant-numeric: tabular-nums;
}

/* 锚点导航 */
.jump-nav {
    position: sticky; top: var(--hdr-h); z-index: calc(var(--z-sticky) - 1);
    display: flex; gap: 3px; overflow-x: auto; scrollbar-width: none;
    padding: 9px 0; background: var(--paper); border-bottom: 1px solid var(--line);
}
.jump-nav::-webkit-scrollbar { display: none; }
.jump-nav a {
    flex: 0 0 auto; font-size: 13px; padding: 5px 11px;
    color: var(--text-2); white-space: nowrap; border-bottom: 2px solid transparent;
}
.jump-nav a:hover { color: var(--orange-text); }
.jump-nav a.active { color: var(--text); font-weight: 700; border-bottom-color: var(--orange); }

/* 章节线保留（评审确认要）。轻量化改从字号字重上取：
   h2 由 800/19px 降到 700/18px，线仍是墨色但只占一重强调而非三重。 */
.detail-section {
    padding: var(--s6) 0 0;
    scroll-margin-top: calc(var(--hdr-h) + 56px);
}
.detail-section > h2 {
    font-size: 18px; font-weight: 700; letter-spacing: -.3px;
    padding-bottom: var(--s3); border-bottom: 2px solid var(--text);
    margin-bottom: var(--s4);
    display: flex; align-items: baseline; gap: 9px;
}
.detail-section > h2 .section-note {
    font-size: 12.5px; font-weight: 400; color: var(--text-3); letter-spacing: 0;
}

/* 正文：限宽 + 提高行高，线上是 14px/1.5 顶宽铺满，长段落很难读 */
.prose { max-width: 68ch; }
.prose p { margin: 0 0 13px; font-size: 15px; line-height: 1.78; color: var(--text-2); }
.prose p:last-child { margin-bottom: 0; }
.prose ul, .prose ol {
    margin: 0; padding-left: 1.35em; font-size: 15px; line-height: 1.78; color: var(--text-2);
}
.prose li { margin-bottom: 9px; padding-left: 2px; }
.prose ol li::marker { color: var(--gold-ink); font-weight: 800; }
.prose strong { color: var(--text); font-weight: 700; }

/* 短区块桌面端两两并排，把长详情页的翻滚长度压掉近一半 */
.section-pair { display: grid; gap: 0; }
@media (min-width: 760px) { .section-pair { grid-template-columns: 1fr 1fr; gap: 0 var(--s7); } }

.tag-row { display: flex; flex-wrap: wrap; gap: 7px; }
.tag-row span {
    font-size: 13px; padding: 5px 12px; border-radius: var(--r);
    background: var(--surface-2); color: var(--text-2);
}

/* ---- 相册 ---- */

/* 桌面：一张主图 + 一行缩略图。点缩略图只换主图（不打断浏览），
   点主图才进灯箱看大图。移动：主图区变成横滑序列 + 下方指示条。 */
.gallery { display: flex; flex-direction: column; gap: 6px; }

.gallery-stage {
    display: flex; overflow: hidden;
    border-radius: var(--r-sm); background: var(--surface-2);
}
.gallery-stage figure {
    position: relative; margin: 0; flex: 0 0 100%;
    aspect-ratio: 16 / 9; overflow: hidden; cursor: zoom-in;
}
.gallery-stage img { width: 100%; height: 100%; object-fit: cover; }
/* 桌面只显示当前那张 */
@media (min-width: 600px) {
    .gallery-stage figure { display: none; }
    .gallery-stage figure.active { display: block; }
    .gallery-stage .gallery-count { display: none; }
}
/* 单栏宽度（600–900px）下主图会占满整宽变得极高，把标题与信息全挤出首屏。
   用固定高度而非 max-height——后者配 aspect-ratio 会让宽度跟着缩。 */
@media (min-width: 600px) and (max-width: 899px) {
    .gallery-stage figure { aspect-ratio: auto; height: clamp(200px, 32vh, 280px); }
}

.gallery-count {
    position: absolute; right: 8px; bottom: 8px;
    display: flex; align-items: center; gap: 5px;
    padding: 4px 10px; border-radius: var(--r);
    font-size: 12px; font-weight: 600;
    background: var(--scrim); color: #fff;
    backdrop-filter: blur(4px); pointer-events: none;
}

/* 桌面缩略行。定宽而不是 flex:1——拉伸会让「只有 3 张图」的场馆
   把缩略图撑到主图的三分之一宽，一条选择器占掉的视觉权重远超它的功能。 */
.gallery-thumbs { display: flex; flex-wrap: wrap; gap: 6px; }
.gallery-thumbs button {
    flex: 0 0 auto; width: 76px; padding: 0; cursor: pointer;
    aspect-ratio: 4 / 3; overflow: hidden; border-radius: var(--r-sm);
    border: 2px solid transparent; background: var(--surface-2);
    transition: border-color var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
    opacity: .62;
}
.gallery-thumbs button:hover { opacity: 1; }
.gallery-thumbs button.active { border-color: var(--orange); opacity: 1; }
.gallery-thumbs img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumbs .more {
    display: grid; place-items: center; font-size: 12px; font-weight: 700;
    color: var(--band-text); background: var(--band-fill); opacity: 1;
}

/* 移动指示条：短横线，可点可滑 */
.gallery-dots { display: none; gap: 5px; justify-content: center; padding-top: 2px; }
.gallery-dots button {
    width: 18px; height: 3px; padding: 0; border: 0; cursor: pointer;
    border-radius: var(--r-sm); background: var(--band-line);
    transition: background var(--dur-fast) var(--ease), width var(--dur-fast) var(--ease);
}
.gallery-dots button.active { background: var(--orange); width: 26px; }

@media (max-width: 599px) {
    .gallery-stage {
        overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
        margin-inline: -16px; padding-inline: 16px; gap: 6px; background: none;
    }
    .gallery-stage::-webkit-scrollbar { display: none; }
    .gallery-stage figure {
        flex: 0 0 84%; scroll-snap-align: center;
        border-radius: var(--r-sm); background: var(--surface-2);
    }
    .gallery-thumbs { display: none; }
    .gallery-dots { display: flex; }
}

/* ---- 灯箱 ---- */

.lightbox {
    position: fixed; inset: 0; z-index: var(--z-lightbox);
    background: var(--lightbox-bg); color: var(--band-text);
    display: none; flex-direction: column;
}
.lightbox.active { display: flex; }
.lightbox-top {
    display: flex; align-items: center; gap: var(--s4);
    padding: var(--s4); font-size: 13px; flex: none;
}
.lightbox-count { font-variant-numeric: tabular-nums; opacity: .8; }
.lightbox-close {
    margin-left: auto; width: 36px; height: 36px;
    display: grid; place-items: center; cursor: pointer;
    border: 1px solid var(--on-image-outline); border-radius: var(--r);
    background: none; color: inherit;
}
.lightbox-close:hover { border-color: var(--orange); }
.lightbox-stage {
    flex: 1; position: relative; display: grid; place-items: center;
    min-height: 0; padding: 0 var(--s4);
}
.lightbox-stage img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--r-sm); }
.lightbox-arrow {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 44px; height: 44px; display: grid; place-items: center;
    border: 1px solid var(--on-image-outline); border-radius: var(--r);
    background: var(--scrim); color: inherit; cursor: pointer;
}
.lightbox-arrow:hover { border-color: var(--orange); color: var(--orange); }
.lightbox-arrow.prev { left: var(--s2); }
.lightbox-arrow.next { right: var(--s2); }
@media (max-width: 599px) { .lightbox-arrow { display: none; } }
.lightbox-thumbs {
    flex: none; display: flex; gap: 6px; overflow-x: auto;
    scrollbar-width: none; padding: var(--s4);
}
.lightbox-thumbs::-webkit-scrollbar { display: none; }
.lightbox-thumbs button {
    flex: 0 0 auto; width: 58px; aspect-ratio: 1; padding: 0; cursor: pointer;
    border: 1px solid transparent; border-radius: var(--r-sm); overflow: hidden;
    background: var(--lightbox-tile) center / cover no-repeat;
}
.lightbox-thumbs button.active { border-color: var(--orange); }
.lightbox-thumbs img { width: 100%; height: 100%; object-fit: cover; }
.lightbox-hint { text-align: center; font-size: 12px; opacity: .45; padding: 0 var(--s4) var(--s4); }

/* ---- 分享面板 ---- */

.share-panel {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-drawer);
    background: var(--surface); color: var(--text);
    padding: var(--s5) var(--s5) var(--s6);
    border-radius: 10px 10px 0 0;
    transform: translateY(101%);
    transition: transform var(--dur) var(--ease);
    box-shadow: 0 -8px 32px rgba(0, 0, 0, .22);
}
.share-panel.active { transform: none; }
@media (min-width: 600px) {
    .share-panel {
        left: 50%; right: auto; top: 50%; bottom: auto; width: 336px;
        border-radius: var(--r);
        transform: translate(-50%, -46%); opacity: 0; visibility: hidden;
        transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease),
                    visibility var(--dur);
    }
    .share-panel.active { transform: translate(-50%, -50%); opacity: 1; visibility: visible; }
}
.share-panel h2 { font-size: 15px; font-weight: 800; letter-spacing: -.3px; margin-bottom: var(--s2); }
.share-panel .share-sub { font-size: 12.5px; color: var(--text-2); margin: 0 0 var(--s5); }
.share-hint {
    margin: 0 0 var(--s4); padding: 9px 12px;
    font-size: 12.5px; line-height: 1.6; color: var(--text-2);
    background: var(--surface-2); border-radius: var(--r-sm);
}
.share-hint b { color: var(--text); letter-spacing: 2px; }

.share-channels {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s4) var(--s3);
    margin-bottom: var(--s5);
}
.share-channel-btn {
    display: flex; flex-direction: column; align-items: center; gap: 7px;
    font-size: 12px; color: var(--text-2);
    background: none; border: 0; cursor: pointer; font-family: inherit;
}
.share-channel-btn i {
    width: 44px; height: 44px; display: grid; place-items: center;
    border-radius: 50%; background: var(--surface-2); color: var(--text);
    transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.share-channel-btn:hover i { background: var(--orange); color: var(--orange-ink); }
/* 二维码区显隐由 JS 读写内联 style.display 控制，此处不得改用 class */
.share-qrcode-area {
    display: grid; place-items: center; gap: 9px;
    padding: var(--s5) 0 var(--s2); border-top: 1px solid var(--line);
}
.share-qrcode-area > div { background: #fff; padding: 8px; border-radius: var(--r-sm); }
.share-qrcode-area p { margin: 0; font-size: 12px; color: var(--text-2); }
.share-link {
    display: flex; gap: 8px; align-items: center; padding: 9px 11px;
    border: 1px solid var(--line); border-radius: var(--r);
    font-size: 12.5px; color: var(--text-2); margin-top: var(--s4);
}
.share-link span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-link button {
    flex: none; font-size: 12.5px; font-weight: 700; color: var(--orange-text);
    background: none; border: 0; cursor: pointer; font-family: inherit;
}

/* ---- 地图 ----
   #venue-map 必须有非零高度，高德在 0 高度容器里渲染空白。 */

.map-container { margin-top: var(--s2); }
#venue-map {
    width: 100%; height: 400px;
    border: 1px solid var(--line); border-radius: var(--r-sm);
    background: var(--surface-2);
}
.map-placeholder {
    width: 100%; height: 100%; display: grid; place-items: center;
    color: var(--text-3); font-size: 13px;
}

/* ============================================================ 14. notice 页 */

.notice-container { padding: var(--s6) 0 var(--s8); }
.notice-nav {
    display: flex; gap: 3px; overflow-x: auto; scrollbar-width: none;
    padding-bottom: var(--s3); margin-bottom: var(--s6);
    border-bottom: 1px solid var(--line);
}
.notice-nav::-webkit-scrollbar { display: none; }
.notice-nav-item {
    flex: 0 0 auto; font-size: 14px; padding: 7px 13px;
    color: var(--text-2); white-space: nowrap; cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: color var(--dur-fast) var(--ease),
                border-color var(--dur-fast) var(--ease);
}
.notice-nav-item:hover { color: var(--orange-text); }
.notice-nav-item.active { color: var(--text); font-weight: 700; border-bottom-color: var(--orange); }

/* tab 切换：switchTab() 靠 .active 控制显隐，CSS 必须给出对应规则，
   否则六个区块会同时铺开、点 tab 毫无反应。 */
.notice-section { display: none; padding-top: var(--s6); }
.notice-section.active { display: block; }
.notice-header { margin-bottom: var(--s5); }
.notice-title {
    font-size: 21px; font-weight: 800; letter-spacing: -.4px;
    padding-bottom: var(--s3); border-bottom: 2px solid var(--text);
}
.notice-subtitle { font-size: 13.5px; color: var(--text-2); margin: 9px 0 0; }
.notice-content { max-width: 72ch; }
.notice-list { display: flex; flex-direction: column; list-style: none; }
.notice-item { padding: var(--s4) 0; border-bottom: 1px solid var(--line); }
.notice-item-header {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s3);
    margin-bottom: 7px;
}
.notice-item-title { font-size: 15.5px; font-weight: 700; letter-spacing: -.2px; }
.notice-item-date {
    font-size: 12.5px; color: var(--text-3); font-variant-numeric: tabular-nums;
}
.notice-item-content { font-size: 14.5px; line-height: 1.78; color: var(--text-2); }
.notice-item-footer { margin-top: 9px; display: flex; gap: var(--s3); align-items: center; }
.notice-tag {
    font-size: 11px; padding: 2px 8px; border-radius: var(--r-sm);
    background: var(--surface-2); color: var(--text-2);
}
.notice-more { font-size: 13px; font-weight: 600; color: var(--orange); }
.notice-more:hover { text-decoration: underline; }

.about-content { max-width: 72ch; }
.about-paragraph { font-size: 15px; line-height: 1.78; color: var(--text-2); margin: 0 0 14px; }

.team-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--s5); margin-top: var(--s5);
}
.team-member { text-align: center; }
.team-member-avatar {
    width: 72px; height: 72px; margin: 0 auto var(--s3);
    border-radius: 50%; overflow: hidden; background: var(--surface-2);
}
.team-member-avatar img { width: 100%; height: 100%; object-fit: cover; }
.team-member-name { font-size: 14.5px; font-weight: 700; }
.team-member-position { font-size: 12.5px; color: var(--text-2); margin-top: 3px; }

/* ============================================================ 15. 页脚 */

.footer {
    background: var(--surface-2); color: var(--text-2);
    padding: var(--s7) 0; font-size: 13px;
    border-top: 1px solid var(--line);
}
.footer-content { display: flex; flex-wrap: wrap; gap: var(--s6) var(--s8); }
.footer-section h3 {
    font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--band-text); margin-bottom: 10px; opacity: .75;
}
.footer-section ul { list-style: none; display: grid; gap: 7px; }
.footer-section a:hover { color: var(--orange-text); }
.footer-bottom {
    margin-top: var(--s6); padding-top: var(--s4);
    border-top: 1px solid var(--band-hairline);
    font-size: 12px; opacity: .6;
}
.footer-bottom a:hover { color: var(--orange-text); }

/* ============================================================ 16. 工具类 */

/* 首页防闪帘：有城市 cookie 时 base.html 会在首帧前给 <html> 打上
   data-hd-veil，把待替换的城市化区块藏住，home.html 换完内容后揭帘淡入。
   遮的时候不带过渡（要瞬间藏住），揭帘走 opacity 过渡。 */
[data-hd-target] { transition: opacity .18s var(--ease); }
html[data-hd-veil] [data-hd-target] { opacity: 0; transition: none; }

/* 懒加载：base.html 的 initLazyImages 观察 img[data-src]，命中后加 .fade-in */
.lazy-image { opacity: 1; }
.fade-in { animation: fade-in var(--dur-slow) var(--ease); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

@media (max-width: 860px) {
    .nav-menu, .search-box { display: none; }
    .hamburger { display: grid; }
    .header-container { gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        transition: none !important; animation: none !important;
    }
}
