/* ==========================================================================
   购票端 H5 样式
   ★★ 与参考项目的 H5 UI **逐字对齐**：本节只保留 H5 的**外壳**（根容器 / 顶栏 /
      tabbar），组件样式全部来自末尾的 PREVIEW-PORT 层（px 原值，与预览稿一致）。
   ★ 页面里禁止硬编码色值，一律用 var(--xxx)；禁止再新建 css 文件。
   ========================================================================== */
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;background:var(--route-bg);color:var(--ink);
  font-family:"PingFang SC","Microsoft YaHei",-apple-system,BlinkMacSystemFont,sans-serif;
  font-size:14px;-webkit-font-smoothing:antialiased}
a{text-decoration:none;color:inherit}
button{font:inherit;color:inherit;cursor:pointer}
img{max-width:100%;display:block}

/* ★★ 移动优先，桌面端居中手机列。
   设计基准 375px；真机普遍 390~430px，固定 375px + 居中会在左右各多出灰边。 */
.h5-root{max-width:100%;margin:0 auto;min-height:100vh;background:var(--route-bg);
  position:relative;padding-bottom:0}
@media (min-width:480px){ .h5-root{max-width:375px;box-shadow:0 0 24px rgba(0,0,0,.08)} }

.h5-main{padding:0}

/* ---------- 底部 tabbar（1:1 对齐预览稿）----------
   height:76px（含 24px 安全区）+ border-top:1px solid #e8e8e8
   + 图标 24×24 + 文字 10px/14px + 未选 #7a7a80 / 选中 #000
   ★ 同时支持 `.tabbar` + [aria-current=page]（预览稿写法）与
     `.h5-tabbar` + `.h5-tab.active`（兼容），两者样式完全一致。 */
.tabbar,.h5-tabbar{position:fixed;left:50%;transform:translateX(-50%);bottom:0;
  width:100%;max-width:375px;height:76px;background:var(--white);
  border-top:1px solid #e8e8e8;display:grid;grid-template-columns:repeat(4,1fr);z-index:30;
  padding-bottom:24px}
@media (max-width:479px){ .tabbar,.h5-tabbar{max-width:100%} }
.tabbar a,.tabbar button,.h5-tab{display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:3px;border:0;background:transparent;text-decoration:none;
  color:#7a7a80;font-size:10px;line-height:14px;padding:0;position:relative;
  -webkit-tap-highlight-color:transparent;cursor:pointer}
