/* ============================================================
   FSTyule · 演出项目信息台
   ------------------------------------------------------------
   视觉系统：多主题（data-theme）+ 质感层 + 动效层
   设计取向：克制的呼吸感 —— 光晕、噪点、玻璃、逐段浮现
   ============================================================ */

:root{
  --radius-s: 8px;
  --radius-m: 14px;
  --radius-l: 20px;
  --radius-xl: 28px;
  /* ★ 底部双 Tab 栏尺寸：所有 padding/高度都由这几个变量推导，
       这样底栏真实高度和 body 预留的间距永远一致（曾因两处写死不同步导致遮挡） */
  --tabbar-pad-t: 9px;
  --tabbar-pad-x: 10px;
  --tabbar-pad-b: 13px;
  --tabbar-btn-h: 42px;
  --tabbar-h: calc(var(--tabbar-pad-t) + var(--tabbar-btn-h) + var(--tabbar-pad-b));
  --topbar-h: 60px;

  --font: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
          "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", sans-serif;
  --font-num: ui-rounded, "SF Pro Rounded", -apple-system, "Segoe UI", "PingFang SC", sans-serif;

  --ease: cubic-bezier(.32,.72,.28,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease-spring: cubic-bezier(.34,1.42,.5,1);

  /* 默认（纸感）阴影，主题可覆盖 */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.04), 0 2px 8px rgba(0,0,0,.035);
  --shadow-md: 0 4px 16px rgba(0,0,0,.08), 0 14px 36px rgba(0,0,0,.06);
  --shadow-lg: 0 12px 34px rgba(0,0,0,.13), 0 34px 68px rgba(0,0,0,.09);

  /* 通用动效参数 */
  --dur-fast: .18s;
  --dur: .28s;
  --dur-slow: .5s;

  /* 噪点强度 */
  --noise-opacity: .32;
  /* 背景光晕强度 */
  --aura-opacity: .55;
  /* 卡片光晕半径 */
  --glow-r: 340px;
  /* 封面饱和度（项目专属色用） */
  --poster-sat: 46%;
  --poster-sat-2: 34%;
  --poster-lum: 40%;
  --poster-veil: .34;
}

/* ============================================================
   主题 01：PAPER 素雅纸质
   ============================================================ */
[data-theme="paper"]{
  --poster-sat: 34%; --poster-sat-2: 26%; --poster-lum: 38%; --poster-veil: .30;
  --bg: #f4f3ee; --bg-elev: #ffffff; --bg-card: #ffffff; --bg-card-hover: #fffefb;
  --surface: rgba(31,28,22,.032); --surface-strong: rgba(31,28,22,.062);
  --border: rgba(31,28,22,.088); --border-strong: rgba(31,28,22,.17);
  --text: #191713; --text-dim: #67635a; --text-faint: #a19d94;
  --accent: #c04a30; --accent-2: #b3831a; --accent-3: #d9724a;
  --accent-glow: rgba(192,74,48,.20);
  --accent-soft: rgba(192,74,48,.075);
  --discount-bg: linear-gradient(135deg,#c04a30,#d9724a 55%,#b3831a);
  --card-grad: linear-gradient(158deg, rgba(192,74,48,.05), transparent 58%);
  --topbar-bg: rgba(244,243,238,.80);
  --hero-grad: linear-gradient(150deg, rgba(192,74,48,.075), rgba(179,131,26,.03) 58%, transparent);
  --grid-gap: 18px; --card-radius: 14px;
  --noise-opacity: .30; --aura-opacity: .32;
  --shadow-sm: 0 1px 2px rgba(25,23,19,.045), 0 2px 8px rgba(25,23,19,.04);
  --shadow-md: 0 3px 12px rgba(25,23,19,.06), 0 14px 32px rgba(25,23,19,.05);
  --shadow-lg: 0 10px 28px rgba(25,23,19,.09), 0 28px 56px rgba(25,23,19,.07);
}

/* ============================================================
   主题 02：MINT 清新薄荷
   ============================================================ */
[data-theme="mint"]{
  --poster-sat: 40%; --poster-sat-2: 30%; --poster-lum: 38%; --poster-veil: .28;
  --bg: #effaf6; --bg-elev: #ffffff; --bg-card: #ffffff; --bg-card-hover: #fbfffd;
  --surface: rgba(12,86,76,.035); --surface-strong: rgba(12,86,76,.072);
  --border: rgba(12,86,76,.10); --border-strong: rgba(12,86,76,.21);
  --text: #072b26; --text-dim: #47776d; --text-faint: #8db3aa;
  --accent: #0a9384; --accent-2: #12b3a2; --accent-3: #45c9b4;
  --accent-glow: rgba(10,147,132,.24);
  --accent-soft: rgba(10,147,132,.08);
  --discount-bg: linear-gradient(135deg,#0a9384,#12b3a2 55%,#45c9b4);
  --card-grad: linear-gradient(158deg, rgba(10,147,132,.075), transparent 58%);
  --topbar-bg: rgba(239,250,246,.82);
  --hero-grad: linear-gradient(150deg, rgba(10,147,132,.10), rgba(18,179,162,.04) 58%, transparent);
  --grid-gap: 16px; --card-radius: 18px;
  --noise-opacity: .26; --aura-opacity: .40;
  --shadow-sm: 0 1px 2px rgba(7,43,38,.045), 0 2px 8px rgba(7,43,38,.035);
  --shadow-md: 0 3px 12px rgba(7,43,38,.06), 0 14px 32px rgba(7,43,38,.05);
  --shadow-lg: 0 10px 28px rgba(7,43,38,.09), 0 28px 56px rgba(7,43,38,.07);
}

/* ============================================================
   主题 03：AURORA 极光深色
   ============================================================ */
[data-theme="aurora"]{
  --poster-sat: 52%; --poster-sat-2: 38%; --poster-lum: 36%; --poster-veil: .30;
  --bg: #07080f; --bg-elev: #0f1119; --bg-card: #12141f; --bg-card-hover: #171a28;
  --surface: rgba(255,255,255,.05); --surface-strong: rgba(255,255,255,.09);
  --border: rgba(255,255,255,.09); --border-strong: rgba(255,255,255,.19);
  --text: #f3f5fc; --text-dim: #99a1bd; --text-faint: #616a86;
  --accent: #8b7bff; --accent-2: #45d6cf; --accent-3: #b98cff;
  --accent-glow: rgba(139,123,255,.46);
  --accent-soft: rgba(139,123,255,.14);
  --discount-bg: linear-gradient(135deg,#8b7bff,#45d6cf);
  --card-grad: linear-gradient(158deg, rgba(139,123,255,.16), rgba(69,214,207,.05) 58%, transparent);
  --topbar-bg: rgba(7,8,15,.72);
  --hero-grad: linear-gradient(150deg, rgba(139,123,255,.18), rgba(69,214,207,.05) 58%, transparent);
  --grid-gap: 16px; --card-radius: 20px;
  --noise-opacity: .22; --aura-opacity: .85;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4), 0 2px 10px rgba(0,0,0,.3);
  --shadow-md: 0 6px 20px rgba(0,0,0,.45), 0 18px 44px rgba(0,0,0,.35);
  --shadow-lg: 0 14px 40px rgba(0,0,0,.55), 0 40px 80px rgba(0,0,0,.45);
}

/* ============================================================
   主题 04：NEON 霓虹播报
   ============================================================ */
[data-theme="neon"]{
  --poster-sat: 54%; --poster-sat-2: 40%; --poster-lum: 34%; --poster-veil: .32;
  --bg: #0c0619; --bg-elev: #170d2c; --bg-card: #1b1035; --bg-card-hover: #231445;
  --surface: rgba(255,255,255,.055); --surface-strong: rgba(255,255,255,.10);
  --border: rgba(255,90,180,.17); --border-strong: rgba(255,90,180,.36);
  --text: #fff5fd; --text-dim: #b8a3d6; --text-faint: #7a6694;
  --accent: #ff3d9a; --accent-2: #ffd60a; --accent-3: #a855f7;
  --accent-glow: rgba(255,61,154,.50);
  --accent-soft: rgba(255,61,154,.14);
  --discount-bg: linear-gradient(135deg,#ff3d9a,#a855f7 50%,#ffd60a);
  --card-grad: linear-gradient(152deg, rgba(255,61,154,.20), rgba(168,85,247,.13) 50%, transparent);
  --topbar-bg: rgba(12,6,25,.74);
  --hero-grad: linear-gradient(150deg, rgba(255,61,154,.20), rgba(168,85,247,.10) 55%, transparent);
  --grid-gap: 14px; --card-radius: 18px;
  --noise-opacity: .20; --aura-opacity: .95;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.45), 0 2px 10px rgba(0,0,0,.35);
  --shadow-md: 0 6px 20px rgba(0,0,0,.5), 0 18px 44px rgba(0,0,0,.4);
  --shadow-lg: 0 14px 40px rgba(0,0,0,.6), 0 40px 80px rgba(0,0,0,.5);
}

/* ============================================================
   基础
   ============================================================ */
*{ box-sizing: border-box; }
html{ -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* 确保 hidden 属性始终生效（避免被 class 里的 display 覆盖） */
[hidden]{ display: none !important; }

/* ============================================================
   构建时注入的静态内容块（给搜索引擎看的）
   ------------------------------------------------------------
   app.js 启动后会立即 remove() 掉它，正常访客看不到。
   这里先给它压扁成不可见且不占位 —— 万一 JS 加载慢或有异常，
   也不会突然在页面顶部裸出一大段无样式的纯文本。
   注意用 clip 而不是 display:none：部分搜索引擎会忽略
   display:none 的内容，用 clip 既能藏住又能被索引。
   ============================================================ */
#seoContent{
  position: absolute !important;
  width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0; padding: 0; margin: -1px;
}

body{
  margin: 0; font-family: var(--font);
  background: var(--bg); color: var(--text); line-height: 1.6;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  /* 给固定底栏留出空间。用 tabbar 真实高度 + 安全区，
     再留 4px 余量 —— 避免「刚好相等」在部分机型上仍被压住 1~2px。 */
  padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 4px);
  transition: background .4s var(--ease), color .4s var(--ease);
}

/* --- 背景层 1：三层极光光晕 --- */
body::before{
  content:""; position: fixed; inset: -10%; pointer-events: none; z-index: 0;
  opacity: var(--aura-opacity);
  background:
    radial-gradient(52% 42% at 8% -6%, var(--accent-glow), transparent 62%),
    radial-gradient(46% 40% at 96% 2%, var(--surface-strong), transparent 58%),
    radial-gradient(60% 50% at 50% 108%, var(--accent-soft), transparent 62%);
  animation: auraDrift 26s var(--ease) infinite alternate;
  transition: opacity .5s var(--ease);
}
@keyframes auraDrift{
  0%   { transform: translate3d(0,0,0) scale(1); }
  50%  { transform: translate3d(-1.6%, 1.2%, 0) scale(1.05); }
  100% { transform: translate3d(1.4%, -1%, 0) scale(1.02); }
}

/* --- 背景层 2：噪点纹理（抗塑料感的关键） --- */
body::after{
  content:""; position: fixed; inset: 0; pointer-events: none; z-index: 1;
  opacity: var(--noise-opacity); mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  transition: opacity .5s var(--ease);
}

button{ font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
a{ color: inherit; text-decoration: none; }
input{ font-family: inherit; }

::selection{ background: var(--accent); color: #fff; }

/* 自定义滚动条（桌面） */
@media (min-width: 901px){
  ::-webkit-scrollbar{ width: 11px; height: 11px; }
  ::-webkit-scrollbar-track{ background: transparent; }
  ::-webkit-scrollbar-thumb{
    background: var(--border-strong); border-radius: 20px;
    border: 3px solid var(--bg); background-clip: padding-box;
  }
  ::-webkit-scrollbar-thumb:hover{ background: var(--accent); background-clip: padding-box; }
}

/* ============================================================
   滚动进度条
   ============================================================ */
.scroll-progress{
  position: fixed; top: 0; left: 0; height: 2.5px; width: 0; z-index: 300;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  box-shadow: 0 0 12px var(--accent-glow);
  transition: width .1s linear, opacity .3s var(--ease);
  pointer-events: none; border-radius: 0 2px 2px 0;
}

/* ============================================================
   顶栏
   ============================================================ */
.topbar{
  position: sticky; top: 0; z-index: 60;
  background: var(--topbar-bg);
  backdrop-filter: saturate(190%) blur(20px);
  -webkit-backdrop-filter: saturate(190%) blur(20px);
  border-bottom: 1px solid var(--border);
  transition: background .4s var(--ease), border-color .4s var(--ease);
}
/* 滚动后顶栏收紧 + 加阴影 */
.topbar.scrolled{
  box-shadow: 0 1px 0 var(--border), 0 8px 28px rgba(0,0,0,.06);
}
[data-theme="aurora"] .topbar.scrolled,
[data-theme="neon"] .topbar.scrolled{ box-shadow: 0 1px 0 var(--border), 0 8px 32px rgba(0,0,0,.45); }

.topbar-inner{
  max-width: 1160px; margin: 0 auto;
  height: var(--topbar-h); padding: 0 18px;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.brand{ display: flex; align-items: center; gap: 10px; min-width: 0; flex-shrink: 0; }
.brand-mark{
  width: 34px; height: 34px; border-radius: 11px; display: grid; place-items: center;
  background: var(--discount-bg); background-size: 200% 200%;
  color: #fff; font-weight: 800; font-size: 17px;
  box-shadow: 0 4px 16px var(--accent-glow), inset 0 1px 0 rgba(255,255,255,.32);
  flex-shrink: 0; position: relative; overflow: hidden;
  animation: markFlow 9s var(--ease) infinite alternate;
  transition: transform .35s var(--ease-spring);
}
.brand:hover .brand-mark{ transform: rotate(-6deg) scale(1.06); }
@keyframes markFlow{
  0%{ background-position: 0% 50%; } 100%{ background-position: 100% 50%; }
}
/* 光泽扫过 */
.brand-mark::after{
  content:""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 32%, rgba(255,255,255,.62) 50%, transparent 68%);
  transform: translateX(-140%);
  animation: shine 5.5s var(--ease) infinite;
}
@keyframes shine{
  0%, 62%{ transform: translateX(-140%); }
  88%, 100%{ transform: translateX(140%); }
}
.brand-mark.sm{ width: 28px; height: 28px; border-radius: 9px; font-size: 14px; }

.brand-text{ display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.brand-text b{ font-size: 16.5px; font-weight: 780; letter-spacing: -.2px; }
.brand-text small{ font-size: 11px; color: var(--text-faint); letter-spacing: .4px; white-space: nowrap; }

.topnav{ display: flex; gap: 3px; align-items: center; }
.topnav a{
  padding: 7px 14px; border-radius: 10px; font-size: 14px; font-weight: 560;
  color: var(--text-dim); transition: all var(--dur-fast) var(--ease); white-space: nowrap;
  position: relative;
}
.topnav a:hover{ color: var(--text); background: var(--surface); }
.topnav a.is-active{ color: var(--accent); background: var(--accent-soft); font-weight: 660; }
.topnav a.is-active::after{
  content:""; position: absolute; left: 50%; bottom: 1px; transform: translateX(-50%);
  width: 14px; height: 2px; border-radius: 2px; background: var(--accent);
}

.topbar-actions{ display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.btn-contact-sm{
  padding: 8px 16px; border-radius: 10px; font-size: 13.5px; font-weight: 650;
  background: var(--discount-bg); background-size: 180% 180%;
  color: #fff; box-shadow: 0 3px 14px var(--accent-glow);
  transition: all var(--dur) var(--ease); white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px; position: relative; overflow: hidden;
  animation: markFlow 9s var(--ease) infinite alternate;
}
.btn-contact-sm:hover{ transform: translateY(-1.5px); box-shadow: 0 8px 24px var(--accent-glow); }
.btn-contact-sm:active{ transform: translateY(0) scale(.973); }

.icon-btn{
  width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--border); color: var(--text-dim);
  transition: all var(--dur) var(--ease);
}
.icon-btn:hover{ background: var(--surface-strong); color: var(--text); border-color: var(--border-strong); transform: translateY(-1px); }
.icon-btn:active{ transform: scale(.93); }
.icon-btn.is-open{ color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

/* ============================================================
   风格面板
   ============================================================ */
.theme-panel{
  max-height: 0; overflow: hidden;
  transition: max-height .45s var(--ease), padding .4s var(--ease);
  border-top: 1px solid transparent; background: var(--bg-elev);
}
.theme-panel.open{ max-height: 500px; padding: 18px 18px 20px; border-top-color: var(--border); }
.theme-panel-head{
  max-width: 1160px; margin: 0 auto 14px;
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; font-weight: 650; color: var(--text-dim); letter-spacing: .5px;
}
.theme-close{ font-size: 24px; line-height: 1; color: var(--text-faint); padding: 0 4px; transition: color .2s, transform .2s; }
.theme-close:hover{ color: var(--text); transform: rotate(90deg); }
.theme-grid{
  max-width: 1160px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px,1fr)); gap: 12px;
}
.theme-card{
  border: 1.5px solid var(--border); border-radius: var(--radius-m);
  padding: 14px; text-align: left; background: var(--surface);
  transition: all .24s var(--ease); position: relative; overflow: hidden;
}
.theme-card:hover{ transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.theme-card.active{ border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); }
.theme-card.active::after{
  content:"✓"; position: absolute; bottom: 10px; right: 12px;
  font-size: 11px; font-weight: 800; color: var(--accent);
}
.theme-card .swatches{ display: flex; gap: 5px; margin-bottom: 10px; }
.theme-card .sw{
  width: 20px; height: 20px; border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(128,128,128,.20), 0 2px 6px rgba(0,0,0,.10);
}
.theme-card .tname{ font-size: 13.5px; font-weight: 690; display: block; }
.theme-card .tdesc{ font-size: 11px; color: var(--text-faint); display: block; margin-top: 2px; }
.theme-card .tno{
  position: absolute; top: 10px; right: 12px; font-size: 10px; font-weight: 700;
  color: var(--text-faint); border: 1px solid var(--border); border-radius: 20px; padding: 1px 7px;
}
.theme-hint{ max-width: 1160px; margin: 14px auto 0; font-size: 11.5px; color: var(--text-faint); text-align: center; }

/* ============================================================
   主容器
   ============================================================ */
#main{ max-width: 1160px; margin: 0 auto; padding: 0 18px 40px; position: relative; z-index: 5; }

/* ============================================================
   顶部简介条
   ============================================================ */
.intro-bar{
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 34px; align-items: center;
  padding: 40px 0 28px; position: relative;
}
/* ★ hidden 属性必须能真正生效
   ------------------------------------------------------------
   .intro-bar 自己写了 display: grid（以及各主题里的各种 display），
   会盖掉浏览器对 [hidden] 默认的 display: none —— 于是 JS 里设了
   hidden = true，蓝区还是稳稳地占着位置。这里显式补回来。
   放在基础规则之后、主题规则之前不够，所以用 !important 保底：
   这是「隐藏」语义，任何主题都不该覆盖它。 */
.intro-bar[hidden]{ display: none !important; }
.ib-left{ min-width: 0; }
.ib-title{
  font-size: clamp(25px, 3.6vw, 36px); font-weight: 830; line-height: 1.22;
  letter-spacing: -1px; margin: 0 0 12px;
}
.ib-title em{
  font-style: normal; position: relative; display: inline-block;
  background: linear-gradient(105deg, var(--accent), var(--accent-2) 55%, var(--accent-3));
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: titleFlow 8s var(--ease) infinite alternate;
}
@keyframes titleFlow{ 0%{ background-position: 0% center; } 100%{ background-position: 100% center; } }
.ib-desc{ font-size: 15px; color: var(--text-dim); line-height: 1.72; margin: 0; max-width: 560px; }

.ib-stats{ display: flex; gap: 28px; flex-wrap: nowrap; flex-shrink: 0; }
.ib-stat{ display: flex; flex-direction: column; gap: 2px; position: relative; flex-shrink: 0; }
.ib-stat .sv{
  font-family: var(--font-num);
  font-size: 27px; font-weight: 830; letter-spacing: -1px; line-height: 1.05;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
  display: inline-flex; align-items: baseline;
}
.ib-stat .sv u{ font-size: 12px; font-weight: 620; text-decoration: none; margin-left: 2px; -webkit-text-fill-color: var(--text-dim); }
.ib-stat .sl{ font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }

/* ============================================================
   筛选区
   ============================================================ */
.filters{ padding: 4px 0 6px; }
.search-wrap{
  position: relative; display: flex; align-items: center;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-m); height: 50px; padding: 0 14px; gap: 10px;
  box-shadow: var(--shadow-sm); transition: all .24s var(--ease);
  overflow: hidden;
}
/* 搜索框聚焦时的一道光 */
.search-wrap::before{
  content:""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(100deg, transparent 40%, var(--accent-soft) 50%, transparent 60%);
  transition: opacity .3s var(--ease);
}
.search-wrap:focus-within{ border-color: var(--accent); box-shadow: 0 0 0 3.5px var(--accent-glow); }
.search-wrap:focus-within::before{ opacity: 1; animation: searchSweep 1.2s var(--ease); }
@keyframes searchSweep{
  0%{ transform: translateX(-100%); } 100%{ transform: translateX(100%); }
}
.search-icon{ color: var(--text-faint); flex-shrink: 0; }
#searchInput{ flex: 1; border: none; outline: none; background: none; font-size: 15px; color: var(--text); min-width: 0; }
#searchInput::placeholder{ color: var(--text-faint); }
.search-clear{ font-size: 20px; color: var(--text-faint); padding: 0 2px; line-height: 1; transition: color .2s, transform .2s; }
.search-clear:hover{ color: var(--text); transform: scale(1.15); }

.chips{ display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
.chips::-webkit-scrollbar{ display: none; }
.chip{
  flex-shrink: 0; padding: 7px 15px; border-radius: 22px;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-dim); font-size: 13.5px; font-weight: 560;
  white-space: nowrap; transition: all .22s var(--ease);
  display: inline-flex; align-items: center; gap: 6px;
  position: relative; overflow: hidden;
}
.chip:hover{ background: var(--surface-strong); color: var(--text); transform: translateY(-1px); }
.chip:active{ transform: scale(.96); }
.chip.is-active{
  background: var(--accent); border-color: var(--accent);
  color: #fff; font-weight: 650; box-shadow: 0 4px 16px var(--accent-glow);
}
.chip.is-active::before{
  content:""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 36%, rgba(255,255,255,.42) 50%, transparent 64%);
  animation: shine .85s var(--ease);
}
.chip .dot-s{
  width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
  background: var(--text-faint); transition: background .2s;
}
.chip:not(.is-active):hover .dot-s.tone-hot{ box-shadow: 0 0 0 3px rgba(229,72,77,.22); }
.dot-s.tone-ok{ background: #22a06b; }
.dot-s.tone-warn{ background: #e8a33d; }
.dot-s.tone-hot{ background: #e5484d; animation: pulseHot 2s var(--ease) infinite; }
.dot-s.tone-off{ background: #9aa2bd; }
@keyframes pulseHot{
  0%,100%{ box-shadow: 0 0 0 0 rgba(229,72,77,.42); }
  70%{ box-shadow: 0 0 0 6px rgba(229,72,77,0); }
}
.chip.is-active .dot-s{ background: rgba(255,255,255,.9); animation: none; }

/* 状态筛选条 */
.chips-status{ margin-top: 14px; padding-bottom: 2px; }
.chips-status .chip{ font-size: 13px; padding: 7px 14px; }

/* 城市/品类分组面板 */
.filter-panel{
  margin-top: 12px; border: 1px solid var(--border); border-radius: var(--radius-m);
  background: var(--surface); overflow: hidden;
}
.filter-row{ display: flex; align-items: center; gap: 14px; padding: 11px 16px; position: relative; }
.filter-row + .filter-row{ border-top: 1px solid var(--border); }
.fr-label{
  font-size: 12px; color: var(--text-faint); font-weight: 620; letter-spacing: .5px;
  flex-shrink: 0; width: 34px;
}
.filter-row .chips{ flex: 1; min-width: 0; padding-bottom: 0; padding-right: 22px; }
.filter-row .chip{ font-size: 12.5px; padding: 6px 13px; }
/* 移动端横向滚动时右侧渐隐，提示可滑动 */
.filter-row::after{
  content:""; position: absolute; right: 0; top: 0; bottom: 0; width: 26px;
  background: linear-gradient(to right, transparent, var(--surface));
  pointer-events: none;
}

/* ★ 筛选区改成一行：状态 chips 横滑（左）+ 排序下拉（右）
   原来两行 74px，现在压到约 34px，首屏多露出一截。
   注意：类名不能用 .filter-row —— 那个已经被搜索面板占用，会串样式。 */
.fbar{
  display: flex; align-items: center; gap: 10px;
  margin-top: 2px; padding: 0;
}
.fbar .chips-status{
  flex: 1 1 auto; min-width: 0;
  margin-top: 0; padding-bottom: 0;
  align-items: center;
  /* 右侧渐隐，暗示"还能横滑" */
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 22px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 22px), transparent);
}
.fbar .chips-status .chip{
  font-size: 12.5px; padding: 5px 11px; border-radius: 18px;
  gap: 5px;
}
.fbar .chips-status .chip .chip-n{ height: 15px; min-width: 17px; font-size: 10.5px; }

.sort-btn{
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
  height: 32px; padding: 0 12px; border-radius: 16px;
  background: var(--bg-card); border: 1px solid var(--border);
  color: var(--text-dim); font-size: 12.5px; font-weight: 650;
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
  transition: all .2s var(--ease);
}
.sort-btn:hover{ border-color: var(--border-strong); color: var(--text); }
.sort-btn:active{ transform: scale(.96); }
.sort-btn[aria-expanded="true"]{
  border-color: var(--accent); color: var(--accent);
  background: var(--accent-soft);
}

/* 排序面板：贴按钮右下弹出 */
.sort-menu{
  position: absolute; z-index: 40;
  margin-top: 6px;
  min-width: 156px; padding: 5px;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; gap: 1px;
  animation: menuIn .18s var(--ease-out) both;
}
@keyframes menuIn{
  from{ opacity: 0; transform: translateY(-6px) scale(.97); }
  to{ opacity: 1; transform: translateY(0) scale(1); }
}
.sort-opt{
  text-align: left; padding: 9px 11px; border-radius: 9px;
  font-size: 13px; font-weight: 600; color: var(--text-dim);
  transition: background .16s, color .16s;
}
.sort-opt:hover{ background: var(--surface-strong); color: var(--text); }
.sort-opt.is-active{ color: var(--accent); font-weight: 750; background: var(--accent-soft); }
.sort-opt.is-active::after{
  content: '✓'; float: right; font-weight: 900; font-size: 12px;
}

/* 结果计数：只在「筛选/搜索生效」时出现。
   蓝区已经显示了总数，这里不重复占一整行 —— 做成不占流的小胶囊贴在列表上方。 */
.result-count{
  font-size: 11.5px; font-weight: 650; color: var(--text-faint);
  margin: 2px 2px 0; display: block;
}
.result-count:empty{ display: none; }

/* ============================================================
   ★「即将开演」横向时间轴
   ------------------------------------------------------------
   位置：排序栏下方、卡片网格上方。
   作用：把「最近要开的几场」提前拎出来，给客户一个「别错过」的信号，
        也给运营者一个制造回访理由的位置（真实数据，不是编的）。

   为什么做成横向滑动而不是个网格：
     这里讲的是「时间先后」，横排在心理上就是一条时间线；
     而且它只占一行高度（约 84px），不抢卡片列表的首屏空间。

   配色：日期块用深靛蓝 + 珊瑚橙的「紧急态」，和全站暖色出口保持一致。
   ============================================================ */
.soon{
  margin: 11px 0 0;                  /* 14 → 11，和上面筛选栏的 8px 间距配成一组 */
}
.soon-hd{
  display: flex; align-items: baseline; gap: 9px;
  margin: 0 2px 7px;                 /* 9 → 7，标题块和轨道之间少一层空隙 */
}
.soon-tt{
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13.5px; font-weight: 850; color: var(--text);
  letter-spacing: .2px;
}
/* 呼吸的小圆点：不刺眼，但能让人注意到这块是「活的」 */
.soon-dot{
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--warm); flex: 0 0 auto;
  box-shadow: 0 0 0 0 rgba(255,107,74,.5);
  animation: soonPulse 2.4s var(--ease) infinite;
}
@keyframes soonPulse{
  0%, 100%{ box-shadow: 0 0 0 0 rgba(255,107,74,.45); }
  55%{ box-shadow: 0 0 0 6px rgba(255,107,74,0); }
}
.soon-sub{ font-size: 11.5px; font-weight: 650; color: var(--text-faint); }

/* 轨道：横滑，右侧渐隐，暗示「还能往右滑」 */
.soon-rail{
  display: flex; gap: 10px;
  overflow-x: auto; overflow-y: hidden;
  padding: 2px 2px 8px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 26px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 26px), transparent);
}
.soon-rail::-webkit-scrollbar{ display: none; }