.tabbar svg,.h5-tab .tab-ico svg,.h5-tab .tab-ico img{width:24px;height:24px;display:block;color:#7a7a80}
.tabbar a[aria-current=page],.tabbar button[aria-current=page],.h5-tab.active{color:#000}
.tabbar a[aria-current=page] svg,.tabbar button[aria-current=page] svg,
.h5-tab.active .tab-ico svg,.h5-tab.active .tab-ico img{color:#000}

/* ★★★ H5 顶部留白修正（用**高特异性**，不依赖文件顺序去覆盖移植层）
   ★★ 这条规则**很容易被误当成死样式删掉**：预览稿的 `.page{padding:78px 0 24px}` 里的
      78px 是为了避开**预览手机框里模拟的 iOS 状态栏(45px) + 微信胶囊按钮** ——
      那是预览外壳的画法。真实 H5 的 webview **不包含状态栏**，而且我们已经有真实的
      `.route-header`（48px sticky）。若照搬 78px，页面顶部会多出一大块空白。
   → 因此 H5 侧统一把顶部内边距归零，由 `.route-header` 承担顶部定位。 */
body .h5-root .page{padding-top:0}
/* ★ 首页 hero 是贴顶的全宽图，也不需要 78px */
body .h5-root .page > .home-hero:first-child{margin-top:0}

.tips{margin:0;padding-left:18px;color:var(--muted);font-size:var(--font-caption);line-height:1.9}
.tips code{background:var(--paper);padding:1px 5px;border-radius:4px;color:var(--ok)}

/* 状态标签（旧类名，保留兼容；新页面请用 .tag） */
.status-tag{display:inline-block;height:22px;line-height:22px;padding:0 8px;
  border-radius:var(--radius-tag);font-size:var(--font-tiny);background:var(--paper);color:var(--muted)}
.status-tag.ok{background:#E8F8F1;color:var(--ok)}
.status-tag.wait{background:#FDF4E7;color:var(--warn)}
.status-tag.no{background:#FDEDEB;color:var(--danger)}

/* ==== SHARED-UIKIT v1 ==== */
/* --------------------------------------------------------------------------
   共享组件库 —— ★ 页面请直接复用这些类名，不要再新建 css 文件
   -------------------------------------------------------------------------- */

/* 列表 */
.list-item{display:flex;align-items:flex-start;gap:12px;padding:14px var(--page-padding);
  border-bottom:1px solid var(--line);position:relative}
.list-item:last-child{border-bottom:0}
.list-item.tap:active{background:#FAFAFB}
.li-main{flex:1;min-width:0}
.li-title{font-size:var(--font-card-title);color:var(--ink);font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.li-sub{font-size:var(--font-caption);color:var(--muted);margin-top:5px;line-height:1.7}
.li-sub.warn{color:var(--warn)}
.li-sub.danger{color:var(--danger)}
.li-right{text-align:right;flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:6px}

/* 区块标题 */
.sec-title{font-size:var(--font-caption);color:var(--secondary);margin:16px 2px 8px}
.sec-title:first-child{margin-top:2px}

/* 通用行 */
.row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:7px 0;
  font-size:var(--font-body)}

.btn-primary:disabled,.btn-ghost:disabled,.btn-danger:disabled,
.btn-primary.is-disabled,.btn-ghost.is-disabled,.btn-danger.is-disabled{opacity:.45;cursor:not-allowed}

/* 状态标签扩展 */
.status-tag.sub{background:var(--paper);color:var(--secondary)}
.status-tag.info{background:#EDF3FE;color:var(--blue)}
.status-tag.dark{background:var(--ink);color:#fff}

/* 进度条 */
.progress{height:8px;border-radius:4px;background:var(--line);overflow:hidden}

/* 空态 / 加载态 */
.empty-state{text-align:center;padding:60px 0;color:var(--secondary);font-size:var(--font-caption)}
.empty-state .e-ico{width:64px;height:64px;border-radius:16px;background:var(--line);
  margin:0 auto 14px;display:block}
.loading{display:flex;align-items:center;justify-content:center;gap:8px;padding:46px 0;
  color:var(--secondary);font-size:var(--font-caption)}
.spin{width:16px;height:16px;border:2px solid var(--line);border-top-color:var(--yellow);
  border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* 通用 */
.muted{color:var(--muted)}
.hint{color:var(--secondary);font-size:var(--font-tiny);line-height:1.75}
.strong{font-weight:600;color:var(--ink)}
.mono{font-family:ui-monospace,Consolas,monospace}
.center{text-align:center}
.right{text-align:right}
[hidden]{display:none !important}
.banner{background:linear-gradient(135deg,var(--yellow-soft),var(--yellow));
  border-radius:var(--radius-card);padding:20px var(--page-padding);color:#3A3400}

/* ==== SHARED-COMPONENTS v1 ==== */
/* 票卡片（TicketCard）：票号打码 + 状态 + 原因 */
.ticket-card{background:var(--white);border-radius:var(--radius-card);
  padding:var(--page-padding);margin-top:var(--card-gap)}

/* 订单卡片（OrderCard） */
.order-card{background:var(--white);border-radius:var(--radius-card);
  padding:var(--page-padding);margin-top:var(--card-gap)}
.order-card .oc-head{display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.order-card .oc-no{font-size:var(--font-caption);color:var(--secondary);
  font-family:ui-monospace,Consolas,monospace}
.order-card .oc-body{padding:10px 0}
.order-card .oc-foot{display:flex;align-items:center;justify-content:flex-end;gap:8px;
  padding-top:10px;border-top:1px solid var(--line)}
/* ★★ 2026-10-03 用户口径改写（原来这条是"合计红字 15px + margin-right:auto"）：
   ① 合计金额从 .oc-foot 挪到 .oc-goods 行尾（与票品缩略图同一行）→ 用 margin-left:auto 贴右，
      并把原来的 margin-right:auto 归零（那是给"合计在左、按钮在右"的旧排布用的）
   ② 「合计」= 黑(--ink) + 小字(--font-caption 12.5px)；金额 = 红(--danger) + 大字(--font-title 18px)
      ★ 18px 而非 --font-body(14px)：14 与 12.5 只差 1.5px 看不出主次；18px 与站内其它金额同档
   ③ 这组规则写在组件层而不是页面 <style>：ui_lint 明确要求组件类的覆盖留在组件层，
      页面里重定义会报"重新定义了组件类 .oc-total"（实测 2 条告警）。
      .oc-* 只有订单列表（/h5/order/index）一个消费者，改这里等价且不伤别处。 */
.order-card .oc-total{flex:none;margin-left:auto;margin-right:0;white-space:nowrap;text-align:right;
  font-size:var(--font-caption);font-weight:400;color:var(--ink);font-variant-numeric:tabular-nums}
.order-card .oc-total b{font-size:var(--font-title);font-weight:700;color:var(--danger);margin-left:5px}

/* 商品卡片（GoodsCard） */
.goods-card{background:var(--white);border-radius:var(--radius-card);
  padding:var(--page-padding);margin-top:var(--card-gap);display:flex;gap:12px}

/* ==== SHARED-ALERTS v1 ==== */
/* --------------------------------------------------------------------------
   ★★ 权威提示条定义（唯一处，不要在视图 <style> 里重复定义这些类）
   ★ 用法：<div class="alert alert-warn">…</div>
   -------------------------------------------------------------------------- */
.alert{background:var(--white);border:1px solid var(--line);border-left:4px solid var(--blue);
  border-radius:var(--radius-btn);padding:10px 12px;margin-top:var(--card-gap);
  font-size:var(--font-caption);line-height:1.85;color:var(--title)}
.alert b,.alert .strong{color:var(--ink);font-weight:600}
.alert .lock{color:var(--danger);font-weight:600}

.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}

/* 通用：合计/标签行 */
.total{font-weight:700;color:var(--ink)}
.meta{font-size:var(--font-tiny);color:var(--secondary);line-height:1.75}

/* ==========================================================================
   ★★★ PREVIEW-PORT v1（px）—— 权威组件层，取值与预览稿逐字一致
   注意：这一段 `:root{}` 把令牌**又声明了一遍**，而 h5.css 在 tokens.css 之后加载，
   所以**这里才是真正生效的那份**。改配色两处都要改。
   ========================================================================== */
:root{
  --paper:#f8f9fc;
  --route-bg:#F5F6F9;
  --yellow:#ffe706;
  --ink:#000;
  --title:#26292e;
  --secondary:#999;
  --muted:#777b83;
  --line:#f0f1f3;
  --danger:#e65445;
  --white:#fff;
  --ok:#0b7a54;
  --warn:#9a5a05;
  --blue:#1b4cb0;
}
*{ box-sizing:border-box }
html,body{ margin:0;min-height:100%;font-family:"PingFang SC","Microsoft YaHei",-apple-system,BlinkMacSystemFont,sans-serif;color:var(--ink) }
button{ font:inherit;color:inherit;cursor:pointer }
button:focus-visible{ outline:2px solid #3866cc;outline-offset:2px }
.tabbar{ height:76px;position:fixed;left:50%;transform:translateX(-50%);bottom:0;width:100%;max-width:375px;background:#fff;border-top:1px solid #e8e8e8;display:grid;grid-template-columns:repeat(4,1fr);z-index:30;padding-bottom:24px }
.tabbar[hidden]{ display:none }
.tabbar button{ display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;border:0;background:transparent;font-size:10px;line-height:14px;padding:0 }
.tabbar svg{ width:24px;height:24px;display:block;color:#7a7a80 }
.tabbar button[aria-current=page]{ color:#000 }
.tabbar button[aria-current=page] svg{ color:#000 }
svg.i{ display:block;flex:none }
.page{ min-height:100%;background:var(--route-bg);padding:0 0 24px }
.page.white{ background:#fff }
.route-header{ height:48px;display:flex;align-items:center;padding:0 15px;gap:16px;background:#fff;border-bottom:1px solid var(--line) }
.back-button{ width:24px;height:40px;display:flex;align-items:center;justify-content:center;flex:none;border:0;background:transparent;padding:0;margin-left:-4px;border-radius:50% }
.back-button:active{ background:#f2f3f5 }
.home-hero{ height:200px;background:#ececec;position:relative }
.home-hero>img{ width:100%;height:100%;object-fit:cover }
.home-content{ background:var(--paper);border-radius:20px 20px 0 0;margin-top:-15px;position:relative;padding-top:11px }
.marquee{ height:30px;margin:0 var(--page-gutter) 4px;background:#fff8d6;border-radius:8px;display:flex;align-items:center;gap:7px;padding:0 11px;font-size:12px;color:#8a6d00;overflow:hidden;white-space:nowrap }
.marquee svg{ color:#c9a227 }
.menu-grid{ display:grid;grid-template-columns:repeat(4,1fr);text-align:center }
.menu-grid button{ border:0;background:transparent;min-height:83px;font-size:11px;padding:9px 0;color:var(--title) }
.menu-grid .ico{ width:44px;height:44px;border-radius:14px;display:grid;place-items:center;margin:0 auto 7px }
.ticket-card{ display:flex;gap:12px;padding:12px 0;border-bottom:1px solid #eceef1;background:transparent;width:100%;text-align:left;border-left:0;border-right:0;border-top:0 }
.ticket-card:last-child{ border-bottom:0 }
.ticket-card>img{ width:96px;height:96px;border-radius:9px;object-fit:cover;flex:none }
.section-head{ display:flex;justify-content:space-between;align-items:flex-end;margin:16px 0 4px }
.section-head h2{ font-size:18px;margin:0 }
.section-head small{ font-size:11px;color:var(--secondary) }
.buy-bar{ position:fixed;left:0;right:0;bottom:0;background:#fff;border-top:1px solid var(--line);padding:10px 15px 14px;display:flex;align-items:center;gap:10px;z-index:30 }
.buy-bar .sum{ flex:1;font-size:12px;color:var(--muted) }
.buy-bar .sum b{ display:block;color:var(--danger);font-size:20px;font-weight:600 }
.btn-main{ border:0;border-radius:24px;background:var(--yellow);padding:0 26px;height:46px;font-size:15px;font-weight:500;color:var(--ink) }
.btn-main:disabled{ background:#e8e9ec;color:#a9adb5 }
.btn-ghost{ border:1px solid var(--line);border-radius:24px;background:#fff;padding:0 20px;height:46px;font-size:14px }
.list{ padding:14px var(--page-gutter) 0 }
.page>.card{ margin-left:var(--page-gutter);margin-right:var(--page-gutter) }
.card{ --card-pad:15px;background:#fff;border-radius:10px;padding:var(--card-pad);margin:12px 0 }
.card h2{ font-size:15px;margin:0 0 8px }
/* --------------------------------------------------------------------------
   ★ 卡片标题带（GLOBAL-CARD-HEAD v2）
   卡片若**以 <h2> 打头**，这个 h2 就自动变成「标题带」：卡片顶部一行小字标题，
   左右用负外边距顶到卡片边（这样它才能左右贯通、并被卡片圆角裁住）。
   ★ 标题带底色为**白色**，与卡片同色 —— 所以「板块之间要分开」改由
     「卡片边界」承担：页面底色 --route-bg + --page-gutter 留白 + 卡片间隙。
     留下 1px 下边线只是为了把「标题行」与「正文」分开，不是为了分板块。
   ★ --card-pad 变量：负边距必须**精确等于**卡片内边距，否则标题带会溢出/露白。
     弹窗里 `.card{padding:0}` 的页面必须顺手把 --card-pad 也置 0。
   -------------------------------------------------------------------------- */
.blk-hd,
.card > h2:first-child{
  background:#fff;border-bottom:1px solid #EEF0F4;
  padding:9px var(--card-pad,15px);
  font-size:12.5px;font-weight:600;color:#5b6472;line-height:1.5 }
.blk-hd{ display:flex;align-items:center;justify-content:space-between }
.card > h2:first-child{
  margin: calc(-1 * var(--card-pad)) calc(-1 * var(--card-pad)) 10px;
  border-radius:var(--radius-card) var(--radius-card) 0 0 }
.card > h2:first-child a{ font-size:12px;font-weight:400;color:var(--secondary) }
.card p{ font-size:13px;color:var(--muted);margin:5px 0;line-height:1.6 }
.card .kv{ display:flex;justify-content:space-between;font-size:13px;padding:7px 0;border-bottom:1px solid var(--line) }
.card .kv:last-child{ border-bottom:0 }
.card .kv span:first-child{ color:var(--secondary) }
.row-button{ display:flex;align-items:center;gap:12px;width:100%;border:0;background:#fff;border-radius:9px;padding:15px;margin:9px 0;text-align:left;font-size:14px }
.row-button .grow{ flex:1 }
.row-button .hint{ font-size:12px;color:var(--secondary) }
.full-btn{ border:0;background:var(--yellow);border-radius:25px;width:100%;height:46px;margin-top:16px;font-size:15px;font-weight:500;color:var(--ink) }
.tabs{ display:flex;background:#fff;border-radius:8px;overflow:hidden }
.tabs button{ border:0;background:transparent;padding:12px 6px;font-size:12px;flex:1 }
.tabs button.active{ border-bottom:3px solid var(--yellow);font-weight:500 }
.empty{ text-align:center;color:#a3a6ad;font-size:13px;padding-top:120px }
.empty svg{ margin:0 auto 12px;color:#d3d6dc }
.order-card{ background:#fff;margin-top:12px;padding:14px;border-radius:10px;width:100%;text-align:left;border:0 }
.order-card .of{ display:flex;justify-content:space-between;align-items:center;margin-top:11px;padding-top:11px;border-top:1px solid var(--line);font-size:12px;color:var(--secondary) }
.tag{ display:inline-block;font-size:10px;padding:2px 7px;border-radius:5px;background:#f0f2f5;color:#6b7078 }
.tag.ok{ background:#e6f7f1;color:#0b7a54 }
.tag.wait{ background:#fff4e0;color:#9a5a05 }
.tag.no{ background:#fdedeb;color:#b32e1f }
.tag.info{ background:#eaf1fe;color:#1b4cb0 }
.tag.dark{ background:var(--ink);color:#fff }
.field{ height:48px;border:1px solid #eee;border-radius:30px;padding:0 15px;display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;color:#b5b8c1;font-size:15px;background:#fff }
.field input{ border:0;outline:0;background:transparent;font:inherit;color:#232323;min-width:0;flex:1 }
.field button{ background:var(--yellow);border:0;border-radius:20px;height:34px;padding:0 14px;font-size:13px;flex:none;color:#000 }
.me-content{ padding:0 var(--page-gutter);padding-top:73px;min-height:100% }
.user{ height:75px;display:flex;align-items:center;gap:10px }
.avatar{ width:70px;height:70px;border-radius:50%;border:2px solid #fff;background:#dedede;position:relative;overflow:hidden;flex:none }
.avatar:before{ content:"";position:absolute;width:26px;height:27px;border-radius:50%;background:#fff;top:9px;left:20px }
.avatar:after{ content:"";position:absolute;width:46px;height:28px;background:#fff;border-radius:50% 50% 10% 10%;top:42px;left:10px }
.username{ font-size:16px;line-height:22px }
.username small{ display:block;font-size:11px;color:var(--secondary);margin-top:3px }
.me-order,.me-more{ background:#fff;border-radius:10px }
.order-grid{ display:grid;grid-template-columns:repeat(4,1fr);margin-top:6px }
.order-grid button{ border:0;background:transparent;height:49px;display:flex;flex-direction:column;align-items:center;justify-content:space-between;font-size:12px;white-space:nowrap;padding:0;color:var(--title) }
.me-more{ margin-top:17px;padding:14px 10px }
.me-more h2{ font-size:16px;font-weight:400;line-height:22px;margin:0 0 7px }
.me-more button{ border:0;background:transparent;width:100%;height:44px;display:flex;align-items:center;gap:15px;text-align:left;padding:0;font-size:14px;color:var(--title) }
.me-more button .grow{ flex:1 }
.me-more.compact{ margin-top:9px;padding-top:12px;padding-bottom:17px }
.asset{ display:grid;grid-template-columns:repeat(3,1fr);background:#fff;border-radius:10px;margin-top:12px;padding:14px 0;text-align:center }
.asset b{ display:block;font-size:17px;color:var(--title) }
.asset span{ font-size:11px;color:var(--secondary) }
.asset small{ display:block;font-size:10px;color:#b9bcc2;margin-top:2px }
/* 提示条：黄底警示（预览稿口径）。语义变体见 .notice-ok / -danger / -plain / -info */
.notice{ background:#fff4e0;border:1px solid #f6ddae;border-radius:9px;padding:11px 13px;font-size:12px;color:#9a5a05;line-height:1.7;margin-top:12px }
.notice-ok{ background:var(--ok-soft);border-color:#bbf7d0;color:var(--ok-deep) }
.notice-danger{ background:var(--danger-soft);border-color:#f7c9c3;color:var(--danger-deep) }
.notice-plain{ background:var(--fill-light);border-color:var(--line);color:var(--muted) }
.notice-info{ background:var(--blue-soft);border-color:#c7d9fb;color:var(--blue-deep) }
.modal{ position:fixed;inset:0;background:#0006;z-index:9000;display:grid;place-items:center;padding:36px }
.modal[hidden]{ display:none }
.modal .box{ background:#fff;border-radius:16px;overflow:hidden;width:100%;max-width:280px }
.modal .box img{ width:100%;height:130px;object-fit:cover;display:block }
.modal .box .b{ padding:16px }
.modal .box h3{ margin:0 0 8px;font-size:16px }
.modal .box p{ margin:0;font-size:12.5px;color:var(--muted);line-height:1.7 }
.modal .box .ok{ margin-top:14px;width:100%;height:42px;border:0;border-radius:21px;background:var(--yellow);font-size:14px }
/* ★ 2026-10-04 新增：弹窗**次要按钮**（如定位说明里的「暂不」）。
   此前只有 .ok（黄色主按钮），次要动作没有对应类，一写就是浏览器默认按钮的样子
   —— 实测截图里「暂不」是个没样式的小方块，和主按钮完全不成套。 */
.modal .box .cancel{ margin-top:8px;width:100%;height:42px;border:1px solid var(--line);border-radius:21px;
  background:#fff;color:var(--secondary);font-size:14px }
/* ★ 2026-10-04 用户口径：弹窗里的两个动作**同一行**，尺寸形状完全一致，只用颜色分主次。
   （原来主按钮整宽、次按钮另起一行还只有个小方块，视觉上不成套。） */
.modal .box .acts{ display:flex;gap:10px;margin-top:14px }
.modal .box .acts .ok,.modal .box .acts .cancel{ flex:1;width:auto;margin-top:0 }
/* ★ 主按钮也要有**同样宽度**的边框，否则在 flex 下会比次按钮宽/窄 2px
   （次按钮有 1px 边框、主按钮没有；实测 120px vs 118px，肉眼能看出不齐）。 */
.modal .box .acts .ok{ border:1px solid var(--yellow) }
.modal .close{ margin-top:12px;text-align:center;color:#fff;font-size:12px;background:none;border:0;display:block;width:100% }
/* --------------------------------------------------------------------------
   底部弹出层（Sheet）★ 2026-10-02 新增
   与居中 .modal 并列：凡「点一行 → 出流程」的弹窗统一用它（参考稿的 van-popup
   position="bottom" round：从底部升起、上圆角、可点遮罩关闭、带安全区内边距）。
   -------------------------------------------------------------------------- */
.sheet-mask{ position:fixed;inset:0;background:#0006;z-index:9000;display:flex;align-items:flex-end;justify-content:center }
.sheet{ width:100%;max-width:520px;background:#fff;border-radius:16px 16px 0 0;max-height:84vh;overflow-y:auto;
  padding-bottom:env(safe-area-inset-bottom);animation:sheet-up .22s ease-out }
@keyframes sheet-up{ from{ transform:translateY(100%) } to{ transform:translateY(0) } }
@media (prefers-reduced-motion:reduce){ .sheet{ animation:none } }
.sheet-hd{ display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:15px 15px 12px;border-bottom:1px solid var(--line) }
.sheet-hd b{ font-size:16px;color:var(--title) }
.sheet-hd a{ font-size:13px;color:var(--secondary);text-decoration:none }
.sheet-bd{ padding:6px 15px 18px }
.sheet-bd .btn-main{ width:100%;margin-top:14px }
.sheet-note{ margin-top:10px;font-size:var(--font-tiny);color:var(--secondary);line-height:1.75 }
/* 弹出层里的表单行：左标签右输入（与 .card .kv 同一行高节奏） */
.sheet-row{ display:flex;align-items:center;gap:10px;min-height:var(--touch-min);border-bottom:1px solid var(--line) }
.sheet-row:last-of-type{ border-bottom:0 }
.sheet-row .k{ flex:none;width:96px;color:var(--secondary);font-size:13px }
.sheet-row .v{ flex:1;min-width:0;text-align:right;color:var(--title);font-size:14px;word-break:break-all }
.sheet-row input,.sheet-row select{ flex:1;min-width:0;border:0;outline:0;background:transparent;font:inherit;
  color:var(--title);text-align:right }
.sheet-code{ flex:none;border:0;background:var(--yellow);border-radius:16px;height:32px;padding:0 12px;
  color:var(--ink);font-size:12px;font-weight:600 }
.sheet-code:disabled{ background:var(--line);color:var(--secondary);font-weight:400 }
.home-hero .mask{ position:absolute;inset:0;background:linear-gradient(180deg,#0000 40%,#00000073) }
.home-hero .head{ position:absolute;left:18px;bottom:30px;color:#fff }
.home-hero .head b{ font-size:22px;display:block }
.home-hero .head span{ font-size:12px;opacity:.92 }
.home-hero .bell{ position:absolute;right:16px;top:52px;width:32px;height:32px;border-radius:50%;background:#fff9;border:0;display:grid;place-items:center;z-index:2 }
.card .kv span:last-child{ text-align:right;min-width:0;word-break:break-all }
.ghost-btn{ border:1px solid var(--line);background:#fff;border-radius:25px;width:100%;height:46px;margin-top:10px;font-size:14px }
.mono{ font-family:ui-monospace,Consolas,monospace;font-size:12px }
.badge-line{ margin-top:5px;display:flex;gap:5px }
.ticket-card .th{ display:flex;gap:11px }
.ticket-card .th img{ width:74px;height:74px;border-radius:8px;object-fit:cover;flex:none }
.ticket-card .tt{ font-size:14.5px;font-weight:500;color:var(--title) }
.ticket-card .ts{ font-size:12px;color:var(--muted);margin-top:5px }
.ticket-card .tn{ font-size:11px;color:var(--secondary);margin-top:5px }
.ticket-card .tf{ display:flex;align-items:center;justify-content:space-between;margin-top:11px;padding-top:11px;border-top:1px solid var(--line) }
.ticket-card .tf .l{ font-size:12px;color:var(--secondary) }
.uploader{ display:grid;grid-template-columns:repeat(3,1fr);gap:10px }
.money-list .kv{ display:flex;justify-content:space-between;font-size:13px;padding:9px 0;border-bottom:1px solid var(--line) }
.money-list .kv:last-child{ border-bottom:0 }
.money-list .kv .n{ color:var(--secondary) }
.money-list .kv .v.pos{ color:var(--ok);font-weight:500 }
.money-list .kv .v.neg{ color:var(--danger);font-weight:500 }
.calc{ background:#fafbfc;border:1px dashed #dfe3e8;border-radius:10px;padding:14px;margin-top:12px }
.calc .l{ display:flex;justify-content:space-between;font-size:13.5px;padding:6px 0 }
.calc .l.total{ border-top:1px solid var(--line);margin-top:6px;padding-top:11px;font-size:15px;font-weight:600 }
.calc .l .neg{ color:var(--danger) }
.calc .l.total b{ color:var(--ok);font-size:18px }
.poster{ background:#fff;border-radius:12px;padding:14px;margin-top:12px;text-align:center;border:1px solid var(--line) }
.quota-bar{ height:8px;border-radius:4px;background:#eef0f3;overflow:hidden;margin-top:8px }
.quota-bar i{ display:block;height:100%;background:var(--yellow) }
.goods-grid{ display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:11px;padding:14px var(--page-gutter) }
.list .goods-grid{ padding-left:0;padding-right:0 }
.goods-card{ background:#fff;border-radius:10px;overflow:hidden;border:1px solid var(--line);text-align:left;padding:0 }
.goods-card img{ width:100%;aspect-ratio:1;object-fit:cover;display:block }
.goods-card .g{ padding:9px }
.goods-card .t{ font-size:13.5px;color:var(--title);white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
.goods-card .cash{ color:var(--danger);font-size:15px;font-weight:600;margin-top:5px }
.goods-card .bal{ font-size:11px;color:var(--secondary);margin-top:2px }

/* ==========================================================================
   商品卡（GoodsCard）细节 —— 全站共享
   ★ 新类名一律带 hc- 前缀（home card）：移植层已占用 .goods-card .t/.cash/.bal 等，
     重名会被那些规则悄悄接管。
   ========================================================================== */
.goods-grid .goods-card{ display:flex;flex-direction:column;gap:0 }
.goods-grid .goods-card>div:first-child{ flex:none }
.goods-card .g{ flex:1 1 auto;display:flex;flex-direction:column;min-height:0 }
.goods-card .hc-title{ font-size:15px;font-weight:600;color:var(--title);line-height:1.3;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
/* ★★ 2026-10-04（用户要求）：首页票品卡片的标签行 —— 最多 3 个，一行排开不换行（放不下就截断，
   宁可少显示一个也不让卡片高度参差）。 */
.goods-card .hc-tags{ display:flex;flex-wrap:nowrap;gap:4px;margin-top:5px;overflow:hidden }
.goods-card .hc-tags .tag{ flex:none;font-size:10px;line-height:16px;height:16px;padding:0 5px;border-radius:3px }
.goods-card .hc-sub{ font-size:12px;color:var(--muted);line-height:1.35;margin-top:5px;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden }
.goods-card .hc-face{ color:var(--muted) }
.goods-card .hc-sell{ color:var(--secondary) }
.goods-card .hc-price{ display:flex;align-items:baseline;gap:6px;margin-top:6px;
    font-size:14px;white-space:nowrap;overflow:hidden }
.goods-card .hc-cash{ flex:none;font-size:17px;font-weight:700;color:var(--danger);line-height:1.1 }
.goods-card .hc-pts{ flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;
    font-size:11px;color:var(--secondary) }
.goods-card .hc-unit{ font-size:11px;font-weight:400;margin-left:2px }
/* ★ 次级按钮描边用 inset 阴影（不占盒模型）——否则 flex-basis:0 时两枚按钮宽度差 2px */
.goods-card .hc-acts{ display:flex;gap:6px;margin-top:auto;padding-top:8px }
.goods-card .hc-acts .btn-main,
.goods-card .hc-acts .btn-ghost{ flex:1 1 0;min-width:0;height:28px;padding:0 8px;margin:0;font-size:12px }
.goods-card .hc-acts .btn-ghost{ border:0;box-shadow:inset 0 0 0 1px var(--border) }
.goods-card .hc-acts .btn-ghost.is-muted{ color:var(--secondary);box-shadow:inset 0 0 0 1px var(--line) }
.goods-card .gc-ph{ width:100%;aspect-ratio:1;display:grid;place-items:center;
    background:var(--paper);font-size:26px;font-weight:600;color:var(--border) }

.balance-chip{ display:inline-flex;align-items:center;gap:6px;background:#fff4aa;border-radius:999px;padding:5px 12px;font-size:12px;color:#7a6600 }
.action-bar{ position:fixed;left:0;right:0;bottom:0;background:#fff;border-top:1px solid var(--line);padding:10px 15px 14px;display:flex;align-items:center;gap:10px;z-index:30 }
.action-bar .sum{ flex:1;font-size:12px;color:var(--muted) }
.action-bar .sum b{ display:block;color:var(--danger);font-size:19px;font-weight:600 }

/* --------------------------------------------------------------------------
   底部提交条（SumBar）：.action-bar 里放一个 .sum-bar，
   里面「金额行 + 整宽按钮」上下两段。金额行两端对齐，左右边与按钮完全重合。
   -------------------------------------------------------------------------- */
.sum-bar{ display:flex;flex-direction:column;gap:8px;width:100%;min-width:0 }
.sum-bar-sum{ display:flex;align-items:baseline;justify-content:space-between;gap:10px;
    font-size:12px;line-height:1.2 }
.sum-bar-label{ color:var(--secondary);flex:none }
.sum-bar-num{ color:var(--danger);font-size:18px;font-weight:700;
    font-variant-numeric:tabular-nums;white-space:nowrap }
.sum-bar-num small{ font-size:12px;font-weight:400;margin-left:2px }

/* ==========================================================================
   本项目补充组件（一律走同一套令牌与预览稿取值，不引入新视觉语言）
   ========================================================================== */

/* ---------- Toast ---------- */
.h5-toast{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,.82);color:#fff;
  padding:11px 18px;border-radius:9px;font-size:13px;z-index:9999;max-width:75%;text-align:center;line-height:1.6}

/* ---------- 页头标题（居中）----------
   返回箭头在左、标题**居中**。用绝对定位 + 左右各留 56px：无论左边返回键多宽、
   右边有没有东西，标题都真的居中；pointer-events:none —— 它只是文字，不该挡住返回键。 */
.route-header{position:sticky;top:0;z-index:20}
.route-title{position:absolute;left:56px;right:56px;top:0;height:48px;
  display:flex;align-items:center;justify-content:center;
  font-size:var(--font-title);font-weight:600;color:var(--title);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}
/* 标题栏右侧的次要操作（「全部已读」等）：margin-left:auto 顶到行尾 */
.route-act{margin-left:auto;flex:none;font-size:var(--font-caption);color:var(--secondary);
  background:none;border:0;padding:0;position:relative}
.route-act::after{content:'';position:absolute;left:-12px;right:-12px;top:50%;transform:translateY(-50%);height:44px}
.route-act.on{color:var(--blue)}
/* 顶栏返回键热区补到 44×44（视觉尺寸不变） */
.back-button{position:relative}
.back-button::after{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;transform:translate(-50%,-50%)}

/* 有 tabbar 的页面，给底部留出与 tabbar 等高的滚动空间 */
.h5-root.has-tabbar{padding-bottom:calc(76px + env(safe-area-inset-bottom))}
.h5-root.has-tabbar .page{padding-bottom:24px}
.h5-root.has-tabbar .action-bar,.h5-root.has-tabbar .buy-bar{bottom:calc(76px + env(safe-area-inset-bottom))}
/* ★ 2026-10-04：底部导航改成全局常驻后补的一条 ——
   上面 `.h5-root.has-tabbar .page{padding-bottom:24px}` 的优先级高于 `.page.has-bar{110px}`，
   于是「既有底部操作栏、又有底部导航」的页面（确认订单/订单详情/票品详情）
   滚动区会被压掉约 76px，最后一行内容被两条栏盖住。这里按两条栏的高度一起留白。 */
.h5-root.has-tabbar .page.has-bar{padding-bottom:calc(110px + 76px + env(safe-area-inset-bottom))}
.action-bar,.buy-bar{padding-bottom:calc(14px + env(safe-area-inset-bottom))}
.page.has-bar{padding-bottom:110px}

/* 设计稿用 <button> 承载的按钮/宫格/列表行，H5 里改用 <a> 承载真实跳转 → 补齐盒模型 */
.btn-main,.btn-ghost,.full-btn,.ghost-btn,a.btn-main,a.btn-ghost,.buy-bar .btn-main{
  display:inline-flex;align-items:center;justify-content:center;
  white-space:nowrap;flex:none;text-decoration:none}
.menu-grid a,.order-grid a,.me-more a{text-decoration:none;color:var(--title)}
.menu-grid a{display:block;text-align:center;min-height:83px;font-size:11px;padding:9px 0}
.order-grid a{display:flex;flex-direction:column;align-items:center;justify-content:space-between;
  height:49px;font-size:12px;white-space:nowrap;padding:0}
.me-more a{display:flex;align-items:center;gap:15px;width:100%;height:44px;font-size:14px}
.me-more a .grow,.me-more button .grow{flex:1;min-width:0}

/* 分类多时的横滚 tab */
.tabs.is-scroll{overflow-x:auto;overflow-y:hidden;white-space:nowrap;scrollbar-width:none;
  -webkit-overflow-scrolling:touch}
.tabs.is-scroll::-webkit-scrollbar{display:none}
.tabs.is-scroll button{flex:none;padding:12px 13px}

/* 首页右上角铃铛：放进 44px 热区 */
.bell{position:relative}
.bell::after{content:'';position:absolute;left:-6px;right:-6px;top:-6px;bottom:-6px}

/* 触控区域兜底：纯文字链接默认只有文字大小，用伪元素把可点范围撑到 44px */
.section-head small a,.card h2 a,.kv a,.li-title a,.sec-title a,.section-head a,
.card a[href="javascript:;"]{position:relative}
.section-head small a::after,.card h2 a::after,.kv a::after,
.sec-title a::after,.section-head a::after,.li-right a::after,
.card p a::after,.notice a::after,.alert a::after{
  content:'';position:absolute;left:-12px;right:-12px;top:50%;transform:translateY(-50%);
  height:44px;min-width:44px}
.card p,.notice,.alert{position:relative}
.card h2 a{display:inline-block}

/* 角标/标签一律不换行 */
.tag,.badge,.status-tag{white-space:nowrap}

/* 长文/协议页正文 */
.doc{padding:16px 15px 40px;font-size:14px;line-height:1.95;color:var(--title);background:#fff}
.doc h3{font-size:15px;font-weight:600;margin:20px 0 6px}
.doc h3:first-child{margin-top:0}
.doc p{margin:8px 0}
.doc ul,.doc ol{margin:8px 0;padding-left:20px}
.doc li{margin:5px 0}
.doc strong{font-weight:600}
.doc table{width:100%;border-collapse:collapse;margin:10px 0;font-size:13px}
.doc th,.doc td{border:1px solid var(--line);padding:7px 9px;text-align:left}
.doc-meta{padding:14px 15px 0;font-size:12px;color:var(--secondary)}
.doc-title{padding:16px 15px 0;font-size:18px;font-weight:600;color:var(--title)}

/* ---------- 「我的」页顶部整块白底 ----------
   ★ 必须用同优先级选择器覆盖上面的 `body .h5-root .me-content{padding-top:73px}`。 */
body .h5-root .me-content{padding-top:0}
.me-top{background:#fff;padding:24px 15px 0;margin:0 calc(-1 * var(--page-gutter));position:relative;
  /* ★ 2026-10-03：用户卡与下方卡片改成独立白卡后，下沿要收圆角才看得出分开 */
  border-radius:0 0 var(--radius-card) var(--radius-card)}
.me-set{position:absolute;top:16px;right:15px;width:34px;height:34px;display:grid;place-items:center;
  color:var(--muted);border-radius:50%;-webkit-tap-highlight-color:transparent}
.me-set::after{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;transform:translate(-50%,-50%)}
.me-set:active{background:var(--line)}
.me-top .user{height:auto;padding:0 0 14px}
.me-top .avatar-box{display:block;flex:none;position:relative;line-height:0}
.me-top .avatar.has-img{display:block;object-fit:cover;background:#f2f3f5}
.me-top .asset{background:transparent;border-radius:0;margin:0;padding:14px 0}
.asset a{display:block;position:relative;color:inherit}
.asset a::after{content:"";position:absolute;left:0;right:0;top:50%;height:100%;min-height:44px;transform:translateY(-50%)}
.asset a:active{opacity:.65}
/* ★ 2026-10-03：白块内的加载态 / 空态（组件默认的 46px / 120px 是给整页用的，
   放在「我的」页顶部白块里太空）。作用域限定必须写在组件层，页面里写会被告警。 */
.me-top .loading{padding:40px 0 56px}
.me-top .empty{padding-top:40px}
.me-more .row-state{flex:none;white-space:nowrap;color:var(--secondary)}
.card.money-list{display:block}

/* ---------- 日历（场次按日期选）---------- */
.cal{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.cal .head{font-size:var(--font-tiny);color:var(--secondary);text-align:center;padding:6px 0}
.cal .d{text-align:center;padding:6px 0;border-radius:var(--radius-tag);font-size:var(--font-tiny);
  color:var(--muted);min-height:44px;position:relative}
.cal .d .n{font-size:var(--font-body);color:var(--title)}
.cal .d.on{background:var(--yellow)}
.cal .d.on .n{color:var(--ink);font-weight:600}
.cal .d.off{opacity:.35}

/* ---------- 分段控件（单选）---------- */
.seg{display:flex;gap:8px;margin-top:10px}
.seg button{flex:1;height:38px;border:0;border-radius:var(--radius-pill);background:var(--paper);
  color:var(--title);font-size:var(--font-caption)}
.seg button.on{background:var(--yellow);color:var(--ink);font-weight:600}

/* ---------- 数字步进器（购票数量）---------- */
.stepper{display:inline-flex;align-items:center;border:1px solid var(--border);border-radius:var(--radius-btn);overflow:hidden}
.stepper button{width:40px;height:36px;border:0;background:#fff;font-size:18px;line-height:1;color:var(--title)}
.stepper button:disabled{color:#c9ccd2}
.stepper .n{min-width:46px;text-align:center;font-size:15px;font-variant-numeric:tabular-nums}

/* ==========================================================================
   ★ 首页 / 宫格（从 index/index.html 上收，2026-09-30）
   ★ 为什么上收：页面里**禁止硬编码色值**（规范 R-1）。这些取值是设计资产，
     放在共享样式表里才能被「我的」页等复用，也才改得动。
   ========================================================================== */
/* hero 与内容区的衔接：两个页级常量（改这里就能整体调衔接） */
.page{ --seam-r:24px; --seam-gap:15px }
/* 内容区圆角与搭接量共用一处来源，避免「圆角两侧露出深色直角缺口」 */
.home-content{ border-radius:var(--seam-r) var(--seam-r) 0 0; margin-top:calc(-1 * var(--seam-gap)) }
/* 「肩」★ 必须排在 .mask 之前：这样它和 hero 一起被压暗，颜色与紧邻像素完全一致 */
.home-hero .seam{
  position:absolute;left:0;right:0;top:0;
  height:calc(100% + var(--seam-r) - var(--seam-gap));
  background:inherit;background-size:100% 100%;background-repeat:no-repeat;
  clip-path:inset(calc(100% - var(--seam-r)) 0 0 0);pointer-events:none }
/* 无 banner 图时用同观感的深色渐变兜底（有图时 <img> 会盖住这层） */
.home-hero{ height:190px; background:linear-gradient(155deg,var(--hero-1) 0%,var(--hero-2) 55%,var(--hero-3) 100%) }
/* 左上角城市入口：沿用「玻璃底 pill」这一手法（与右上角铃铛同族） */
.hero-city{ position:absolute;left:16px;top:52px;z-index:2;display:inline-flex;align-items:center;gap:3px;
  background:var(--glass-strong);border-radius:999px;padding:5px 11px;font-size:12px;
  color:var(--hero-text);font-weight:500 }
.hero-city:active{ background:var(--glass-stronger) }
/* 铃铛未读角标（数字 >99 由后端截断） */
.home-hero .bell-bdg{position:absolute;top:-3px;right:-3px;min-width:16px;height:16px;padding:0 4px;
  border-radius:8px;background:var(--danger);color:var(--white);font-size:10.5px;font-style:normal;
  font-weight:600;line-height:16px;text-align:center;box-shadow:0 0 0 1.5px var(--glass-stronger)}
.menu-grid{padding:11px 0 4px}
/* 宫格色块：黄 / 蓝 / 粉 / 紫 / 绿 / 青 六色轮转（与参考稿同一套观感） */
.menu-grid .ico.t1{background:var(--tone1-bg);color:var(--tone1-fg)}
.menu-grid .ico.t2{background:var(--tone2-bg);color:var(--tone2-fg)}
.menu-grid .ico.t3{background:var(--tone3-bg);color:var(--tone3-fg)}
.menu-grid .ico.t4{background:var(--tone4-bg);color:var(--tone4-fg)}
.menu-grid .ico.t5{background:var(--tone5-bg);color:var(--tone5-fg)}
.menu-grid .ico.t6{background:var(--tone6-bg);color:var(--tone6-fg)}
/* 商品卡图占位块需要相对定位，角标才能贴到卡片角落 */
.goods-card>div:first-child{position:relative}

/* ==========================================================================
   商品卡图位（票品列表 / 首页橱窗）—— 图片展示加固
   ★ 要解决的问题：图块高度原来只由 <img> 自己撑（aspect-ratio:1），
     一旦图加载失败就被浏览器缩成碎图/0 高 → 卡片塌高、列表跳版。
     现在把尺寸定在「图槽」（.goods-card 的第一个子元素）上，
     「无图 / 坏图 / 图还在下载」三种状态的图槽尺寸完全一致。
   ★ 槽位尺寸与配色一律走令牌（--radius-card 的圆角由 .goods-card 的 overflow:hidden 裁切）。
   ========================================================================== */
.goods-grid .goods-card>div:first-child{
  width:100%;aspect-ratio:1;overflow:hidden;background:var(--paper)}
/* 首字占位：铺满同一个 1:1 图槽 —— 「服务端就没下发封面」与
   「图挂了被 onerror 换成占位」两条路径共用这一条，尺寸天然一致 */
.goods-grid .goods-card .gc-ph{
  width:100%;height:100%;min-height:100%;display:grid;place-items:center;
  background:var(--paper);font-size:26px;font-weight:600;color:var(--border)}

/* ==========================================================================
   券卡片（★★ 2026-10-04 新增到组件层）
   --------------------------------------------------------------------------
   造型照"纸质券"来：左边一块金额/折扣（黄底），中间一条**虚线撕口**，右边券名与说明，
   右下角一颗领取按钮。颜色一律走令牌，不写死。组件层的 .card/.tag/.full-btn 不再使用
   （本页已是一套自有的券卡片结构）。
   ========================================================================== */
.cpcard{display:flex;position:relative;margin:0 0 12px;border-radius:var(--radius-card);
  background:var(--white);box-shadow:0 1px 6px rgba(0,0,0,.05);overflow:hidden}
.cpcard-l{flex:none;width:96px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:2px;padding:16px 8px;background:var(--yellow-soft);position:relative}
/* 撕口：右边界一条虚线 + 上下两个半圆缺口 */
.cpcard-l::after{content:'';position:absolute;right:-1px;top:14px;bottom:14px;
  border-right:1px dashed var(--border)}
.cpcard-r{flex:1;min-width:0;padding:14px 12px;display:flex;flex-direction:column;gap:6px}
/* 金额排布：前缀/单位小、数字大（「减 10.00 元」→ 减<24px>10.00</24px>元）。
   实测：整体 20px 时「元」会被挤到第二行，成为一个孤字。 */
.cpcard-amt{display:flex;align-items:baseline;justify-content:center;gap:1px;
  color:var(--title);line-height:1.1;white-space:nowrap}
.cpcard-amt .cpcard-n{font-size:22px;font-weight:700}
.cpcard-amt .cpcard-u{font-size:13px;font-weight:600}
.cpcard-thr{font-size:11px;color:var(--secondary);text-align:center}
.cpcard-nm{font-size:13.5px;font-weight:600;color:var(--title);line-height:1.35}
.cpcard-mt{font-size:11.5px;color:var(--muted);line-height:1.5}
.cpcard-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:2px}
.cpcard-tags{display:flex;flex-wrap:wrap;gap:4px;min-width:0}
.cpcard-btn{flex:none;align-self:center;margin-right:12px;height:34px;padding:0 14px;border:0;border-radius:17px;
  background:var(--yellow);color:var(--ink);font-size:14px;font-weight:600;cursor:pointer}
.cpcard-btn:disabled{background:var(--line);color:var(--secondary)}
/* ★ 不可用的券（已使用 / 已过期 / 已作废）：左侧金额块降饱和，一眼分出"这张已经用不了"。
   用 filter 而不是覆盖颜色：底色是令牌（--yellow-soft），覆盖会引入第二处色值。 */
.cpcard.is-dead .cpcard-l{filter:grayscale(1);opacity:.55}
.cpcard.is-dead .cpcard-r{opacity:.75}