.soon-item{
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  width: 268px; padding: 9px 11px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 15px; cursor: pointer; text-align: left;
  scroll-snap-align: start;
  box-shadow: 0 1px 2px rgba(20,24,58,.04), 0 4px 12px rgba(20,24,58,.05);
  transition: transform .24s var(--ease), box-shadow .28s var(--ease), border-color .24s var(--ease);
}
.soon-item:hover{
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: 0 4px 10px rgba(20,24,58,.07), 0 14px 30px rgba(20,24,58,.10);
}
/* 7 天内：左侧一条珊瑚橙，扫一眼就知道哪几个急 */
.soon-item.is-urgent{
  border-color: rgba(255,107,74,.34);
  background: linear-gradient(100deg, rgba(255,107,74,.055), transparent 62%), var(--bg-card);
}

/* 日期块 */
.si-date{
  flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 12px;
  background: linear-gradient(160deg, rgba(27,31,75,.075), rgba(27,31,75,.035));
  border: 1px solid var(--border);
  line-height: 1;
}
.soon-item.is-urgent .si-date{
  background: linear-gradient(160deg, #FF8A6B, #FF6B4A);
  border-color: transparent;
  box-shadow: 0 3px 10px rgba(255,107,74,.30);
}
.si-md{
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 15px; font-weight: 900; letter-spacing: -.4px;
  color: var(--text);
}
.soon-item.is-urgent .si-md{ color: #fff; }
.si-wk{
  margin-top: 2px; font-style: normal;
  font-size: 9.5px; font-weight: 700; color: var(--text-faint);
}
.soon-item.is-urgent .si-wk{ color: rgba(255,255,255,.86); }

/* 中间：相对天数 + 标题 + 城市场馆 */
.si-body{
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.si-day{
  font-size: 10.5px; font-weight: 800; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.si-day.urgent{ color: #E8452A; }
.si-tt{
  font-size: 12.5px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.si-meta{
  display: flex; align-items: center; gap: 5px; min-width: 0;
  font-size: 10.5px; color: var(--text-faint); line-height: 1.3;
}
.si-city{ font-style: normal; font-weight: 750; color: var(--text-dim); flex: 0 0 auto; }
.si-ven{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 右侧：价格 + 状态 */
.si-right{
  flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
}
.si-price{
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 12.5px; font-weight: 850; color: #E8452A; white-space: nowrap;
}
.si-st{
  font-size: 9.5px; font-weight: 750; white-space: nowrap;
  padding: 2px 6px; border-radius: 7px;
  background: var(--surface); color: var(--text-dim);
}

/* 窄屏：卡片窄一点，一次能露出 1.3 张（暗示可滑动） */
@media (max-width: 560px){
  .soon-item{ width: 236px; padding: 7px 10px; gap: 9px; }
  .si-date{ width: 40px; height: 40px; border-radius: 10px; }
  .si-md{ font-size: 14px; }
  .si-price{ font-size: 12px; }
}

/* ============================================================
   卡片网格
   ============================================================ */
.card-grid{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(278px, 1fr));
  gap: var(--grid-gap); padding-top: 24px;
}
.event-card{
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--card-radius); overflow: hidden; cursor: pointer;
  display: flex; flex-direction: column; position: relative;
  transform-style: preserve-3d;
  transition: transform .4s var(--ease-out), box-shadow .4s var(--ease-out),
              border-color .3s var(--ease), background .3s var(--ease);
  will-change: transform;
}
/* 鼠标跟随光晕 */
.card-glow{
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
  border-radius: inherit; opacity: 0; transition: opacity .35s var(--ease);
  background: radial-gradient(
    var(--glow-r) circle at var(--mx, 50%) var(--my, 50%),
    var(--accent-glow), transparent 62%
  );
  mix-blend-mode: screen;
}
[data-theme="paper"] .card-glow,
[data-theme="mint"] .card-glow{ mix-blend-mode: normal; opacity: 0; }
.event-card:hover .card-glow{ opacity: .85; }
@media (hover: none){ .card-glow{ display: none; } }

.event-card::after{
  content:""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  z-index: 4; opacity: 0; transition: opacity .3s var(--ease);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}
.event-card:hover::after{ opacity: .55; }

.event-card:hover{
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
  border-color: transparent;
  background: var(--bg-card-hover);
}
.event-card:active{ transform: translateY(-2px) scale(.988); }
.event-card:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- 封面（程序化渐变，每个项目一个色相） ---- */
.card-poster{
  position: relative; aspect-ratio: 16/9; overflow: hidden;
  background:
    radial-gradient(118% 128% at 76% 14%, hsl(var(--h,260) var(--poster-sat) 56% / .92), transparent 60%),
    radial-gradient(116% 118% at 14% 94%, hsl(calc(var(--h,260) + 42) var(--poster-sat-2) 46% / .86), transparent 64%),
    linear-gradient(148deg,
      hsl(var(--h,260) calc(var(--poster-sat) + 4%) var(--poster-lum)) 0%,
      hsl(calc(var(--h,260) + 20) var(--poster-sat-2) calc(var(--poster-lum) - 7%)) 54%,
      hsl(calc(var(--h,260) + 44) calc(var(--poster-sat-2) - 6%) calc(var(--poster-lum) - 15%)) 100%);
  display: grid; place-items: center;
  isolation: isolate;
}
/* 网格线纹理（科技/秩序感） */
.card-poster::before{
  content:""; position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: .30;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.30) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.30) 1px, transparent 1px);
  background-size: 34px 34px;
  -webkit-mask-image: radial-gradient(90% 80% at 60% 40%, #000 20%, transparent 78%);
  mask-image: radial-gradient(90% 80% at 60% 40%, #000 20%, transparent 78%);
}
/* 底部压暗，保证文字可读 */
.card-poster::after{
  content:""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, rgba(0,0,0,.55) 0%, rgba(0,0,0,.14) 38%, transparent 62%);
}
/* 缓慢流动的光斑 */
.poster-aura{
  position: absolute; z-index: 0;
  width: 70%; height: 130%; top: -30%; left: -12%;
  background: radial-gradient(closest-side, rgba(255,255,255,.34), transparent 72%);
  filter: blur(16px);
  animation: posterAura 13s var(--ease) infinite alternate;
  pointer-events: none;
}
@keyframes posterAura{
  0%{ transform: translate3d(0,0,0) rotate(0deg) scale(1); opacity: .70; }
  50%{ transform: translate3d(28%, 12%, 0) rotate(12deg) scale(1.15); opacity: .95; }
  100%{ transform: translate3d(56%, -6%, 0) rotate(-8deg) scale(1.05); opacity: .68; }
}

/* 专属色相罩：把封面压成"信息底纹"而不是"广告色块" */
.poster-veil{
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: rgba(0,0,0,var(--poster-veil));
  mix-blend-mode: multiply;
}

.card-poster .poster-icon{
  position: absolute; right: 12%; top: 50%; z-index: 2;
  width: 58px; height: 58px; margin-top: -29px;
  opacity: .30; color: #fff;
  filter: drop-shadow(0 8px 20px rgba(0,0,0,.35));
  transition: transform .55s var(--ease-spring), opacity .4s var(--ease);
}
.card-poster .poster-icon svg{ width: 100%; height: 100%; display: block; }
.event-card:hover .poster-icon{ transform: scale(1.16) rotate(-6deg); opacity: .42; }

/* 封面信息层：V2 已改为「演出名 + 日期·场馆 + 倒计时」底部整块（见文件末尾最终版） */
.poster-artist{
  font-size: 19px; font-weight: 800; line-height: 1.25; color: #fff;
  letter-spacing: -.4px; margin: 0;
  text-shadow: 0 3px 16px rgba(0,0,0,.55);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 68%;
}
.poster-kind{
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 650; letter-spacing: .35px;
  color: rgba(255,255,255,.80); margin-top: 5px;
  max-width: 68%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.poster-kind::before{
  content:""; width: 14px; height: 1.5px; border-radius: 2px;
  background: rgba(255,255,255,.62);
}

/* 状态徽章 */
.poster-badges{ position: absolute; top: 10px; left: 10px; display: flex; gap: 6px; z-index: 3; flex-wrap: wrap; max-width: 82%; }
.badge{
  font-size: 10.5px; font-weight: 700; padding: 4px 9px; border-radius: 20px;
  background: rgba(0,0,0,.52); color: #fff;
  backdrop-filter: blur(10px) saturate(150%);
  -webkit-backdrop-filter: blur(10px) saturate(150%);
  border: 1px solid rgba(255,255,255,.20); letter-spacing: .3px; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 5px;
  box-shadow: 0 2px 10px rgba(0,0,0,.22);
}
.badge .bdot{ width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.badge.tone-ok{ background: #17a06a; border-color: transparent; }
.badge.tone-warn{ background: #e8a33d; border-color: transparent; color: #3a2703; }
.badge.tone-hot{
  background: #e5484d; border-color: transparent;
  box-shadow: 0 2px 10px rgba(229,72,77,.42);
}
.badge.tone-hot .bdot{ animation: pulseDot 1.8s var(--ease) infinite; }
@keyframes pulseDot{ 0%,100%{ opacity: 1; } 50%{ opacity: .35; } }
.badge.tone-off{ background: rgba(88,93,112,.93); border-color: transparent; }

.poster-meta{
  position: absolute; bottom: 11px; left: 14px; right: 14px; z-index: 3;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  color: rgba(255,255,255,.92); font-size: 11.5px; font-weight: 620;
  text-shadow: 0 2px 10px rgba(0,0,0,.65);
}
.poster-meta .pm-date{
  display: flex; align-items: center; gap: 5px;
  white-space: nowrap; flex-shrink: 0;
}
.poster-meta .pm-date svg{ flex-shrink: 0; }
.poster-meta .pm-sep{ margin: 0 2px; opacity: .55; font-style: normal; }
.poster-meta .pm-city{
  background: rgba(0,0,0,.48); padding: 3px 9px; border-radius: 20px;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,.18); font-size: 11px; text-shadow: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 52%; flex-shrink: 1; min-width: 0;
}

.card-body{ padding: 15px 16px 16px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.card-title{
  font-size: 15.5px; font-weight: 700; line-height: 1.4; letter-spacing: .1px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin: 0;
  transition: color .25s var(--ease);
}
.event-card:hover .card-title{ color: var(--accent); }
.card-sub{ font-size: 12px; color: var(--text-faint); margin: -3px 0 0; }
.card-venue{
  font-size: 12.5px; color: var(--text-dim); display: flex; align-items: center; gap: 5px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; margin: 0;
}
.card-venue svg{ flex-shrink: 0; opacity: .7; }
.card-status-note{
  font-size: 12px; color: var(--text-dim); display: inline-flex; align-items: center; gap: 5px;
  margin: 0;
}
.card-status-note .nsdot{ width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.nsdot.tone-ok{ background: #22a06b; }
.nsdot.tone-warn{ background: #e8a33d; }
.nsdot.tone-hot{ background: #e5484d; }
.nsdot.tone-off{ background: #9aa2bd; }

.card-foot{
  margin-top: auto; padding-top: 11px; border-top: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  min-height: 34px;
}
.price-block{ display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.price-label{ font-size: 10.5px; color: var(--text-faint); letter-spacing: .4px; }
.price-range{
  font-family: var(--font-num);
  font-size: 13.5px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums;
}
.price-range .cur{ font-size: 11.5px; margin-right: 1px; color: var(--text-dim); }
.card-sessions{ font-size: 11.5px; color: var(--text-faint); }
.card-ask{
  font-size: 12.5px; font-weight: 660; color: var(--accent);
  display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
  transition: gap .25s var(--ease);
}
.event-card:hover .card-ask{ gap: 8px; }

/* ============================================================
   滚动进场：错落浮现
   ============================================================ */
.reveal{
  opacity: 0; transform: translateY(22px);
  transition: opacity .62s var(--ease-out), transform .62s var(--ease-out);
  transition-delay: var(--rd, 0ms);
}
.reveal.in{ opacity: 1; transform: none; }
/* 首屏卡片用入场动画（不用 reveal，避免与 IntersectionObserver 打架） */
.event-card.anim{ animation: cardIn .58s var(--ease-out) both; }
@keyframes cardIn{
  from{ opacity: 0; transform: translateY(20px) scale(.975); }
  to{ opacity: 1; transform: none; }
}

/* ============================================================
   空状态
   ============================================================ */
.empty{ text-align: center; padding: 70px 20px; }
.empty-title{ font-size: 17px; font-weight: 690; margin: 0 0 6px; }
.empty-sub{ font-size: 13.5px; color: var(--text-faint); margin: 0 0 22px; }
.empty-actions{ display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* ============================================================
   通用按钮
   ============================================================ */
.btn{
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 11px 20px; border-radius: 11px; font-size: 14px; font-weight: 650;
  transition: all var(--dur) var(--ease); white-space: nowrap;
}
.btn-primary{
  background: var(--discount-bg); background-size: 180% 180%; color: #fff;
  box-shadow: 0 4px 16px var(--accent-glow);
  animation: markFlow 9s var(--ease) infinite alternate;
}
.btn-primary:hover{ transform: translateY(-2px); box-shadow: 0 9px 26px var(--accent-glow); }
.btn-primary:active{ transform: translateY(0) scale(.975); }
.btn-ghost{ background: var(--surface); border: 1px solid var(--border-strong); color: var(--text-dim); }
.btn-ghost:hover{ background: var(--surface-strong); color: var(--text); transform: translateY(-2px); }

/* ============================================================
   CTA 联系区
   ============================================================ */
.cta-section{
  margin: 56px 0 10px; border-radius: var(--radius-xl); overflow: hidden;
  background: var(--bg-card); border: 1px solid var(--border-strong);
  position: relative; padding: 46px 40px; box-shadow: var(--shadow-md);
}
.cta-section::before{ content:""; position: absolute; inset: 0; background: var(--hero-grad); pointer-events: none; }
.cta-section::after{
  content:""; position: absolute; inset: -50% -10%; pointer-events: none;
  background: radial-gradient(closest-side, var(--accent-glow), transparent 70%);
  opacity: .5; animation: auraDrift 20s var(--ease) infinite alternate;
}
.cta-inner{ position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 30px; flex-wrap: wrap; }
.cta-left{ max-width: 520px; }
.cta-left h2{ font-size: clamp(20px,3vw,27px); font-weight: 810; margin: 0 0 11px; letter-spacing: -.7px; }
.cta-left p{ font-size: 14.8px; color: var(--text-dim); margin: 0; line-height: 1.72; }
.cta-actions{ display: flex; flex-direction: column; gap: 11px; min-width: 220px; }
.contact-item{
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius-m); padding: 13px 17px; transition: all .26s var(--ease);
  position: relative; overflow: hidden;
}
.contact-item:hover{ border-color: var(--accent); transform: translateX(4px); box-shadow: var(--shadow-sm); }
.contact-item .ci-ic{ color: var(--accent); flex-shrink: 0; display: grid; place-items: center; }
.contact-item .ci-tx{ display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.contact-item .ci-lb{ font-size: 10.5px; color: var(--text-faint); letter-spacing: .4px; }
.contact-item .ci-vl{ font-size: 14px; font-weight: 650; word-break: break-all; }

/* ============================================================
   弹窗
   ============================================================ */
.modal-mask{
  position: fixed; inset: 0; z-index: 200;
  background: rgba(6,7,12,.66); backdrop-filter: blur(9px) saturate(120%);
  -webkit-backdrop-filter: blur(9px) saturate(120%);
  display: grid; place-items: center; padding: 20px;
  animation: fadeIn .26s var(--ease) both;
}
.modal-mask[hidden]{ display: none; }
@keyframes fadeIn{ from{ opacity:0 } to{ opacity:1 } }

.modal{
  background: var(--bg-elev); border: 1px solid var(--border-strong);
  border-radius: var(--radius-l); padding: 28px 26px 24px;
  width: 100%; max-width: 430px; position: relative;
  box-shadow: var(--shadow-lg);
  animation: modalIn .38s var(--ease-spring) both;
  max-height: calc(100vh - 40px); overflow-y: auto;
}
@keyframes modalIn{
  from{ opacity:0; transform: translateY(24px) scale(.955); }
  to{ opacity:1; transform:none; }
}
.modal::before{
  content:""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  border-radius: var(--radius-l) var(--radius-l) 0 0;
  background: linear-gradient(90deg, var(--accent), var(--accent-2), var(--accent-3));
  background-size: 200% auto; animation: markFlow 6s var(--ease) infinite alternate;
}
.modal-close{
  position: absolute; top: 14px; right: 16px; font-size: 25px; line-height: 1;
  color: var(--text-faint); transition: color .2s, transform .25s; padding: 2px 5px;
}
.modal-close:hover{ color: var(--text); transform: rotate(90deg); }
.modal-head{ display: flex; gap: 14px; align-items: flex-start; margin-bottom: 20px; padding-right: 26px; }
.modal-ic{
  width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent);
  border: 1px solid var(--border-strong); flex-shrink: 0;
  box-shadow: 0 4px 14px var(--accent-glow);
}
.modal-head h3{ font-size: 17.5px; font-weight: 740; margin: 2px 0 6px; }
.modal-head p{ font-size: 13.5px; color: var(--text-dim); margin: 0; line-height: 1.62; }
.modal-body{ display: flex; flex-direction: column; gap: 10px; }
.modal-note{ font-size: 12px; color: var(--text-faint); text-align: center; margin: 16px 0 0; }

/* 项目名带入提示 */
.modal-context{
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: var(--radius-s);
  padding: 12px 14px; margin-bottom: 16px;
}
.modal-context .mc-lb{ font-size: 10.5px; color: var(--text-faint); letter-spacing: .5px; margin-bottom: 4px; }
.modal-context .mc-vl{ font-size: 14px; font-weight: 650; line-height: 1.45; }

/* ============================================================
   详情页
   ============================================================ */
/* ★ fill-mode 用 backwards 而不是 both。
   both 会在动画结束后永久保留 to 帧的 transform: none —— 看起来一样，
   但「有 transform 属性」本身就会让这个元素成为 position:fixed 的包含块，
   于是里面所有 fixed 元素都改成相对它定位，吸底栏/浮层全部错位。
   backwards 只在动画开始前应用起始帧，结束后彻底摘掉 transform。 */
.detail{ padding-top: 20px; animation: detailIn .5s var(--ease-out) backwards; }
@keyframes detailIn{
  from{ opacity:0; transform: translateY(16px); }
  to{ opacity:1; transform:none; }
}
.detail-hero{
  border-radius: var(--radius-xl); overflow: hidden; position: relative;
  border: 1px solid var(--border);
  padding: 36px 30px 32px; min-height: 240px;
  display: flex; flex-direction: column; justify-content: flex-end;
  background:
    radial-gradient(118% 128% at 78% 10%, hsl(var(--h,260) var(--poster-sat) 54% / .90), transparent 60%),
    radial-gradient(112% 118% at 10% 96%, hsl(calc(var(--h,260) + 42) var(--poster-sat-2) 44% / .82), transparent 64%),
    linear-gradient(148deg,
      hsl(var(--h,260) calc(var(--poster-sat) + 6%) calc(var(--poster-lum) - 2%)) 0%,
      hsl(calc(var(--h,260) + 22) var(--poster-sat-2) calc(var(--poster-lum) - 9%)) 55%,
      hsl(calc(var(--h,260) + 46) calc(var(--poster-sat-2) - 8%) calc(var(--poster-lum) - 17%)) 100%);
  isolation: isolate;
}
/* 网格纹理 + 噪点 */
.detail-hero::before{
  content:""; position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: .26;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.28) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.28) 1px, transparent 1px);
  background-size: 40px 40px;
  -webkit-mask-image: radial-gradient(100% 90% at 65% 35%, #000 15%, transparent 80%);
  mask-image: radial-gradient(100% 90% at 65% 35%, #000 15%, transparent 80%);
}
.detail-hero::after{
  content:""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, rgba(0,0,0,.52) 0%, rgba(0,0,0,.12) 42%, transparent 66%);
}
.detail-hero .hero-aura{
  position: absolute; z-index: 0; top: -40%; left: -8%;
  width: 60%; height: 160%;
  background: radial-gradient(closest-side, rgba(255,255,255,.40), transparent 72%);
  filter: blur(18px);
  animation: posterAura 15s var(--ease) infinite alternate;
  pointer-events: none;
}
.detail-hero .hero-icon{
  position: absolute; top: 26px; right: 32px; width: 116px; height: 116px;
  color: #fff; opacity: .22; pointer-events: none; z-index: 2;
}
.detail-hero .hero-icon svg{ width: 100%; height: 100%; display: block; }
.detail-badges{ display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 15px; position: relative; z-index: 3; }
.detail-title{
  font-size: clamp(22px, 3.3vw, 32px); font-weight: 810; line-height: 1.25;
  margin: 0; letter-spacing: -.7px; position: relative; z-index: 3;
  color: #fff; text-shadow: 0 3px 18px rgba(0,0,0,.45);
}
.detail-subtitle{ font-size: 14px; margin: 9px 0 0; position: relative; z-index: 3; color: rgba(255,255,255,.82); }

.btn-back{
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13.5px; color: var(--text-dim); font-weight: 570;
  padding: 8px 0; margin-bottom: 6px; transition: color .2s, gap .25s var(--ease);
}
.btn-back:hover{ color: var(--accent); gap: 11px; }

.detail-grid{ display: grid; grid-template-columns: 1.5fr 1fr; gap: 20px; margin-top: 20px; align-items: start; }
.detail-panel{
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-l); padding: 22px;
  transition: border-color .25s var(--ease);
}
.detail-panel:hover{ border-color: var(--border-strong); }
.detail-panel h3{
  font-size: 12.5px; font-weight: 710; color: var(--text-faint);
  letter-spacing: 1.2px; margin: 0 0 16px;
}
.info-list{ display: flex; flex-direction: column; margin: 0; }
.info-row{ display: flex; gap: 16px; padding: 13px 0; border-bottom: 1px solid var(--border); font-size: 14px; }
.info-row:last-child{ border-bottom: none; }
.info-row dt{ width: 84px; flex-shrink: 0; color: var(--text-faint); font-size: 13.5px; }
.info-row dd{ margin: 0; font-weight: 570; flex: 1; }

.side-panel{
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-l); padding: 22px; position: sticky; top: calc(var(--topbar-h) + 16px);
  box-shadow: var(--shadow-sm);
}
.side-panel .sp-label{ font-size: 12px; color: var(--text-faint); letter-spacing: .4px; }
.side-panel .sp-range{
  font-family: var(--font-num);
  font-size: 27px; font-weight: 820; letter-spacing: -.9px; margin: 8px 0 4px;
  font-variant-numeric: tabular-nums;
}
.side-panel .sp-sub{ font-size: 12.5px; color: var(--text-dim); margin-bottom: 18px; }
.sp-note{
  font-size: 12px; color: var(--text-faint); line-height: 1.68;
  background: var(--surface); border-radius: var(--radius-s);
  padding: 12px 14px; border: 1px solid var(--border); margin-bottom: 16px;
}
.sp-tags{ display: flex; gap: 6px; flex-wrap: wrap; }
.sp-tag{
  font-size: 11.5px; padding: 5px 11px; border-radius: 7px;
  background: var(--surface-strong); color: var(--text-dim); border: 1px solid var(--border);
  transition: all .2s var(--ease);
}
.sp-tag:hover{ border-color: var(--accent); color: var(--accent); }
.sp-disclaimer{
  font-size: 11px; color: var(--text-faint); text-align: center;
  margin: 16px 0 0; line-height: 1.55; padding-top: 15px; border-top: 1px solid var(--border);
}
.detail-desc{ font-size: 14.2px; line-height: 1.78; color: var(--text-dim); }
.detail-desc p{ margin: 0 0 12px; }
.detail-desc p:last-child{ margin-bottom: 0; }

/* ============================================================
   页面型视图（状态 / 日历 / 说明）
   ============================================================ */
.page-simple{ padding-top: 42px; }
.page-simple h1{ font-size: clamp(26px,3.7vw,36px); font-weight: 820; margin: 0 0 10px; letter-spacing: -.9px; }
.page-simple > p.lead{ color: var(--text-dim); font-size: 15.5px; margin: 0 0 34px; max-width: 620px; line-height: 1.7; }

/* 分组列表（状态页 / 日历页共用） */
.cal-group{ margin-bottom: 30px; }
.cal-date{
  font-size: 15px; font-weight: 720; margin-bottom: 12px;
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 9px; border-bottom: 1px solid var(--border);
}
.cal-date .wd{
  font-size: 11.5px; font-weight: 560; color: var(--text-faint);
  background: var(--surface); border: 1px solid var(--border);
  padding: 2px 8px; border-radius: 20px;
}
.cal-item{
  display: flex; align-items: center; gap: 14px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-m); padding: 14px 17px; margin-bottom: 9px;
  cursor: pointer; transition: all .26s var(--ease); position: relative; overflow: hidden;
}
.cal-item::before{
  content:""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--accent); transform: scaleY(0); transform-origin: center;
  transition: transform .3s var(--ease);
}
.cal-item:hover{
  transform: translateX(5px); border-color: var(--border-strong);
  box-shadow: var(--shadow-md); background: var(--bg-card-hover);
}
.cal-item:hover::before{ transform: scaleY(1); }
.cal-item .ci-icon{
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 12px;
  display: grid; place-items: center; color: var(--accent);
  background: linear-gradient(140deg, var(--accent-soft), transparent);
  border: 1px solid var(--border);
}
.cal-item .ci-icon svg{ width: 24px; height: 24px; display: block; }
.cal-item .ci-main{ flex: 1; min-width: 0; }
.cal-item .ci-title{
  font-size: 14.5px; font-weight: 660; margin-bottom: 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: color .22s var(--ease);
}
.cal-item:hover .ci-title{ color: var(--accent); }
.cal-item .ci-meta{ font-size: 12.5px; color: var(--text-dim); display: flex; align-items: center; flex-wrap: wrap; gap: 0; }
.cal-item .ci-price{
  flex-shrink: 0; font-family: var(--font-num);
  font-size: 13.5px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
  background: var(--surface); border: 1px solid var(--border);
  padding: 5px 11px; border-radius: 20px;
  transition: all .25s var(--ease);
}
.cal-item:hover .ci-price{ background: var(--accent); color: #fff; border-color: var(--accent); }

.about-card{
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-l); padding: 28px 26px; margin-bottom: 16px;
  transition: all .28s var(--ease); position: relative; overflow: hidden;
}
.about-card::before{
  content:""; position: absolute; inset: 0; opacity: 0;
  background: var(--card-grad); transition: opacity .35s var(--ease);
  pointer-events: none;
}
.about-card:hover{ border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.about-card:hover::before{ opacity: 1; }
.about-card > *{ position: relative; z-index: 1; }
.about-card h3{ font-size: 17px; font-weight: 720; margin: 0 0 13px; display: flex; align-items: center; gap: 10px; }
.about-card h3::before{
  content:""; width: 3px; height: 17px; border-radius: 2px;
  background: linear-gradient(180deg,var(--accent),var(--accent-2)); flex-shrink: 0;
}
.about-card p{ font-size: 14.2px; color: var(--text-dim); line-height: 1.78; margin: 0 0 11px; }
.about-card p:last-child{ margin-bottom: 0; }
.about-card strong{ color: var(--text); font-weight: 660; }

.feature-list{ list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 11px; }
.feature-list li{ display: flex; gap: 11px; align-items: flex-start; font-size: 14px; color: var(--text-dim); line-height: 1.65; }
.feature-list li svg{ color: var(--accent); flex-shrink: 0; margin-top: 3px; }

.notice-box{
  background: var(--surface); border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent); border-radius: var(--radius-s);
  padding: 15px 17px; margin: 16px 0; font-size: 13.2px; color: var(--text-dim); line-height: 1.72;
}

/* 数据服务页表格感列表 */
.spec-grid{ display: grid; grid-template-columns: repeat(auto-fit, minmax(210px,1fr)); gap: 14px; margin-top: 8px; }
.spec-item{
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-m); padding: 18px 18px;
}
.spec-item .sk{ font-size: 11.5px; color: var(--text-faint); letter-spacing: .5px; margin-bottom: 6px; }
.spec-item .sv{ font-size: 15px; font-weight: 670; }

/* 联系方式大卡 */
.contact-cards{ display: grid; grid-template-columns: repeat(auto-fit, minmax(250px,1fr)); gap: 16px; margin-top: 8px; }
.contact-big{
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-l); padding: 26px 24px;
  display: flex; gap: 16px; align-items: flex-start;
  transition: all .28s var(--ease);
}
.contact-big:hover{ transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--accent); }
.contact-big .cb-ic{
  width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); border: 1px solid var(--border-strong); flex-shrink: 0;
}
.contact-big .cb-b{ min-width: 0; }
.contact-big .cb-lb{ font-size: 11.5px; color: var(--text-faint); letter-spacing: .5px; margin-bottom: 4px; }
.contact-big .cb-vl{ font-size: 16.5px; font-weight: 710; word-break: break-all; }

/* ============================================================
   页脚
   ============================================================ */
.footer{
  border-top: 1px solid var(--border); background: var(--bg-elev);
  margin-top: 56px; position: relative; z-index: 5;
  /* ★ 页脚与固定底栏之间的呼吸间距。
     body 的 padding-bottom 只负责「不让内容被底栏压住」，
     但页脚紧贴 padding 起点，视觉上仍会糊在一起 —— 这里再补一段留白。 */
  padding-bottom: 22px;
}
.footer::before{
  content:""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity: .55;
}
.footer-inner{
  max-width: 1160px; margin: 0 auto; padding: 32px 18px;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 22px; flex-wrap: wrap;
}
.footer-brand{ display: flex; gap: 11px; align-items: flex-start; max-width: 480px; }
.footer-brand b{ font-size: 15px; font-weight: 730; }
.footer-brand p{ font-size: 12px; color: var(--text-faint); margin: 5px 0 0; line-height: 1.6; }
.footer-contact{ display: flex; flex-direction: column; gap: 5px; font-size: 12.5px; color: var(--text-dim); }
.footer-contact span{ display: flex; align-items: center; gap: 7px; }
.footer-contact svg{ color: var(--accent); flex-shrink: 0; }
.footer-links{ font-size: 12px; color: var(--text-faint); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ============================================================
   底部 Tab 栏
   ============================================================ */
.tabbar{
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 70;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--topbar-bg);
  backdrop-filter: saturate(190%) blur(22px);
  -webkit-backdrop-filter: saturate(190%) blur(22px);
  border-top: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-around;
}
.tab{
  flex: 1; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  color: var(--text-faint); font-size: 10.5px; font-weight: 560;
  transition: color .22s var(--ease); position: relative;
}
.tab svg{ transition: transform .3s var(--ease-spring); }
.tab.is-active{ color: var(--accent); font-weight: 690; }
.tab.is-active svg{ transform: translateY(-2px) scale(1.1); }
.tab.is-active::before{
  content:""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 28px; height: 2.5px; border-radius: 0 0 4px 4px; background: var(--accent);
  box-shadow: 0 2px 10px var(--accent-glow);
}
.tab:active svg{ transform: scale(.9); }

/* ============================================================
   响应式
   ============================================================ */
@media (max-width: 900px){
  .intro-bar{ grid-template-columns: 1fr; gap: 22px; padding: 30px 0 20px; }
  .ib-desc{ max-width: none; }
  .ib-stats{ gap: 22px; }
  .detail-grid{ grid-template-columns: 1fr; }
  .side-panel{ position: static; }
  .topnav{ display: none; }
  .cta-section{ padding: 34px 28px; }
  .cta-inner{ flex-direction: column; align-items: stretch; }
  .cta-actions{ min-width: 0; }
}
@media (max-width: 640px){
  :root{ --grid-gap: 12px; --topbar-h: 56px; --aura-opacity: .7; }
  .topbar-inner{ padding: 0 14px; gap: 8px; }
  .brand-text small{ display: none; }
  .btn-contact-sm{ padding: 7px 12px; font-size: 12.5px; }
  .btn-contact-sm svg{ display: none; }
  .icon-btn{ width: 36px; height: 36px; }
  #main{ padding: 0 14px 30px; }

  /* 简介条 */
  .intro-bar{ padding: 24px 0 18px; gap: 18px; }
  .ib-title{ font-size: 23px; letter-spacing: -.5px; margin-bottom: 8px; }
  .ib-desc{ font-size: 13.5px; }
  .ib-stats{ display: grid; grid-template-columns: 1fr 1fr; gap: 14px 12px; }
  .ib-stat .sv{ font-size: 22px; }
  .ib-stat .sl{ font-size: 11px; }

  /* 筛选 */
  .search-wrap{ height: 45px; }
  #searchInput{ font-size: 14.5px; }
  .chips-status .chip{ font-size: 12.5px; padding: 6px 12px; }
  .filter-panel{ margin-top: 10px; }
  .filter-row{ padding: 9px 12px; gap: 10px; }
  .filter-row .chip{ font-size: 12px; padding: 5px 11px; }
  .fr-label{ width: 30px; font-size: 11.5px; }
  .sort-tab{ padding: 5px 11px; font-size: 12px; }
  .result-count{ font-size: 12px; }

  /* 卡片：两列（按效果图） */
  .card-grid{ grid-template-columns: 1fr 1fr; gap: 10px; padding-top: 12px; }
  .card-poster{ aspect-ratio: 4/5; }
  .card-poster .poster-icon{ width: 34px; height: 34px; margin-top: -17px; right: 10%; }
  .poster-artist{ font-size: 14px; max-width: 92%; }
  .poster-kind{ font-size: 9px; margin-top: 3px; }
  .poster-kind::before{ width: 10px; }
  .card-title{ font-size: 13px; line-height: 1.36; }
  .card-body{ padding: 10px 11px 12px; gap: 5px; }
  .card-sub{ font-size: 11px; }
  .card-venue{ font-size: 11px; }
  .card-status-note{ font-size: 11px; }
  .price-range{ font-size: 12.5px; }
  .price-label{ font-size: 9.5px; }
  .card-sessions{ font-size: 10.5px; }
  .card-ask{ display: none; }
  .poster-badges{ top: 8px; left: 8px; gap: 5px; }
  .badge{ font-size: 9.5px; padding: 3px 8px; }
  .poster-meta{ bottom: 8px; left: 10px; right: 10px; font-size: 10px; gap: 5px; }
  .poster-meta .pm-sep{ margin: 0 .5px; opacity: .55; }
  .poster-meta .pm-date svg{ width: 11px; height: 11px; margin-right: -1px; }
  .poster-meta .pm-city{ font-size: 9.5px; padding: 2px 6px; max-width: 56%; }

  /* CTA */
  .cta-section{ padding: 28px 20px; border-radius: var(--radius-l); margin-top: 40px; }
  .cta-left h2{ font-size: 21px; }
  .cta-left p{ font-size: 13.5px; }

  /* 弹窗 */
  .modal{ padding: 24px 20px 20px; }
  .modal-head h3{ font-size: 16px; }
  .modal-head p{ font-size: 13px; }
  .modal-ic{ width: 40px; height: 40px; }

  /* 详情 */
  .detail-hero{ padding: 24px 18px 20px; border-radius: var(--radius-l); min-height: 180px; }
  .detail-hero .hero-icon{ width: 72px; height: 72px; top: 14px; right: 16px; }
  .detail-panel, .side-panel{ padding: 17px; border-radius: var(--radius-m); }
  .info-row dt{ width: 66px; font-size: 12.5px; }
  .info-row{ font-size: 13px; }
  .side-panel .sp-range{ font-size: 23px; }

  /* 分组列表 */
  .page-simple{ padding-top: 26px; }
  .cal-item{ padding: 12px 13px; gap: 11px; }
  .cal-item .ci-icon{ width: 34px; height: 34px; border-radius: 10px; }
  .cal-item .ci-icon svg{ width: 20px; height: 20px; }
  .cal-item .ci-title{ font-size: 13.5px; }
  .cal-item .ci-meta{ font-size: 11.5px; }
  .cal-item .ci-price{ font-size: 12px; padding: 4px 9px; }

  .about-card{ padding: 21px 18px; }
}
@media (max-width: 380px){
  .card-grid{ grid-template-columns: 1fr 1fr; gap: 8px; }
  .ib-stats{ grid-template-columns: 1fr 1fr; }
}

@media (min-width: 901px){
  body{ padding-bottom: 0; }
  .tabbar{ display: none; }
}

/* ============================================================
   动效降级
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal{ opacity: 1 !important; transform: none !important; }
  body::before{ animation: none; }
  .card-glow{ display: none; }
}

/* ============================================================
   ★ V2 改版 · 亮蓝主题（2026-10）
   ------------------------------------------------------------
   设计要点：
     · 顶部用「深蓝底 + 浅蓝 logo」的深浅反转，视觉上顶栏更沉、logo 浮起
     · 立体感三件套：渐变底 + 外投影 + inset 内高光
     · 问候语自动轮播（4s 上滚），客户不可手动操作
     · 零缓存：不写任何本地存储
   ============================================================ */
[data-theme="blue"]{
  --poster-sat: 52%; --poster-sat-2: 40%; --poster-lum: 42%; --poster-veil: .30;

  --bg: #F6F7FB; --bg-elev: #FFFFFF; --bg-card: #FFFFFF; --bg-card-hover: #FEFFFF;
  --surface: rgba(22,28,58,.034); --surface-strong: rgba(22,28,58,.066);
  --border: #E6E8F2; --border-strong: #CBD0E4;
  --text: #131735; --text-dim: #4B5170; --text-faint: #9298B4;

  /* ★ 深靛蓝主色：比原来的 #2E3570 更沉、更"内容站"，少一分后台管理系统味 */
  --accent: #1B1F4B; --accent-2: #2E3570; --accent-3: #5A63A8;
  --accent-glow: rgba(27,31,75,.20);
  --accent-soft: rgba(27,31,75,.06);

  /* ★ 珊瑚橙：唯一的暖色出口，承担价格、优惠、行动按钮 */
  --warm: #FF6B4A; --warm-2: #FF8A6B; --warm-soft: rgba(255,107,74,.10);

  --discount-bg: linear-gradient(135deg,#FF6B4A,#FF8A6B 60%,#FFA07E);
  --card-grad: linear-gradient(158deg, rgba(27,31,75,.04), transparent 58%);
  --topbar-bg: #1B1F4B;
  --hero-grad: linear-gradient(150deg, rgba(27,31,75,.08), rgba(255,107,74,.05) 58%, transparent);
  --grid-gap: 16px; --card-radius: 20px;
  /* ★ 恢复质感层：这两项原本是 0，正是"平、冷、像后台"的根因 */
  --noise-opacity: .20; --aura-opacity: .34;
  --shadow-sm: 0 1px 2px rgba(20,24,58,.05), 0 2px 8px rgba(20,24,58,.045);
  --shadow-md: 0 4px 16px rgba(20,24,58,.075), 0 14px 36px rgba(20,24,58,.055);
  --shadow-lg: 0 12px 34px rgba(20,24,58,.11), 0 34px 68px rgba(20,24,58,.075);
}

/* 深靛蓝主题：保留极光与噪点（只有极低强度），避免大面积平色块 */
[data-theme="blue"] body::before{
  background:
    radial-gradient(54% 40% at 6% -8%, rgba(255,107,74,.13), transparent 62%),
    radial-gradient(48% 38% at 98% 0%, rgba(90,99,168,.16), transparent 58%),
    radial-gradient(62% 48% at 50% 110%, rgba(27,31,75,.07), transparent 64%);
}

/* ---- 深靛蓝主题：顶栏 ---- */
[data-theme="blue"] .topbar{
  background: linear-gradient(180deg, #232856, #1B1F4B);
  border-bottom: 0;
  box-shadow: 0 2px 14px rgba(12,15,40,.28);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
[data-theme="blue"] .topbar.scrolled{
  box-shadow: 0 2px 18px rgba(12,15,40,.36);
}
[data-theme="blue"] .brand-name,
[data-theme="blue"] .brand-text b{ color: #fff; }
[data-theme="blue"] .brand-text small{ color: rgba(255,255,255,.68); }

/* logo：珊瑚橙实心块 —— 全站第一个暖色落点，视线自然先落在这里 */
[data-theme="blue"] .brand-mark{
  width: auto; min-width: 54px; height: 34px; padding: 0 13px;
  border-radius: 11px;
  background: linear-gradient(180deg, #FF8A6B, #FF6B4A);
  background-size: 100% 100%;
  color: #fff;
  font-size: 15px; font-weight: 900; letter-spacing: .6px;
  text-shadow: 0 1px 2px rgba(150,45,20,.32);
  box-shadow: 0 3px 12px rgba(255,107,74,.38), 0 1px 2px rgba(150,45,20,.22),
              inset 0 1px 0 rgba(255,255,255,.40);
  animation: none;
}
[data-theme="blue"] .brand-mark::after{ display: none; }
[data-theme="blue"] .brand:hover .brand-mark{ transform: translateY(-1px); }
[data-theme="blue"] .brand-mark.sm{
  min-width: 42px; height: 28px; padding: 0 10px; border-radius: 9px; font-size: 13px;
}

/* 顶栏内的圆形按钮（移动端）也要在深底上看得清 */
[data-theme="blue"] .icon-btn{ color: #fff; background: rgba(255,255,255,.14); }
[data-theme="blue"] .icon-btn:hover{ background: rgba(255,255,255,.24); }

/* ---- 深靛蓝主题：顶部简介区（品牌区，已瘦身） ---- */
[data-theme="blue"] .intro-bar{
  background: linear-gradient(180deg, #232856, #1B1F4B);
  color: #fff; border-radius: 0 0 20px 20px;
  margin: 0 0 10px; padding: 10px 18px 13px;
  box-shadow: 0 6px 24px rgba(12,15,40,.22);
}
[data-theme="blue"] .ib-title{ color: #fff; }
[data-theme="blue"] .ib-desc{ color: rgba(255,255,255,.78); }
[data-theme="blue"] .ib-stat{ background: rgba(255,255,255,.12); }
[data-theme="blue"] .ib-stat .sv{ color: #fff; }
[data-theme="blue"] .ib-stat .sl{ color: rgba(255,255,255,.68); }
[data-theme="blue"] .ib-stat u{ color: rgba(255,255,255,.70); }

/* 顶部搜索框（深底上的玻璃白） */
[data-theme="blue"] .filters{ margin-top: 0; }
[data-theme="blue"] .search-wrap{
  background: rgba(255,255,255,.14);
  border: 1px solid rgba(255,255,255,.18);
}
[data-theme="blue"] .search-wrap input{ color: #fff; }
[data-theme="blue"] .search-wrap input::placeholder{ color: rgba(255,255,255,.58); }
[data-theme="blue"] .search-icon{ color: rgba(255,255,255,.68); }
[data-theme="blue"] .search-clear{ color: rgba(255,255,255,.78); }

/* ★ 珊瑚橙：价格与行动按钮全站统一出口 */
[data-theme="blue"] .price-now,
[data-theme="blue"] .price-strong{ color: var(--warm); }

/* ============================================================
   问候语轮播（客户不可点，每 4 秒自动上滚一条）
   ============================================================ */
.bless{
  display: flex; align-items: flex-start; gap: 9px;
  background: rgba(255,255,255,.12);
  border-radius: 12px; padding: 11px 13px;
  min-height: 46px; margin: 0 0 12px;
  box-sizing: border-box; width: 100%;
}
.bless-ic{
  flex: 0 0 auto; font-size: 13px; line-height: 20px;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.2));
}
.bless-body{
  flex: 1 1 auto; height: 20px; overflow: hidden; position: relative;
  min-width: 0; max-width: 100%;
}
.bless-txt{
  position: absolute; inset: 0;
  font-size: 12.5px; line-height: 20px; color: rgba(255,255,255,.95);
  opacity: 0; transform: translateY(100%);
  transition: transform .45s cubic-bezier(.4,0,.2,1), opacity .45s cubic-bezier(.4,0,.2,1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bless-txt.show{ opacity: 1; transform: translateY(0); }
.bless-txt.out{ opacity: 0; transform: translateY(-100%); }
.bless-dots{
  display: flex; gap: 3px; align-self: center; flex: 0 0 auto; padding-left: 2px;
}
.bless-dots i{
  width: 4px; height: 4px; border-radius: 50%;
  background: rgba(255,255,255,.35);
  transition: width .3s var(--ease), background .3s var(--ease);
}
.bless-dots i.on{ background: #fff; width: 10px; border-radius: 2px; }

/* ============================================================
   城市快捷筛选（搜索框下方，横滑）
   ============================================================ */
.city-row{
  display: flex; gap: 6px; margin-top: 10px;
  overflow-x: auto; padding-bottom: 1px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.city-row::-webkit-scrollbar{ display: none; }
.city{
  flex: 0 0 auto; height: 26px; padding: 0 12px; border-radius: 999px;
  display: inline-flex; align-items: center;
  font-size: 11.5px; font-weight: 700; white-space: nowrap;
  background: rgba(255,255,255,.16); color: rgba(255,255,255,.90);
  border: 0; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.city.on{ background: #fff; color: #2E3570; }
.city:active{ transform: scale(.96); }

/* ============================================================
   底部双 Tab 导航（全部演出 / 私信咨询）
   ============================================================ */
.tabbar-2{
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 70;
  display: grid; grid-template-columns: repeat(2, 1fr);
  background: var(--bg); border-top: 1px solid var(--border);
  padding: var(--tabbar-pad-t) var(--tabbar-pad-x) calc(var(--tabbar-pad-b) + env(safe-area-inset-bottom));
  gap: 8px;
}
.tabbar-2 .tab2{
  display: flex; align-items: center; justify-content: center; gap: 7px;
  height: var(--tabbar-btn-h); border-radius: 11px;
  font-size: 11px; font-weight: 700; color: var(--text-faint);
  background: var(--surface); border: 0; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.tabbar-2 .tab2 svg{
  width: 19px; height: 19px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.tabbar-2 .tab2.on{ color: #fff; background: #2E3570; }
.tabbar-2 .tab2.on svg{ stroke-width: 2; }
.tabbar-2 .tab2:active{ transform: scale(.985); }

/* ============================================================
   ★ V2 · 详情页：场次切换 + 票档选择
   ============================================================ */
.sess-row{
  display: flex; gap: 8px; overflow-x: auto;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  padding-bottom: 2px; margin: 0 0 14px;
}
.sess-row::-webkit-scrollbar{ display: none; }
.sess{
  flex: 0 0 auto; min-width: 92px; padding: 9px 13px; border-radius: 11px;
  background: #fff; border: 1.5px solid var(--border);
  text-align: left; cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.sess-d{ font-size: 12.5px; font-weight: 800; color: var(--text); line-height: 1.3; }
.sess-t { font-size: 10.5px; color: var(--text-faint); margin-top: 2px; }
.sess.on{
  border-color: #2E3570; background: #F3F7FE;
  box-shadow: 0 0 0 3px rgba(46,53,112,.10);
}
.sess.on .sess-d{ color: #2E3570; }

/* 票档列表 */
.tier-list{ display: flex; flex-direction: column; gap: 9px; }
.tier{
  display: flex; align-items: center; gap: 11px;
  padding: 12px 13px; border-radius: 12px;
  background: #fff; border: 1.5px solid var(--border);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.tier.on{
  border-color: #2E3570; background: #F8FAFF;
  box-shadow: 0 0 0 3px rgba(46,53,112,.10);
}
.tier-info{ flex: 1; min-width: 0; }
.tier-n{ font-size: 13px; font-weight: 800; color: var(--text); line-height: 1.35; }
.tier-s{ font-size: 10.5px; color: var(--text-faint); margin-top: 3px; }
.tier-s .kw{ color: #B54708; font-weight: 800; }
.tier-p{ text-align: right; flex: 0 0 auto; }
.p-face{ font-size: 10.5px; color: var(--text-faint); text-decoration: line-through; }
.p-sale{
  font-size: 17px; font-weight: 900; color: #E8452A;
  line-height: 1.2; font-variant-numeric: tabular-nums; letter-spacing: -.3px;
}
.p-sale .cur{ font-size: 12px; font-weight: 800; }
.p-sale .per{ font-size: 10px; color: var(--text-faint); font-weight: 600; }
.tick{
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1.5px solid var(--border-strong); background: #fff;
  font-size: 11px; font-weight: 900; color: transparent;
  transition: all var(--dur-fast) var(--ease);
}
.tier.on .tick{ background: #2E3570; border-color: #2E3570; color: #fff; }

/* 倒计时（详情页通栏实色） */
.d-countdown{
  display: flex; align-items: center; justify-content: space-between;
  background: linear-gradient(135deg, #262B5E, #1B1F4B); padding: 13px 14px; border-radius: 14px;
  margin: 0 0 14px;
}
.d-cd-l{ font-size: 10.5px; color: rgba(255,255,255,.62); font-weight: 600; }
.d-cd-v{
  font-size: 17px; font-weight: 900; color: #fff;
  font-variant-numeric: tabular-nums; letter-spacing: -.3px;
}
/* ★ 紧迫态用珊瑚橙的亮版本：深靛蓝底上够亮，也和全站暖色出口一致。
   原来的 #FF8A80 在深底上偏灰、对比度不足。 */
.d-cd-v.urgent{ color: #FF9578; text-shadow: 0 0 14px rgba(255,107,74,.45); }

/* 列表卡片上的倒计时条（V2 已改为海报底部整块布局，见文件末尾最终版） */
.cd-label{ font-size: 9.5px; color: rgba(255,255,255,.72); font-weight: 600; }
.cd-num{
  font-size: 15px; font-weight: 900; color: #fff; letter-spacing: -.4px;
  font-variant-numeric: tabular-nums;
}

/* 吸底条（纯白，不用毛玻璃） */
.sticky-ask{
  position: sticky; bottom: 0; z-index: 20;
  background: #fff; box-shadow: 0 -1px 0 var(--border);
  padding: 10px 14px calc(14px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 12px;
}
.sticky-ask .sa-price{ flex: 1; min-width: 0; }
.sticky-ask .sa-lb{ font-size: 10.5px; color: var(--text-faint); }
.sticky-ask .sa-v{
  font-size: 19px; font-weight: 900; color: #E8452A;
  font-variant-numeric: tabular-nums; letter-spacing: -.4px;
}
.sticky-ask .btn{ flex: 0 0 auto; }

/* 详情页信息行（去掉敏感项后的干净版） */
.info-row .info-k{ color: var(--text-faint); }
.info-row .info-v{ color: var(--text); font-weight: 600; }

/* ============================================================
   ★ V2 · 顶部蓝区内部布局修正
   ============================================================ */
.intro-bar .brand-line{
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center;
  gap: 6px; margin-bottom: 8px;
}
.intro-bar .ib-title{
  font-size: 19px; font-weight: 800; letter-spacing: -.3px;
  margin: 0; line-height: 1.3; color: #fff;
  text-align: center; width: 100%;
}

/* ★ 蓝区问候语已下线（HTML 容器一并移除）。
   下面这段 .intro-bar .bless* 的覆盖规则随之作废，已删除 ——
   留着只会让后人以为这里还有东西。
   基础 .bless / .bless-* 规则保留在文件上方（第 1573 行起），
   复活问候语时直接复用，不必重写。 */

.intro-bar .ib-stats{
  display: flex; gap: 14px; flex-wrap: wrap; justify-content: center;
}
.intro-bar .ib-stat{
  display: flex; flex-direction: column; border-radius: 10px;
  padding: 7px 11px; min-width: 62px;
}
.intro-bar .ib-stat .sv{
  font-size: 16px; font-weight: 900; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.intro-bar .ib-stat .sv u{
  font-size: 10.5px; font-weight: 700; text-decoration: none; margin-left: 1px;
}
.intro-bar .ib-stat .sl{
  font-size: 10px; margin-top: 1px;
}
.intro-bar .search-wrap{ margin: 0; }
.intro-bar .city-row{ margin-top: 10px; }

/* 蓝区之外的筛选区：给状态条和排序行留白 */
#view-home .filters{
  padding: 0 18px; margin-bottom: 12px;
}
@media (max-width: 900px){
  #view-home .filters{ padding: 0 14px; }
}

/* 底部 Tab 选中态在蓝主题下用主色 */
[data-theme="blue"] .tabbar-2 .tab2.on{ background: #2E3570; color: #fff; }

/* 桌面端隐藏底部双 Tab */
@media (min-width: 901px){
  .tabbar-2{ display: none; }
}

/* 页面容器（首页内容左右留白） */
#view-home .card-grid,
#view-home .empty{
  padding-left: 18px; padding-right: 18px;
}
@media (max-width: 900px){
  #view-home .card-grid,
  #view-home .empty{ padding-left: 14px; padding-right: 14px; }
}

/* ============================================================
   ★ V2 · 卡片封面内的文字层级（最终定稿）
   ------------------------------------------------------------
   结构：
     .card-poster
       ├ .poster-badges    （绝对定位，左上角）
       ├ .poster-icon      （绝对定位，右上，装饰）
       └ .poster-foot      （绝对定位贴底，纵向 flex）
            ├ .poster-info    演出名 + 城市·场馆
            └ .poster-countdown  倒计时条

   关键：文字块和倒计时是同一个 flex 列里的兄弟节点，
        天然不可能互相遮挡 —— 不再依赖估算的 bottom 数值。
   ============================================================ */
.event-card .card-poster{
  display: block !important;      /* 干掉旧的 grid + place-items:center */
  position: relative !important;
  overflow: hidden;
  aspect-ratio: 16/9;
  isolation: isolate;
}
.event-card .card-poster .poster-foot{
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; flex-direction: column;
}
.event-card .card-poster .poster-info{
  position: static !important; transform: none !important;
  padding: 0 11px 9px !important; margin: 0 !important;
  pointer-events: none;
}
.event-card .card-poster .poster-name{
  color: #fff; font-size: 15px; font-weight: 900; line-height: 1.28;
  letter-spacing: -.2px; margin: 0;
  text-shadow: 0 2px 12px rgba(0,0,0,.7);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.event-card .card-poster .poster-venue{
  color: rgba(255,255,255,.88); font-size: 10.5px; font-weight: 600;
  margin: 4px 0 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 6px rgba(0,0,0,.65);
}
.event-card .card-poster .poster-countdown{
  position: static !important; left: auto !important; right: auto !important;
  bottom: auto !important; z-index: auto;
  background: linear-gradient(to top, rgba(6,16,38,.94), rgba(6,16,38,.66));
  padding: 9px 11px;
  display: flex; align-items: baseline; gap: 5px;
}
.event-card .card-poster .poster-badges{
  position: absolute; top: 9px; left: 9px; right: 9px; z-index: 4;
  display: flex; gap: 5px; flex-wrap: wrap;
}
.event-card .card-poster .poster-icon{
  position: absolute; right: 10%; top: 30%; z-index: 2;
}

/* ============================================================
   ★ V2 · 票档卡片排版修正（票面价与售价拉开层次）
   ============================================================ */
.tier-list .tier{
  padding: 11px 12px; gap: 10px; align-items: center;
}
.tier-list .tier-info{ flex: 1 1 auto; min-width: 0; }
.tier-list .tier-n{
  font-size: 13.5px; font-weight: 800; line-height: 1.3; color: var(--text);
}
.tier-list .tier-s{
  font-size: 10.5px; color: var(--text-faint); margin-top: 3px; line-height: 1.3;
}
.tier-list .tier-p{
  flex: 0 0 auto; text-align: right; min-width: 78px;
  display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
}
.tier-list .p-face{
  font-size: 10px; color: var(--text-faint); text-decoration: line-through;
  line-height: 1.2; white-space: nowrap;
}
.tier-list .p-sale{
  font-size: 17px; font-weight: 900; color: #E8452A;
  line-height: 1.15; white-space: nowrap;
  font-variant-numeric: tabular-nums; letter-spacing: -.4px;
  display: flex; align-items: baseline; gap: 1px;
}
.tier-list .p-sale .cur{ font-size: 11.5px; }
.tier-list .p-sale .per{ font-size: 9.5px; color: var(--text-faint); font-weight: 600; margin-left: 1px; }

/* 详情页分区 */
.d-wrap{ padding: 14px; }
.d-sec{ margin-bottom: 16px; }
.d-sec-hd{
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 9px;
}
.d-sec-t{ font-size: 13.5px; font-weight: 800; color: var(--text); }
.d-sec-n{ font-size: 11px; color: var(--text-faint); }
.d-note{ font-size: 12.5px; color: var(--text-dim); line-height: 1.7; margin: 0; }
.d-disclaimer{
  font-size: 11px; color: var(--text-faint); line-height: 1.7;
  margin: 18px 0 0; padding: 11px 12px;
  background: var(--surface); border-radius: 10px;
}
.tier-empty{
  padding: 20px 14px; text-align: center; border-radius: 12px;
  background: var(--surface); font-size: 12.5px; color: var(--text-dim);
  border: 1px dashed var(--border-strong);
}

/* ============================================================
   ★ V2 · 详情页吸底条：移动端改为固定定位，真正贴底
   ============================================================ */
@media (max-width: 900px){
  /* 吸底条固定在 Tab 栏之上，任何时候都可见 */
  #view-detail .sticky-ask{
    position: fixed; left: 0; right: 0;
    bottom: calc(64px + env(safe-area-inset-bottom));
    z-index: 55;
    box-shadow: 0 -1px 0 var(--border), 0 -8px 24px rgba(20,24,58,.06);
  }
  /* 给吸底条 + Tab 让位 */
  #view-detail .d-wrap{ padding-bottom: 20px; }
  #view-detail{ padding-bottom: calc(160px + env(safe-area-inset-bottom)); }
}

/* ============================================================
   ★★★ V3 · 紧凑布局改造（压缩顶部蓝区、收紧左右留白）
   ------------------------------------------------------------
   改造前实测（390×844）：
     顶栏 56 + 蓝区 329 = 385px，占屏 45.6%
     第一张卡片要滑到 542px 才看见
   改造目标：蓝区压到 ~110px，首屏就能看到卡片
   ============================================================ */

/* ---------- 1. 顶栏：右侧加搜索按钮 ---------- */
.topbar-search{
  margin-left: auto; flex: 0 0 auto;
  width: 38px; height: 38px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.16); color: #fff;
  border: 0; cursor: pointer; padding: 0;
  transition: background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.topbar-search:hover{ background: rgba(255,255,255,.26); }
.topbar-search:active{ transform: scale(.94); }

/* 搜索面板：点放大镜从顶栏下方滑出 */
.search-panel{
  position: fixed; top: 0; left: 0; right: 0; z-index: 90;
  background: var(--topbar-bg, #2E3570);
  padding: calc(env(safe-area-inset-top) + 10px) 14px 12px;
  box-shadow: 0 8px 26px rgba(20,24,58,.26);
  animation: spDrop .24s var(--ease);
}
@keyframes spDrop{ from{ transform: translateY(-100%); } to{ transform: translateY(0); } }
.search-panel-in{ display: flex; align-items: center; gap: 10px; }
.search-panel .search-wrap{
  flex: 1 1 auto; margin: 0; height: 44px;
  background: rgba(255,255,255,.18);
  border: 1px solid rgba(255,255,255,.26);
}
.search-panel .search-wrap input{ color: #fff; font-size: 15px; }
.search-panel .search-wrap input::placeholder{ color: rgba(255,255,255,.66); }
.search-panel .search-icon{ color: rgba(255,255,255,.78); }
.search-panel .search-clear{ color: rgba(255,255,255,.85); }
.sp-close{
  flex: 0 0 auto; background: 0; border: 0; cursor: pointer;
  color: rgba(255,255,255,.92); font-size: 14px; font-weight: 700;
  padding: 8px 2px;
}
/* 遮罩 */
.search-mask{
  position: fixed; inset: 0; z-index: 85;
  background: rgba(8,16,36,.42);
  backdrop-filter: blur(2px);
  animation: fadeIn .2s var(--ease);
}

/* ---------- 2. 顶部蓝区：砍掉一半高度 ---------- */
[data-theme="blue"] .intro-bar{
  border-radius: 0 0 16px 16px;
  margin: 0 0 10px;
  padding: 13px 14px 12px;          /* 16/18/18 → 13/14/12 */
}
.intro-bar .brand-line{
  margin-bottom: 0;                  /* 12 → 0，标题和问候语之间留 8px 就够 */
  gap: 8px;
}
.intro-bar .ib-title{
  font-size: 17px;                   /* 19 → 17 */
  letter-spacing: -.2px; line-height: 1.25;
  margin: 0;                         /* 原来是 0 0 2px —— 下面没东西了，留白无意义 */
}
/* 数字块：手机端直接隐藏（客户不关心规模数据），桌面端保留 */
.intro-bar .ib-stats{ display: none; }
.intro-bar .brand-line > .ib-stats{ display: none; }

/* 蓝区（手机端）：只留 slogan 一行
   ------------------------------------------------------------
   原本这里还有一行自动轮播的问候语，占着 13px 上 + 12px 下 + 18px 行高。
   问候语下线后，蓝区里只剩 #ibTitle（来自后台 tagline 的 slogan，比如
   「国庆快乐！❤️」）和城市胶囊，再撑 48px 就说不过去了。

   现在压成：上下各 8px + 标题行高，总计约 40px。
   注意 safe-area-inset-top 保留 —— 有些机型（灵动岛/刘海）的状态栏
   会压在内容上，这 12px 是安全距离，不能省。
   城市胶囊有数据时（cityRow 非空）靠 margin-top 自己撑开，互不影响。 */
@media (max-width: 900px){
  .intro-bar{
    padding: calc(env(safe-area-inset-top) + 8px) 14px 8px;
  }
  .intro-bar .brand-line{
    display: block;
  }
  .intro-bar .ib-title{
    font-size: 18px;
    line-height: 1.2;
  }
  /* 城市胶囊紧贴标题下沿，少一层 9px 间距 */
  .intro-bar .city-row{ margin-top: 7px; }
}

/* 问候语已下线，原来这里有一段压扁 .bless 的规则（34px 高度、18px 行高），
   现在没有对应元素了，一并删除。 */

/* 城市：挪到蓝区底部，压缩高度 */
.city-row{
  margin-top: 9px; padding-bottom: 0; gap: 6px;
}
.city{ height: 25px; padding: 0 11px; font-size: 11.5px; }

/* 蓝区内不再放搜索框（已移到顶栏弹出面板） */
.intro-bar .search-wrap{ display: none; }

@media (max-width: 900px){
  #view-home .filters{ padding: 0 12px; margin-bottom: 8px; }

  /* ---------- 3. 左右留白收紧 ---------- */
  #main{ padding: 0 12px 30px; }        /* 14 → 12 */
  .card-grid{ padding-left: 0; padding-right: 0; padding-top: 12px; gap: 10px; }
}

/* ---------- 4. 状态筛选条：与城市条合并成紧凑一行 ---------- */
@media (max-width: 640px){
  .chips{ gap: 6px; }
  .chips-status{ margin-top: 0; }
  .chips-status .chip{ font-size: 12px; padding: 5px 11px; }
  .chip{ gap: 5px; }
  .sort-row{ margin-top: 8px; gap: 8px; }
  .sort-tab{ padding: 5px 10px; font-size: 12px; }
  .result-count{ font-size: 11.5px; }

  /* 卡片再紧凑一点，首屏能多露内容 */
  .card-title{ font-size: 14px; line-height: 1.32; font-weight: 700; }
  .card-body{ padding: 10px 12px 11px; gap: 6px; }
  .card-sub{ font-size: 11.5px; }
  .price-range{ font-size: 14px; }
}

/* ---------- 5. 卡片封面缺图时的兜底（替代破图麦克风） ---------- */
.poster-fallback{
  position: absolute; inset: 0; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(120% 90% at 78% 12%, rgba(107,160,255,.55), transparent 62%),
    linear-gradient(150deg, hsl(var(--pf-h, 218) 62% 46%), hsl(var(--pf-h, 218) 58% 30%));
  overflow: hidden;
}
/* ★ 图片没加载出来（弱网/挂图）时兜底才显形，必须盖在图片层上面，
     否则透明图片层会把兜底的渐变挡住。 */
.card-poster .poster-fallback{ z-index: 2; }
/* 图片一旦就绪，兜底层立刻让位（兜底层由 JS 按需取消 hidden） */
.card-poster:has(.poster-img.is-ready) .poster-fallback{ display: none; }
.poster-fallback::after{
  content: ""; position: absolute; inset: 0;
  background:
    repeating-linear-gradient(115deg, rgba(255,255,255,.055) 0 2px, transparent 2px 22px);
  pointer-events: none;
}
.poster-fallback .pf-glyph{
  position: relative; z-index: 2;
  font-family: var(--font-num);
  font-size: 76px; font-weight: 900; line-height: 1;
  color: rgba(255,255,255,.16);
  text-shadow: 0 6px 22px rgba(4,14,42,.30);
  letter-spacing: -.04em;
  user-select: none; pointer-events: none;
}
.poster-fallback .pf-note{
  position: absolute; z-index: 2; left: 50%; bottom: 44%;
  transform: translateX(-50%);
  font-family: var(--font-num);
  font-size: 10px; font-weight: 800; letter-spacing: .34em;
  color: rgba(255,255,255,.34); white-space: nowrap;
}

/* ---------- 6. 详情页空白收紧 ---------- */
@media (max-width: 900px){
  #view-detail{ padding-bottom: calc(120px + env(safe-area-inset-bottom)); }
}

/* ---------- 7. 卡片封面真实图片 + 新价格样式 ---------- */
.card-poster .poster-img{
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  display: block;
  /* 加载中先不显示，避免"半截图"的缓冲感；加载完淡入 */
  opacity: 0;
  transition: opacity .28s var(--ease, ease);
  background: hsl(var(--h, 218) 46% 34%);
}
.card-poster .poster-img.is-ready{ opacity: 1; }
/* 有真实图片时，弱化原有的色块光晕 */
.card-poster:has(.poster-img) .poster-aura{ opacity: .35; }
.card-poster .poster-icon{ display: none; }   /* 旧麦克风图标不再使用 */

.card-body .price-block{ display: flex; flex-direction: column; gap: 1px; }
.card-body .price-range{
  font-family: var(--font-num);
  font-size: 16px; font-weight: 900; letter-spacing: -.3px;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.card-body .price-range .cur{ font-size: 12.5px; font-weight: 800; margin-right: 1px; }
.card-body .price-range .price-suffix{
  font-size: 11.5px; font-weight: 700; color: var(--text-dim);
  margin-left: 3px; letter-spacing: 0;
}

/* ---------- 8. 卡片价格最终形态：票面 ¥807 - 2180 ---------- */
.card-body .price-range{
  display: inline-flex; align-items: baseline; gap: 2px;
  font-family: var(--font-num);
  font-size: 16px; font-weight: 900; letter-spacing: -.3px;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.card-body .price-range .price-label-inline{
  font-size: 11px; font-weight: 700; color: var(--text-dim);
  letter-spacing: 0; margin-right: 3px;
}
.card-body .price-range .price-suffix{ display: none; }

/* ---------- 9. 详情页封面图 / 兜底 ---------- */
.detail-hero{ position: relative; overflow: hidden; }
.detail-hero .hero-img{
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  display: block;
  opacity: 0;
  transition: opacity .28s var(--ease, ease);
  background: hsl(var(--h, 218) 46% 34%);
}
.detail-hero .hero-img.is-ready{ opacity: 1; }
.detail-hero .poster-fallback{ z-index: 0; border-radius: inherit; }
.detail-hero .pf-glyph{
  font-size: clamp(64px, 17vw, 104px);
  color: rgba(255,255,255,.13);
  transform: translateY(14%);       /* 水印下沉，避开左上角徽章与标题 */
}
.detail-hero .pf-note{ bottom: 64%; }
.detail-hero .hero-aura,
.detail-hero .poster-veil{ z-index: 1; }
.detail-hero .detail-title,
.detail-hero .detail-subtitle{ position: relative; z-index: 2; }
/* 旧麦克风图标停用 */
.detail-hero .hero-icon{ display: none; }

/* ---------- 10. 问候语图标：改用 SVG，不依赖 emoji 字体 ---------- */
.bless-ic{
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: rgba(255,255,255,.22);
  color: #fff; flex: 0 0 auto;
}
.bless-ic svg{ display: block; }
/* 封面水印大字：字号跟随容器，避免小屏溢出 */
.poster-fallback .pf-glyph{ font-size: clamp(48px, 14vw, 76px); }

/* ============================================================
   ★ V4 · 按用户原话执行
   ============================================================ */

/* ---------- 1. 徽章左右分角：左上角状态 / 右上角热卖·时间 ---------- */
.event-card .card-poster .poster-badges,
.poster-badges{
  position: absolute; top: 10px; z-index: 4;
  display: flex; gap: 6px; align-items: flex-start;
}
.poster-badges-l{ left: 10px; right: auto; max-width: 58%; flex-wrap: wrap; }
.poster-badges-r{ right: 10px; left: auto; max-width: 46%; flex-wrap: wrap; justify-content: flex-end; }

.detail-hero .detail-badges-l{
  position: absolute !important; top: 14px !important; left: 16px !important; right: auto !important;
  z-index: 4 !important;
  display: flex; gap: 6px; flex-wrap: wrap; max-width: 55%;
}
.detail-hero .detail-badges-r{
  position: absolute !important; top: 14px !important; right: 16px !important; left: auto !important;
  z-index: 4 !important;
  display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; max-width: 42%;
}
/* 详情页里标题要避开两角的徽章 */
.detail-hero .detail-title{ margin-top: 30px; }

/* 热卖徽章：暖色，跟状态徽章区分开 */
.badge.tone-hot2{
  background: linear-gradient(180deg, #FF8A4C, #F26522);
  color: #fff; border: 0;
  box-shadow: 0 2px 8px rgba(214,74,10,.34), inset 0 1px 0 rgba(255,255,255,.34);
}
.badge.tone-hot2 .bdot{ display: none; }

/* ---------- 2. 手机端徽章不换行、字号收紧 ---------- */
@media (max-width: 640px){
  .poster-badges{ top: 8px; }
  .poster-badges-l{ left: 8px; max-width: 56%; }
  .poster-badges-r{ right: 8px; max-width: 44%; }
  .poster-badges .badge{ font-size: 9.5px; padding: 3px 8px; white-space: nowrap; }
  .detail-badges-l{ top: 12px; left: 14px; max-width: 52%; }
  .detail-badges-r{ top: 12px; right: 14px; max-width: 44%; }
  .detail-badges .badge{ font-size: 10px; padding: 3.5px 9px; white-space: nowrap; }
}

/* ---------- 3. 票档：票面价 + 售价 同时显示，售价凸出 ---------- */
.tier-list .tier-p{
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 1px; min-width: 86px; flex: 0 0 auto;
}
.tier-list .tier-face{
  font-size: 10.5px; font-weight: 650; color: var(--text-faint);
  text-decoration: line-through; text-decoration-color: rgba(152,162,179,.5);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tier-list .tier-sale{
  font-family: var(--font-num);
  font-size: 19px; font-weight: 900; letter-spacing: -.5px;
  color: #E8452A; font-variant-numeric: tabular-nums; white-space: nowrap;
  line-height: 1.1;
}
.tier-list .tier-sale .cur{ font-size: 12px; font-weight: 800; margin-right: .5px; }
.tier-list .tier-sale .unit{ font-size: 10.5px; font-weight: 700; color: var(--text-dim); margin-left: 2px; }
/* 只有票面骨架、没有实时售价 → 显示「售价待定」 */
.tier-list .tier-sale.tier-tbd{
  font-family: var(--font, inherit);
  font-size: 13px; font-weight: 800; letter-spacing: 0;
  color: var(--brand, #2E3570);
}
/* 折扣标签 */
.tier-list .tier-off{
  display: inline-block; margin-top: 2px;
  font-size: 9.5px; font-weight: 800; padding: 1.5px 5px;
  border-radius: 4px; color: #fff;
  background: linear-gradient(180deg, #FF8A4C, #F26522);
  white-space: nowrap;
}

/* ---------- 4. 库存状态：有票 / 暂无库存 ---------- */
.tier-list .tier-stock{
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-weight: 700; color: #067647;
}
.tier-list .tier-stock.out{ color: var(--text-faint); }
.tier-list .tier-stock::before{
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}

/* ============================================================
   ★★★ V5 · 严格按效果图还原卡片
   ------------------------------------------------------------
   结构：色块封面（4:5）内嵌 场次左上 / 状态右上 / 名称·城市·倒计时底部
        白底区：完整标题 + 城市·场次 + ¥807起 / 票面¥580起
   ============================================================ */

/* 卡片外框 */
.event-card{
  position: relative; border-radius: 20px; overflow: hidden;
  background: #fff; border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(20,24,58,.04), 0 6px 18px rgba(20,24,58,.055);
  display: flex; flex-direction: column;
  transition: box-shadow .32s var(--ease), transform .32s var(--ease), border-color .32s var(--ease);
}
.event-card:hover{
  border-color: var(--border-strong);
  box-shadow: 0 3px 8px rgba(20,24,58,.07), 0 18px 40px rgba(20,24,58,.11);
}

/* 封面：4:5 竖版色块 */
.event-card .card-poster{
  display: block !important;
  position: relative !important;
  aspect-ratio: 4 / 5;
  overflow: hidden; isolation: isolate;
  background:
    radial-gradient(130% 100% at 72% 8%, hsl(var(--h) 78% 58% / .95), transparent 68%),
    linear-gradient(168deg, hsl(var(--h) 62% 48%), hsl(var(--h) 66% 34%));
}

/* 左上角：场次数 */
.event-card .cb-count{
  position: absolute; top: 9px; left: 9px; z-index: 4;
  display: inline-flex; align-items: center;
  height: 21px; padding: 0 8px; border-radius: 6px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .2px;
  color: #fff; background: rgba(16,24,40,.62);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.18);
}

/* 右上角：状态 */
.event-card .cb-status{
  position: absolute; top: 9px; right: 9px; z-index: 4;
  display: inline-flex; align-items: center;
  height: 21px; padding: 0 8px; border-radius: 6px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .2px;
  color: #fff; white-space: nowrap;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 1px 4px rgba(6,16,38,.24);
}
.event-card .cb-status.tone-hot{ background: linear-gradient(180deg,#FF8A4C,#EC5F14); }
.event-card .cb-status.tone-ok{ background: linear-gradient(180deg,#3DBF7A,#12925A); }
.event-card .cb-status.tone-warn{ background: linear-gradient(180deg,#F5B83D,#D98A00); }
.event-card .cb-status.tone-off{ background: rgba(16,24,40,.55); backdrop-filter: blur(6px); }

/* 封面底部文字区 */
.event-card .card-on{
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: 34px 11px 11px;
  background: linear-gradient(to top, hsl(var(--h) 62% 18% / .96) 12%, hsl(var(--h) 62% 22% / .72) 46%, transparent);
  display: flex; flex-direction: column; gap: 3px;
}
.event-card .card-on-t{
  margin: 0; font-size: 14.5px; font-weight: 800; line-height: 1.28;
  color: #fff; letter-spacing: -.2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; text-shadow: 0 1px 6px rgba(4,14,42,.4);
}
.event-card .card-on-s{
  margin: 0; font-size: 10.5px; font-weight: 600;
  color: rgba(255,255,255,.74);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.event-card .card-on-cd{
  margin: 3px 0 0; display: flex; align-items: baseline; gap: 4px;
}
.event-card .card-on-cd .cd-t{ font-size: 10.5px; color: rgba(255,255,255,.70); }
/* ★ 7 天内的标签也用暖色：只把数字染色的话，「距开演」三个字还是灰的，
   整行读起来像半截话。现在标签 + 数值同一色系，一眼就是「要紧」。
   取值用 #FFB4A0（珊瑚橙的浅版）—— 直接上 #FF6B6B 会在深色海报上
   和数字抢亮度，两个都亮等于都不亮。 */
.event-card .card-on-cd .cd-t.is-urgent{
  color: #FFB4A0; font-weight: 800;
}
.event-card .card-on-cd .cd-v{
  font-family: var(--font-num);
  font-size: 13px; font-weight: 900; letter-spacing: -.2px;
  color: #FF6B6B; text-shadow: 0 0 12px rgba(255,80,80,.34);
  font-variant-numeric: tabular-nums;
}
/* 已开演 / 首场已过：不用红色（红色是「快来」的信号，这里是「晚了」）。
   压成中性灰白，安静地待着，别抢正在售票的那些项目的注意力。 */
.event-card .card-on-cd .cd-t.is-past,
.event-card .card-on-cd .cd-v.is-past{
  color: rgba(255,255,255,.58); font-weight: 600; text-shadow: none;
  font-family: var(--font); font-size: 10.5px;
}

/* 白底区：只放海报上没有的信息（城市·场次·开演日 + 票价）
   海报上已印标题/城市/场馆/倒计时，这里再写一遍纯属浪费首屏高度 */
.event-card .card-body{
  padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 6px;
  flex: 1 1 auto;
}
.event-card .card-meta-row{
  display: flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 650; color: var(--text-dim);
  line-height: 1.3; min-width: 0;
}
.event-card .card-meta-city{
  color: var(--text); font-weight: 750;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.event-card .card-meta-dot{ color: var(--text-faint); flex: 0 0 auto; }
.event-card .card-meta-sess{ flex: 0 0 auto; color: var(--text-dim); }
.event-card .card-meta-date{
  margin-left: auto; flex: 0 0 auto;
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  color: var(--text-faint); font-weight: 650;
}
.event-card .card-prices{
  margin-top: auto; padding-top: 4px;
  display: flex; flex-direction: column; gap: 1px;
}
.event-card .cp-sale{
  font-family: var(--font-num);
  font-size: 22px; font-weight: 900; letter-spacing: -.7px; line-height: 1.05;
  color: #E8452A; font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline;
}
.event-card .cp-sale .cur{ font-size: 13px; font-weight: 800; margin-right: .5px; }
.event-card .cp-sale .unit{ font-size: 11px; font-weight: 700; color: #E8452A; margin-left: 1.5px; }

/* ★ 只有票面价（没有售价）时：数字用沉稳的深色，不用售价红。
   原因：珊瑚橙红是「实价」的专属色号，票面价是参考价，
   染成一样的红会让客户以为那就是成交价 —— 到了报价环节落差感很强。
   旁边的「票面」小标签负责把话说清楚。 */
.event-card .cp-sale.is-face{ color: var(--text); }
.event-card .cp-sale.is-face .unit{ color: var(--text-dim); }
.event-card .cp-sale .cp-note{
  margin-left: 6px; align-self: center;
  font-family: var(--font);
  font-size: 9.5px; font-weight: 700; letter-spacing: 0;
  color: var(--text-faint);
  background: var(--surface);
  padding: 2px 5px; border-radius: 5px;
}

/* 连票面都没有：不编数字，老实说「价格咨询」 */
.event-card .cp-ask{
  font-size: 14px; font-weight: 800; color: var(--text-dim);
  line-height: 1.2; padding: 3px 0 1px;
}

/* ★ 卡片上原来还有一行「票面 ¥xxx 起」的 .cp-face，现已移除：
   卡片只留一个价格，票面在详情页逐档看。规则一并删掉。*/

/* 手机端再收紧一档，保证两列在小屏也放得下 */
@media (max-width: 640px){
  .event-card{ border-radius: 18px; }  .event-card .card-on{ padding: 26px 9px 9px; }
  .event-card .card-on-t{ font-size: 13px; }
  .event-card .card-on-s{ font-size: 9.5px; }
  .event-card .card-on-cd .cd-v{ font-size: 12px; }
  .event-card .cb-count,
  .event-card .cb-status{ height: 19px; font-size: 9.5px; padding: 0 6.5px; top: 7px; }
  .event-card .cb-count{ left: 7px; }
  .event-card .cb-status{ right: 7px; }
  .event-card .card-body{ padding: 9px 11px 11px; gap: 5px; }
  .event-card .card-meta-row{ font-size: 10px; gap: 4px; }
  .event-card .cp-sale{ font-size: 20px; }
  .event-card .cp-sale .cur{ font-size: 12px; }
}
@media (max-width: 380px){
  .event-card .card-on-t{ font-size: 12px; }
  .event-card .card-full-title{ font-size: 11.5px; }
  .event-card .cp-sale{ font-size: 17px; }
}

/* ============================================================
   ★ V5 · 详情页票档行（严格按效果图2）
   左：580票面（看台） / 随机分配
   右：票面 ¥580（划线）  ¥807/张（红色大字）
   ============================================================ */
.tier-list{ display: flex; flex-direction: column; gap: 9px; }

.tier-list .tier{
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 13px; border-radius: 12px;
  background: #fff; border: 1.5px solid var(--border);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
.tier-list .tier.on{
  border-color: #2E3570;
  background: #F5F9FF;
  box-shadow: 0 0 0 3px rgba(46,53,112,.10);
}
.tier-list .tier.out{
  background: #FAFBFC; border-color: #EEF1F5;
  opacity: .62; pointer-events: none;
}

.tier-list .tier-info{ flex: 1 1 auto; min-width: 0; }
.tier-list .tier-n{
  font-size: 14px; font-weight: 750; color: var(--text);
  line-height: 1.3; letter-spacing: -.2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tier-list .tier.on .tier-n{ color: #2E3570; }
.tier-list .tier-sub{
  display: flex; align-items: center; gap: 8px;
  margin-top: 4px; font-size: 11px; font-weight: 600;
}
.tier-list .tier-seat{ color: var(--text-dim); }
.tier-list .tier-stock{ color: #067647; font-weight: 700; }
.tier-list .tier-stock.out{ color: var(--text-faint); }

/* 右侧价格块 */
.tier-list .tier-p{
  flex: 0 0 auto; min-width: 84px;
  display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
}
.tier-list .tier-face{
  font-size: 10.5px; font-weight: 650; color: var(--text-faint);
  text-decoration: line-through;
  text-decoration-color: rgba(152,162,179,.55);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tier-list .tier-sale{
  font-family: var(--font-num);
  font-size: 20px; font-weight: 900; letter-spacing: -.5px;
  line-height: 1.12; color: #E8452A;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  display: flex; align-items: baseline;
}
.tier-list .tier-sale .cur{ font-size: 12.5px; font-weight: 800; margin-right: .5px; }
.tier-list .tier-sale .unit{ font-size: 10.5px; font-weight: 700; color: #E8452A; margin-left: 1px; }

/* 选中勾 */
.tier-list .tick{
  flex: 0 0 auto; width: 21px; height: 21px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--border-strong);
  color: transparent; font-size: 12px; font-weight: 900;
  transition: all .2s var(--ease);
}
.tier-list .tier.on .tick{
  background: #2E3570; border-color: #2E3570; color: #fff;
}

@media (max-width: 640px){
  .tier-list .tier{ padding: 11px 12px; gap: 8px; border-radius: 11px; }
  .tier-list .tier-n{ font-size: 13.5px; }
  .tier-list .tier-p{ min-width: 78px; }
  .tier-list .tier-sale{ font-size: 19px; }
  .tier-list .tick{ width: 20px; height: 20px; }
}

/* ============================================================
   ★★★ V6 · 按用户图1/图2 精修
   ============================================================ */

/* ---------- 1. 顶部蓝区通栏到边（左右不留白） ---------- */
@media (max-width: 900px){
  /* 主容器去掉左右内边距，蓝区才能铺满 */
  #main{ padding: 0 0 30px; }

  /* 蓝区通栏 */
  [data-theme="blue"] .intro-bar{
    border-radius: 0 0 18px 18px;
    margin: 0 0 10px;
    padding: 12px 14px 13px;
  }

  /* 蓝区之外的筛选区 + 卡片区自己补内边距 */
  #view-home .filters{ padding: 0 12px; }
  #view-home .card-grid{ padding: 12px 12px 0; }

  /* 详情页 / 关于页也自己补 */
  #view-detail, #view-about{ padding-left: 0; padding-right: 0; }
  #view-detail .d-wrap,
  #view-detail .btn-back{ padding-left: 12px; padding-right: 12px; }
  #view-about .about-card{ margin: 0 12px; }
}

/* ---------- 2. 详情页海报顶到屏幕最上方 ---------- */
@media (max-width: 900px){
  /* 详情页时隐藏顶栏，让海报顶到边 */
  body.detail-open .topbar{ display: none; }
  body.detail-open #main{ padding-top: 0; }

  #view-detail .btn-back{
    position: absolute; top: 0; left: 0; z-index: 20;
    margin: 0; padding: 10px 12px;
    color: #fff; background: 0; border: 0;
    text-shadow: 0 1px 6px rgba(4,14,42,.55);
  }
  #view-detail .btn-back svg{ filter: drop-shadow(0 1px 4px rgba(4,14,42,.5)); }

  /* 海报全幅顶到边 */
  #view-detail .detail-hero{
    margin: 0; border-radius: 0 0 20px 20px;
    padding: 0 0 18px;
    min-height: 68vw;                 /* 留足高度：顶部徽章区 + 底部标题区互不打架 */
    display: flex; flex-direction: column; justify-content: flex-end;
  }
  /* 海报上加返回按钮的空间 */
  #view-detail .detail-hero .detail-title,
  #view-detail .detail-hero .detail-subtitle,
  #view-detail .detail-hero .detail-badges-l{ padding-left: 16px; padding-right: 16px; }
  #view-detail .detail-hero .detail-title{
    padding-top: 0;
    margin-top: 0 !important;         /* 贴底布局里不需要让位间距 */
  }
  /* 顶部徽章区：给返回按钮让出高度 */
  #view-detail .detail-hero .detail-badges-l,
  #view-detail .detail-hero .detail-badges-r{
    padding-top: 46px !important;     /* 避开「返回列表」按钮 */
  }
}

/* ---------- 3. 海报可点开看大图 ---------- */
.poster-zoom{
  position: absolute; right: 10px; bottom: 10px; z-index: 5;
  width: 30px; height: 30px; border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(12,20,40,.55); color: #fff;
  border: 1px solid rgba(255,255,255,.24);
  backdrop-filter: blur(8px);
  cursor: pointer; padding: 0;
  transition: background .2s var(--ease), transform .2s var(--ease);
}
.poster-zoom:hover{ background: rgba(12,20,40,.75); }
.poster-zoom:active{ transform: scale(.92); }
.poster-zoom svg{ display: block; }

/* 大图查看层 */
.img-viewer{
  position: fixed; inset: 0; z-index: 200;
  background: rgba(6,10,22,.95);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: fadeIn .22s var(--ease);
  cursor: zoom-out;
}
.img-viewer img{
  max-width: 100%; max-height: 100%;
  object-fit: contain; border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0,0,0,.6);
  animation: viewerIn .28s var(--ease);
}
@keyframes viewerIn{ from{ transform: scale(.9); opacity: 0; } to{ transform: scale(1); opacity: 1; } }
.img-viewer .iv-close{
  position: absolute; top: calc(env(safe-area-inset-top) + 14px); right: 16px;
  width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.16); color: #fff;
  border: 0; cursor: pointer; font-size: 20px; line-height: 1;
  backdrop-filter: blur(8px);
}
.img-viewer .iv-hint{
  position: absolute; bottom: calc(env(safe-area-inset-bottom) + 22px);
  left: 0; right: 0; text-align: center;
  font-size: 12px; color: rgba(255,255,255,.5);
}

/* ---------- 详情页倒计时条：秒级跳动（按效果图2） ---------- */
.d-countdown{
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; border-radius: 12px;
  /* 深蓝实底：不论海报是深是浅，白字永远清晰 */
  background: linear-gradient(135deg, #2E3570, #1B1F4B);
  border: 0;
  box-shadow: 0 4px 16px rgba(46,53,112,.28), inset 0 1px 0 rgba(255,255,255,.18);
}
.d-countdown .d-cd-l{
  font-size: 11px; font-weight: 700; color: rgba(255,255,255,.68);
  white-space: nowrap;
}
.d-countdown .d-cd-v{
  font-family: var(--font-num);
  font-size: 20px; font-weight: 900; letter-spacing: -.4px;
  color: #fff; font-variant-numeric: tabular-nums;
  white-space: nowrap; line-height: 1.1;
}
.d-countdown .d-cd-v.urgent{ color: #FF9578; text-shadow: 0 0 14px rgba(255,107,74,.45); }
.d-countdown .d-cd-r{
  margin-left: auto; flex: 0 0 auto;
  color: rgba(255,255,255,.44); display: inline-flex;
}
@media (max-width: 640px){
  .d-countdown{ padding: 11px 13px; gap: 7px; }
  .d-countdown .d-cd-v{ font-size: 19px; }
}

/* ============================================================
   ★ V7 · 最后精修
   ============================================================ */

/* ---------- 1. 详情页徽章：真正左右两角（覆盖 padding 干扰） ---------- */
@media (max-width: 900px){
  #view-detail .detail-hero .detail-badges-l{
    position: absolute !important;
    top: 0 !important; bottom: auto !important;
    left: 0 !important; right: auto !important;
    margin: 0 !important; padding: 46px 0 0 16px !important;
    max-width: 58% !important;
    display: flex !important; gap: 6px !important; flex-wrap: wrap !important;
    transform: none !important;
  }
  #view-detail .detail-hero .detail-badges-r{
    position: absolute !important;
    top: 0 !important; bottom: auto !important;
    right: 0 !important; left: auto !important;
    margin: 0 !important; padding: 46px 16px 0 0 !important;
    max-width: 42% !important;
    display: flex !important; gap: 6px !important; flex-wrap: wrap !important;
    justify-content: flex-end !important;
    transform: none !important;
  }
}

/* ---------- 2. 吸底条：按钮改为「复制信息」（详情页底部不再重复咨询） ---------- */
.sticky-ask .btn-copy{
  display: inline-flex; align-items: center; gap: 5px;
  padding: 10px 16px; border-radius: 10px;
  font-size: 14px; font-weight: 800; white-space: nowrap;
  color: #fff; border: 0; cursor: pointer;
  background: linear-gradient(180deg, #5A63A8, #2E3570);
  box-shadow: 0 3px 12px rgba(46,53,112,.34), inset 0 1px 0 rgba(255,255,255,.30);
  transition: transform var(--dur-fast) var(--ease), filter var(--dur-fast) var(--ease);
}
.sticky-ask .btn-copy:hover{ filter: brightness(1.06); }
.sticky-ask .btn-copy:active{ transform: scale(.96); }
.sticky-ask .btn-copy.done{
  background: linear-gradient(180deg, #3DBF7A, #12925A);
  box-shadow: 0 3px 12px rgba(18,146,90,.32), inset 0 1px 0 rgba(255,255,255,.30);
}
.sticky-ask .btn-copy svg{ display: block; }

/* ---------- 3. 详情页底部不再重复「私信咨询」 ---------- */
@media (max-width: 900px){
  #view-detail{ padding-bottom: calc(126px + env(safe-area-inset-bottom)); }
}

/* ============================================================
   V8 补丁：红色角标 + 类型标签
   ============================================================ */

/* ---------- 1. 筛选数字：红字 + 红底块 ---------- */
.chip .chip-n{
  font-style: normal;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 19px; height: 17px; padding: 0 5px;
  border-radius: 5px;
  font-family: var(--font-num);
  font-size: 11px; font-weight: 900; line-height: 1;
  letter-spacing: -.2px;
  color: #E8452A;
  background: #FEECEB;
  font-variant-numeric: tabular-nums;
  transition: background .22s, color .22s;
}
.chip .chip-n.is-zero{
  color: #B0B8C6; background: #F1F4F9;
}
/* 选中态：红底块保持红色，避免和蓝底糊在一起 */
.chip.is-active .chip-n{
  color: #fff; background: rgba(255,255,255,.26);
}
.chip.is-active .chip-n.is-zero{
  color: rgba(255,255,255,.55); background: rgba(255,255,255,.16);
}

/* ---------- 2. 卡片左上：场次数 + 类型 ---------- */
.event-card .cb-tl{
  position: absolute; top: 9px; left: 9px; z-index: 4;
  display: inline-flex; align-items: center; gap: 5px;
  max-width: 62%;
}
.event-card .cb-tl .cb-count{ position: static; top: auto; left: auto; }
.event-card .cb-type{
  display: inline-flex; align-items: center;
  height: 21px; padding: 0 8px; border-radius: 6px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .2px;
  color: #fff;
  background: linear-gradient(180deg, rgba(58,120,227,.94), rgba(46,53,112,.94));
  border: 1px solid rgba(255,255,255,.24);
  backdrop-filter: blur(6px);
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(12,40,100,.28);
}

/* ---------- 3. 详情页类型徽章 ---------- */
.badge.tone-type{
  color: #fff;
  background: linear-gradient(180deg, #5A63A8, #2E3570);
  border: 0;
  box-shadow: 0 2px 10px rgba(46,53,112,.36), inset 0 1px 0 rgba(255,255,255,.28);
}
.badge.tone-type .bdot{ display: none; }

/* ---------- 4. 已结束项目的卡片（后台预览/查询时可见） ---------- */
.event-card.is-expired .card-poster::after{
  content: "已结束";
  position: absolute; inset: 0; z-index: 6;
  display: grid; place-items: center;
  background: rgba(10,18,36,.62);
  color: #fff; font-size: 15px; font-weight: 900; letter-spacing: 2px;
  backdrop-filter: blur(2px);
}

/* ============================================================
   ★ V8.5 · 详情页徽章分角加固
   类型在左、状态在右，各占一角色，窄屏也不换行压标题
   ============================================================ */
.detail-hero .detail-badges-l,
.detail-hero .detail-badges-r{
  flex-wrap: nowrap !important;
}
.detail-hero .detail-badges-l{ max-width: 38% !important; }
.detail-hero .detail-badges-r{
  max-width: 58% !important;
  justify-content: flex-end !important;
}
.detail-hero .detail-badges .badge{
  white-space: nowrap;
  flex: 0 0 auto;
}
/* 标题给徽章留足高度，避免任何情况下被压住 */
.detail-hero .detail-title{ margin-top: 34px; }

@media (max-width: 640px){
  #view-detail .detail-hero .detail-badges-l{ max-width: 34% !important; }
  #view-detail .detail-hero .detail-badges-r{ max-width: 62% !important; }
  .detail-hero .detail-badges .badge{ font-size: 9.5px; padding: 3px 8px; }
}
@media (max-width: 640px){
  .event-card .cb-tl{ top: 7px; left: 7px; gap: 4px; max-width: 64%; }
  .event-card .cb-tl .cb-type{
    height: 19px; font-size: 9.5px; padding: 0 6.5px;
  }
}

/* ============================================================
   ★ 分享入口（首页卡片 + 详情页吸底）
   ------------------------------------------------------------
   以前分享图只能进后台生成，前台一个入口都没有 —— 用户根本找不到。
   现在：首页每张卡片右下角一个「分享」，详情页吸底栏一个「分享」。
   ============================================================ */

/* ---------- 详情页吸底：分享按钮（在复制信息左边） ---------- */
.sticky-ask .btn-share{
  display: inline-flex; align-items: center; gap: 5px;
  padding: 10px 14px; border-radius: 10px;
  font-size: 14px; font-weight: 800; white-space: nowrap;
  color: var(--accent, #2E3570); cursor: pointer;
  background: #EEF4FF;
  border: 1px solid rgba(46,53,112,.28);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6);
  transition: transform .14s var(--ease), filter .14s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.sticky-ask .btn-share svg{ display: block; }
.sticky-ask .btn-share:active{ transform: scale(.96); filter: brightness(.96); }
@media (max-width: 360px){
  .sticky-ask .btn-share span{ display: none; }
  .sticky-ask .btn-share{ padding: 10px 12px; }
}

/* ---------- 首页卡片：底部操作按钮（价格下方独立一行） ---------- */
.card-body{ position: relative; }
.card-acts{
  display: flex; align-items: center; gap: 6px;
  margin-top: 10px;
}
.card-share,
.card-copy{
  display: inline-flex; align-items: center; gap: 4px;
  padding: 7px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 800; line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .14s var(--ease), background .14s var(--ease);
}
.card-share{
  color: var(--accent, #2E3570);
  background: #EEF4FF;
  border: 1px solid rgba(46,53,112,.24);
}
.card-share svg, .card-copy svg{ width: 12px; height: 12px; display: block; }
.card-share:active{ transform: scale(.94); background: #E1EBFF; }
.card-copy{
  color: #5A6B84;
  background: #F2F5FA;
  border: 1px solid rgba(90,107,132,.18);
}
.card-copy:active{ transform: scale(.94); background: #E8EDF5; }
.card-copy.done{ color: #12805C; background: #E7F7F0; border-color: rgba(18,128,92,.28); }

/* ============================================================
   ★ 海报提亮（2026-10）
   ------------------------------------------------------------
   问题：海报底 + .poster-veil(multiply 黑罩) 叠加后整张图发闷，
        粉丝看到暗糊糊一片，没欲望点进去。
   处理：① 砍掉 multiply 黑罩，改用很轻的 bottom-only 渐变，
        只在底部压一点点保证白字可读；
        ② 给海报本体加 saturate/contrast 提亮，颜色更透。
   ============================================================ */
.poster-veil{
  background: linear-gradient(
    to bottom,
    rgba(4,12,30,0) 0%,
    rgba(4,12,30,0) 52%,
    rgba(4,12,30,.34) 100%
  ) !important;
  mix-blend-mode: normal !important;
}
.card-poster .poster-img,
.detail-hero .hero-img{
  filter: saturate(1.12) contrast(1.06) brightness(1.06);
}
/* 卡片封面底色也提亮一档，没图时不至于黑洞洞 */
.card-poster{ --poster-lum: 50%; }

/* ============================================================
   ★ 品牌字（2026-10 简化）
   ------------------------------------------------------------
   之前是「金属釉感」：深蓝实投影 + 顶部高光裁切。
   实际在手机小屏 + 低亮度下，深蓝投影贴着白字会把整体
   压暗成灰色，用户明确反馈「看着是黑的，我要白的」。
   现在改为最干净的纯白字 —— 只留一圈极淡的外发光保持层次，
   不再有任何压暗文字的投影。
   ============================================================ */
[data-theme="blue"] .brand-name,
.topbar .brand-name{
  position: relative;
  color: #fff;
  font-weight: 800;
  letter-spacing: .2px;
  /* 仅保留一圈柔和外发光（在字外，不影响字的亮度），让白字在蓝底上更立体 */
  text-shadow: 0 0 12px rgba(255,255,255,.28);
}
/* 顶部高光已移除：它会把下半截字透出底色，视觉上显灰 */
.topbar .brand-name::after{ content: none; }
/* logo 方块也跟着提亮一档，跟文字一起形成光感 */
[data-theme="blue"] .brand-mark{
  background: linear-gradient(180deg, #6BA0F0, #3E7CE6 62%, #2F63C9);
  box-shadow: 0 4px 14px rgba(4,14,42,.48), 0 1px 2px rgba(4,14,42,.36),
              inset 0 1px 0 rgba(255,255,255,.55),
              0 0 22px rgba(110,165,255,.42);
}

/* ============================================================
   ★ V13 · 详情页倒计时跟随场次 + 场次时间分类
   ------------------------------------------------------------
   背景：一个演出常有 5~10 场，扫码进来的可能是任意一场。
   以前倒计时固定读第一场，切场次数字纹丝不动 → 用户以为坏了。
   现在倒计时绑定当前场次，并把「已结束 / 今天 / N天后」直接
   标在场次按钮上，一眼就能看出该点哪一场。
   ============================================================ */

/* ---------- 1. 场次按钮：加时间标签，已结束置灰 ---------- */
.sess-row{ align-items: stretch; }
.sess-b{
  margin-top: 4px; display: inline-block;
  padding: 1.5px 6px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; line-height: 1.35;
  letter-spacing: .1px; white-space: nowrap;
}
.sess-b.hot   { background: #FEECEC; color: #E8452A; }   /* 今天 / 明天 */
.sess-b.soon  { background: #FFF3E3; color: #B45309; }   /* 7 天内 */
.sess-b.normal{ background: #F0F4FA; color: #5A6B84; }   /* 更远 */
.sess-b.past  { background: #F1F3F6; color: #9AA6B8; }   /* 已结束 */

/* 已结束的场次：整体降透明度 + 日期加删除感的灰字 */
.sess.is-past{ background: #FAFBFC; border-color: #EAEEF3; }
.sess.is-past .sess-d,
.sess.is-past .sess-t{ color: #AEB8C6; }
.sess.is-past:not(.on){ opacity: .78; }
/* 选中一个已结束场次：给个灰色描边，而不是蓝色（避免误导） */
.sess.is-past.on{
  border-color: #C4CCD8; background: #F5F7FA;
  box-shadow: 0 0 0 3px rgba(140,152,170,.12);
}
.sess.is-past.on .sess-d{ color: #7A8598; }

.sess-note-past{ color: #9AA6B8; }

/* ---------- 2. 倒计时条：已结束态 ---------- */
.d-countdown.is-past{
  background: linear-gradient(135deg, #6B7688, #525C6B);
  box-shadow: 0 4px 16px rgba(82,92,107,.22), inset 0 1px 0 rgba(255,255,255,.14);
}
.d-countdown.is-past .d-cd-l{ color: rgba(255,255,255,.70); }
.d-countdown.is-past .d-cd-v{
  font-size: 17px; letter-spacing: 0;
  color: rgba(255,255,255,.88);
}
/* 倒计时数字在 HTML 里就渲染好，不需要占位显隐（曾用 placeholder 藏 -- ，
   结果用户看到「只有蓝条没有数字」，已移除） */

/* ---------- 3. 扫码落地：给落地卡片一个高亮呼吸，告诉用户"就是这条" ---------- */
.event-card.card-landed{
  animation: cardLandedPulse 1.5s var(--ease, ease) 1;
}
@keyframes cardLandedPulse{
  0%   { box-shadow: 0 0 0 0 rgba(46,53,112,.34); }
  55%  { box-shadow: 0 0 0 7px rgba(46,53,112,0); }
  100% { box-shadow: 0 0 0 0 rgba(46,53,112,0); }
}
@media (prefers-reduced-motion: reduce){
  .event-card.card-landed{ animation: none; }
}

@media (max-width: 640px){
  .sess{ min-width: 86px; padding: 8px 11px; }
  .sess-b{ font-size: 9px; padding: 1px 5px; }
}

/* ============================================================
   ★ 体验打磨层（2026-10）
   ------------------------------------------------------------
   目标：让每个操作都有「回应感」。
   · 切页有过渡（不再硬切）
   · 筛选不跳动（列表占位兜住）
   · 按下有实感（active 缩放）
   · 长列表能快速回顶
   · 弱网不塌陷（骨架位）
   · 尊重 prefers-reduced-motion
   ============================================================ */

/* ---------- ① 页面视图过渡：列表 ↔ 详情 ↔ 说明 ---------- */
/* 用 animation 而不是 transition，因为视图是 display 切换的 */
/* ★ 一律用 backwards：both 会永久保留 transform 层，
   使 #view-detail 变成 position:fixed 的包含块，
   导致详情页吸底栏在页面顶部时被推到屏幕外（实测 top:1038 > 视口高 844）。 */
.view-anim-in{
  animation: viewIn .26s cubic-bezier(.22,.61,.36,1) backwards;
}
@keyframes viewIn{
  from{ opacity: 0; transform: translateY(9px); }
  to{ opacity: 1; transform: none; }
}
/* 详情页从右侧滑入：符合「进入下一层」的心理模型 */
#view-detail.view-anim-in{ animation: detailSlideIn .3s cubic-bezier(.22,.61,.36,1) backwards; }
@keyframes detailSlideIn{
  from{ opacity: 0; transform: translateX(26px); }
  to{ opacity: 1; transform: none; }
}

/* ---------- ② 筛选切换：列表不跳动 ---------- */
/* 切分类/搜索时先冻住当前高度，新内容落位后再释放，
   避免「先塌陷再撑开」的跳动感 */
#cardGrid{
  min-height: 120px;
  transition: min-height .22s var(--ease-out);
}
/* 筛选切换时卡片重播一次轻盈淡入（不是入场位移，避免"整页在跳"） */
#cardGrid.is-refilter .event-card{
  animation: cardSoftIn .3s var(--ease-out) both;
}
@keyframes cardSoftIn{
  from{ opacity: 0; transform: translateY(6px); }
  to{ opacity: 1; transform: none; }
}

/* ---------- ③ 按下反馈：手机上「按到了」的实感 ---------- */
@media (hover: none){
  .event-card:active{ transform: translateY(-2px) scale(.978); }
  .chip:active{ transform: scale(.94); }
  .sort-tab:active{ transform: scale(.95); }
  .city:active{ transform: scale(.94); }
}
/* 卡片按压时同步收紧阴影，视觉上"压下去" */
.event-card:active{
  box-shadow: 0 2px 10px rgba(15,30,80,.10);
}

/* ---------- ④ 返回顶部 ---------- */
.back-top{
  position: fixed; right: 16px; z-index: 60;
  width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--accent);
  border: 1px solid var(--border);
  box-shadow: 0 6px 22px rgba(15,30,80,.16);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  opacity: 0; visibility: hidden; transform: translateY(10px) scale(.9);
  transition: opacity .26s var(--ease-out), transform .26s var(--ease-out), visibility .26s;
}
.back-top.show{ opacity: 1; visibility: visible; transform: none; }
.back-top:active{ transform: scale(.9); }
.back-top svg{ width: 19px; height: 19px; }
/* 底部有双 Tab 栏，浮层要抬起来一点 */
@media (max-width: 720px){
  .back-top{ right: 14px; bottom: calc(68px + env(safe-area-inset-bottom, 0px) + 14px); }
}
@media (min-width: 721px){
  .back-top{ bottom: 28px; }
}

/* ---------- ⑥ 详情大图骨架位 ---------- */
/* 图没到时先占住高度 + 一层微光扫过，避免"白一下"再撑开 */
.detail-hero .hero-img{
  opacity: 0; transition: opacity .34s var(--ease-out);
}
.detail-hero .hero-img.is-ready{ opacity: 1; }
.hero-skeleton{
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(100deg,
    hsl(var(--h,260) var(--poster-sat) 46% / .55) 0%,
    hsl(var(--h,260) var(--poster-sat) 58% / .38) 42%,
    hsl(var(--h,260) var(--poster-sat) 46% / .55) 100%);
  background-size: 220% 100%;
  animation: skeletonSweep 1.5s ease-in-out infinite;
}
@keyframes skeletonSweep{
  0%{ background-position: 120% 0; }
  100%{ background-position: -120% 0; }
}
.detail-hero:has(.hero-img.is-ready) .hero-skeleton{ display: none; }

/* ---------- ⑨ 首屏海报骨架位（列表卡片） ---------- */
/* 卡片海报区已有 .card-poster 兜底渐变，这里补一层"呼吸"
   让加载中的卡看起来是在工作、而不是卡住 */
.card-poster .poster-fallback[data-loading="1"]::after{
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.16) 50%, transparent 70%);
  background-size: 220% 100%;
  animation: skeletonSweep 1.5s ease-in-out infinite;
}

/* ---------- 空状态：更"会说话" ---------- */
/* 关键词回显 + 热门分类快捷入口 */
.empty .empty-kw{ color: var(--accent); font-weight: 700; }
.empty-hot{
  display: flex; align-items: center; justify-content: center;
  gap: 8px; flex-wrap: wrap; margin-bottom: 20px;
}
.empty-hot .eh-lb{ font-size: 12.5px; color: var(--text-faint); width: 100%; margin-bottom: 2px; }
.empty-hot .eh-btn{
  font-size: 13px; padding: 7px 15px; border-radius: 20px;
  background: var(--surface-strong); color: var(--text);
  border: 1px solid var(--border); cursor: pointer;
  transition: transform .18s var(--ease), background .18s var(--ease), color .18s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.empty-hot .eh-btn:hover{ background: var(--accent-soft); color: var(--accent); }
.empty-hot .eh-btn:active{ transform: scale(.94); }

/* 空状态整体浮现 */
#view-home .empty:not([hidden]){ animation: emptyIn .34s var(--ease-out) both; }
@keyframes emptyIn{
  from{ opacity: 0; transform: translateY(8px); }
  to{ opacity: 1; transform: none; }
}

/* ---------- 状态徽章呼吸感（很轻，一眼扫到但不晃眼） ---------- */
/* 只给「在售」类徽章，下架的不动 */
.badge.tone-ok{ animation: badgeBreath 2.6s ease-in-out infinite; }
@keyframes badgeBreath{
  0%, 100%{ box-shadow: 0 0 0 0 rgba(23,160,106,.42); }
  55%{ box-shadow: 0 0 0 5px rgba(23,160,106,0); }
}

/* ---------- 详情页顶部悬浮返回 ---------- */
/* 滚动后返回键变成毛玻璃浮层，不再是一根死条 */
.btn-back{
  transition: background .26s var(--ease-out), box-shadow .26s var(--ease-out),
              color .26s var(--ease-out), transform .26s var(--ease-out);
}
/* ★ 注意三个坑：
   ① 移动端有 `#view-detail .btn-back{ position:absolute }`（ID 选择器），
      权重高于纯 class，所以这里必须同样带上 #view-detail 才能压过去。
   ② 不能用 position:fixed 留在 .detail 内 —— .detail 带 `animation: detailIn ... both`，
      fill-mode 会永久保留 transform 层，使它成为 fixed 的包含块，
      top 会算成相对 .detail 的位置（实测被顶到 -262px，直接滚没了）。
   ③ 也不能用 position:sticky —— sticky 仍占文档流，会把详情内容整体下推，
      滚到底时页脚被底部双 Tab 栏遮住（实测 -40px）。
   最终方案：fixed + 由 JS 把它挂到 body 下（脱离 .detail 的包含块），
   这样既不回流、又能正确定位到视口顶部。 */
#view-detail .btn-back.is-float,
.btn-back.is-float{
  position: fixed; top: 12px; left: 14px; z-index: 90;
  margin: 0; padding: 8px 15px; font-size: 13px;
  width: fit-content;
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--accent);
  background: rgba(255,255,255,.82);
  border: 1px solid rgba(255,255,255,.6);
  border-radius: 20px;
  text-shadow: none;
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  box-shadow: 0 4px 18px rgba(15,30,80,.18);
  animation: backFloatIn .28s cubic-bezier(.22,.61,.36,1) both;
}
@keyframes backFloatIn{
  from{ opacity: 0; transform: translateY(-8px); }
  to{ opacity: 1; transform: none; }
}
#view-detail .btn-back.is-float svg{ filter: none; }
[data-theme="aurora"] .btn-back.is-float,
[data-theme="neon"] .btn-back.is-float{
  background: rgba(22,26,40,.72); color: #fff;
}

/* ---------- ⑧ 减弱动态效果：全局收敛 ---------- */
@media (prefers-reduced-motion: reduce){
  .view-anim-in,
  #view-detail.view-anim-in,
  #view-home .empty:not([hidden]){
    animation: none !important;
  }
  .hero-skeleton,
  .card-poster .poster-fallback[data-loading="1"]::after,
  .badge.tone-ok{ animation: none !important; }
  .back-top{ transition: opacity .2s, visibility .2s; transform: none; }
  .btn-back.is-float{ animation: none !important; }
  .event-card,
  .chip,
  .sort-tab,
  .city,
  .eh-btn{ transition-duration: .001s !important; }
  html{ scroll-behavior: auto !important; }
}

/* ============================================================
   ★ 兜底层状态标识（2026-10）
   ------------------------------------------------------------
   问题：兜底层原本是「品牌色渐变 + 首字母」，看起来跟一张正常海报
         没区别。用户看到后以为"这站的图就长这样"，而实际上是图没加载出来。
   做法：保留品牌色底（不破坏视觉），但在上面加一个清楚的状态标签：
         · 加载中 → 转圈 + 「图片加载中」
         · 加载失败 → 「图片加载失败」+ 可点击重试
   这样一眼就能分清"图挂了"和"本来就这样"。
   ============================================================ */

/* 状态标签容器：底部居中 */
.poster-fallback .pf-status{
  position: absolute; z-index: 3;
  left: 50%; bottom: 10px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 20px;
  background: rgba(6,14,36,.42);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: rgba(255,255,255,.92);
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
  white-space: nowrap; pointer-events: none;
  max-width: calc(100% - 20px);
}
/* 加载中转圈 */
.poster-fallback .pf-spin{
  width: 9px; height: 9px; border-radius: 50%;
  border: 1.6px solid rgba(255,255,255,.32);
  border-top-color: rgba(255,255,255,.95);
  animation: pfSpin .7s linear infinite;
  flex-shrink: 0;
}
@keyframes pfSpin{ to{ transform: rotate(360deg); } }

/* 失败态：可点击重试 */
.poster-fallback.is-failed .pf-status{
  pointer-events: auto; cursor: pointer;
  background: rgba(150,26,32,.62);
  transition: background .2s;
}
.poster-fallback.is-failed .pf-status:active{ background: rgba(150,26,32,.82); }
.poster-fallback.is-failed .pf-status::after{
  content: '重试'; margin-left: 2px; padding-left: 6px;
  border-left: 1px solid rgba(255,255,255,.34);
  font-weight: 800;
}

/* 详情页大图兜底：同样加状态（但不加点击重试，避免跟返回键抢） */
.detail-hero .poster-fallback .pf-status{ bottom: 14px; }

/* 减弱动效：不转圈 */
@media (prefers-reduced-motion: reduce){
  .poster-fallback .pf-spin{ animation: none; }
}

/* ============================================================
   ★ 离线数据提示条（2026-10）
   ------------------------------------------------------------
   背景：云端连不上时，页面会静默回落到本地备份数据。
        以前没有任何提示 —— 「为什么我看到的价格是旧的」这类问题
        非常难查，因为页面悄悄用了备份，看起来一切正常。
   做法：明确告知 + 提供重试。宁可让用户知道"现在是离线"，
        也不要让他拿着旧数据以为是实时价。
   ============================================================ */
.offline-bar{
  position: fixed; left: 50%; transform: translateX(-50%);
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  z-index: 55;
  display: flex; align-items: center; gap: 8px;
  max-width: calc(100vw - 28px);
  padding: 8px 8px 8px 13px;
  border-radius: 22px;
  background: rgba(58,38,4,.90);
  color: #FFE9C2;
  font-size: 12.5px; font-weight: 600; line-height: 1.3;
  box-shadow: 0 6px 24px rgba(20,12,0,.28);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  backdrop-filter: saturate(160%) blur(10px);
  animation: offlineIn .32s cubic-bezier(.22,.9,.36,1) both;
}
@keyframes offlineIn{
  from{ opacity: 0; transform: translate(-50%, -12px); }
  to{ opacity: 1; transform: translate(-50%, 0); }
}
.offline-bar .ob-ic{ display: inline-flex; flex-shrink: 0; opacity: .9; }
.offline-bar .ob-tx{
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.offline-bar .ob-btn{
  flex-shrink: 0; cursor: pointer;
  padding: 5px 12px; border: 0; border-radius: 16px;
  background: rgba(255,233,194,.94); color: #3A2604;
  font-size: 12px; font-weight: 800;
  transition: transform .16s var(--ease), background .16s;
  -webkit-tap-highlight-color: transparent;
}
.offline-bar .ob-btn:active{ transform: scale(.93); }
.offline-bar.is-busy .ob-btn{ opacity: .55; pointer-events: none; }

/* 详情页时顶栏隐藏，提示条位置不变（它自己 fixed 在视口顶部） */

@media (prefers-reduced-motion: reduce){
  .offline-bar{ animation: none; }
}
