/* OnceHere · 我们曾经来过 —— 视觉样式 */

/* hidden 属性的浏览器默认样式是 display:none，但优先级低于类选择器。
   任何设置了 display:flex/grid 的元素（如 .hero-actions）一旦带 hidden，
   都会被类选择器盖掉而照常显示，导致"切换视图无效"。强制兜底。 */
[hidden] { display: none !important; }

:root {
  /* 告诉浏览器本站是深色主题：
     原生下拉列表（select 展开后的选项）、日期/时间选择面板、滚动条、
     自动填充底色等 UA 控件都会跟着走深色，否则在浅色系统上会突然弹出一块白底。
     注意：Chrome/Edge/Firefox 认这个属性；个别国产内核（如部分 Android WebView）
     不认，所以 select option 还要再显式配一次兜底。 */
  color-scheme: dark;
  --bg: #070b18;
  --bg2: #0d1430;
  --ink: #eef1fb;
  --muted: #99a3c4;
  --gold: #f3d496;
  --gold-dim: #c9a86a;
  --line: rgba(255, 255, 255, 0.1);
  --glass: rgba(255, 255, 255, 0.045);
  --glass-hi: rgba(255, 255, 255, 0.08);
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
  --r: 18px;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background:
    radial-gradient(1200px 700px at 80% -10%, #1a2a55 0%, transparent 60%),
    radial-gradient(900px 600px at 10% 10%, #23204a 0%, transparent 55%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg2) 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
    "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", sans-serif;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

#stars {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

main, header, footer { position: relative; z-index: 1; }

/* ---------- 顶栏 ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px clamp(16px, 5vw, 56px);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}

.brand {
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--ink);
  text-decoration: none;
  font-size: 17px;
  cursor: pointer;
  white-space: nowrap;
}
.brand-mark { color: var(--gold); margin-right: 4px; }

.topbar nav { display: flex; gap: 6px; flex-wrap: wrap; }
.topbar nav button {
  background: transparent;
  border: 0;
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: 0.2s;
}
.topbar nav button:hover { color: var(--ink); background: var(--glass); }

/* ---------- 布局 ---------- */
main { max-width: 1080px; margin: 0 auto; padding: clamp(28px, 6vw, 64px) clamp(16px, 5vw, 32px) 80px; }

.view { animation: fade .45s ease both; }
@keyframes fade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---------- 首页 ---------- */
.hero { text-align: center; padding: clamp(20px, 6vw, 60px) 0 36px; }

.eyebrow {
  letter-spacing: 0.42em;
  text-transform: uppercase;
  font-size: 12px;
  color: var(--gold-dim);
  margin: 0 0 14px;
}

.hero h1 {
  margin: 0 0 20px;
  font-size: clamp(38px, 8vw, 74px);
  line-height: 1.12;
  letter-spacing: 0.04em;
  background: linear-gradient(180deg, #fff 0%, var(--gold) 130%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 800;
}

.lede { color: #cdd4ec; font-size: clamp(15px, 2.2vw, 18px); margin: 0 auto 32px; max-width: 620px; }
.lede b { color: var(--gold); }

.hero-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.hero-note { margin-top: 18px; font-size: 13px; color: var(--muted); min-height: 20px; }

.btn {
  font: inherit;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 13px 26px;
  cursor: pointer;
  transition: transform .16s, box-shadow .2s, background .2s, border-color .2s;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn.primary {
  background: linear-gradient(135deg, var(--gold) 0%, #e0b969 100%);
  color: #241a05;
  box-shadow: 0 10px 30px rgba(243, 212, 150, 0.22);
}
.btn.primary:hover { box-shadow: 0 14px 38px rgba(243, 212, 150, 0.34); }
.btn.ghost { background: var(--glass); border-color: var(--line); color: var(--ink); }
.btn.ghost:hover { background: var(--glass-hi); }
.btn.small { padding: 9px 18px; font-size: 14px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* ---------- 统计 ---------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin: 20px 0 54px;
}
.stat {
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 22px 18px;
  text-align: center;
}
.stat b { display: block; font-size: clamp(24px, 4vw, 34px); color: var(--gold); font-weight: 800; line-height: 1.2; }
.stat span { font-size: 13px; color: var(--muted); }
.stat .tags { display: flex; flex-wrap: wrap; gap: 5px; justify-content: center; margin-top: 8px; }
.tag { font-size: 11px; color: #cfd6ee; background: rgba(255,255,255,.07); border-radius: 999px; padding: 2px 9px; }

.latest h2 { font-size: 15px; color: var(--muted); font-weight: 600; letter-spacing: .1em; margin-bottom: 14px; }
/* 最近来过：桌面端固定 4 列 × 2 排 = 8 张，正好铺满两排。
   不用 auto-fill——它会按容器宽度算出 5 或 6 列，导致最后一行只剩零星几张，
   排面不整。响应式断点见 mobile.css。 */
.latest-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}
/* 中等宽度：3 列 */
@media (max-width: 1100px) {
  .latest-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .latest-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
}

/* ---------- 卡片 ---------- */
.card {
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: clamp(24px, 4vw, 40px);
  box-shadow: var(--shadow);
  backdrop-filter: blur(10px);
}
.card.narrow { max-width: 560px; margin: 0 auto; }
.card h2 { margin: 0 0 6px; font-size: clamp(22px, 3.4vw, 30px); }
.sub { color: var(--muted); margin: 0 0 26px; font-size: 14px; }

/* ---------- 表单 ---------- */
.field { display: block; margin-bottom: 18px; }
.label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 7px; }
.label em { font-style: normal; color: var(--muted); font-weight: 400; }
.field input {
  width: 100%;
  font: inherit;
  color: var(--ink);
  background: rgba(0, 0, 0, 0.26);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 13px 15px;
  outline: none;
  transition: border-color .2s, background .2s;
}
.field input:focus { border-color: var(--gold-dim); background: rgba(0, 0, 0, 0.36); }
.field input::placeholder { color: #6c769a; }
.hint { display: block; margin-top: 6px; font-size: 12px; color: #7d87ab; }
/* 原生日期 / 时间 / 月份控件（当前前台已改用三个下拉，这里作为兜底保留，
   万一以后又用回 input[type=date]，也不至于弹白底）。:root 的 color-scheme 已覆盖大部分场景。 */
input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"] { color-scheme: dark; }

.check { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; color: #c3cbe6; margin: 4px 0 18px; cursor: pointer; }
.check input { margin-top: 5px; accent-color: var(--gold-dim); }

.privacy {
  font-size: 12.5px;
  color: #d9b98a;
  background: rgba(243, 212, 150, 0.08);
  border: 1px solid rgba(243, 212, 150, 0.2);
  border-radius: 12px;
  padding: 12px 14px;
  margin: 0 0 22px;
}

.form-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.error { color: #ff9c9c; font-size: 13.5px; margin: 14px 0 0; }

/* ---------- 支付 ---------- */
.preview {
  background: rgba(0, 0, 0, 0.24);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px;
  margin-bottom: 18px;
  font-size: 14px;
}
.preview .row { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; }
.preview .row span { color: var(--muted); }
/* 「想说的话」那一行：整句话右对齐会挤成一条窄柱子，改成上下排。
   标点、引号多的中文尤其难看，所以单独给它一条 .msg。 */
.preview .row.msg { flex-direction: column; align-items: flex-start; gap: 3px; padding-top: 8px; }
.preview .row.msg > span { color: var(--muted); }
.preview .row.msg > b {
  text-align: start;
  word-break: break-word;
  /* 用户在 textarea 里换的行，确认页要照着换，不能被折成一行 */
  white-space: pre-line;
}
/* 定时说明：括号 + 另起一行 + 小一号字，视觉上属于"注解"，不抢原文 */
.preview .row.msg .msg-when {
  display: block;
  margin-top: 5px;
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--muted);
  white-space: normal;
}
/* 生日：年 / 月 / 日 三个下拉。
   不用 input[type=date]：安卓原生选择器要翻页找年份，体验很差。 */
.bday {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  gap: 8px;
}
.bday select {
  width: 100%;
  min-width: 0;
  padding: 11px 10px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .04);
  color: var(--ink);
  font-size: 15px;
  font-family: inherit;
  /* iOS 会给 select 加默认圆角和内阴影，清掉 */
  appearance: none;
  -webkit-appearance: none;
}
/* 展开后的选项列表：默认是系统白底，跟深色主题不搭。
   和 .lang-select option 用同一个色值，保证全站下拉外观一致。 */
.bday select option {
  background: #151b35;
  color: var(--ink);
}
.bday select:focus {
  outline: none;
  border-color: rgba(243, 212, 150, .6);
}
/* 未选择时（placeholder 选项）显示为弱化色，选中后为正常色 */
.bday select:invalid { color: var(--muted); }

/* ---------- 想说的话 ---------- */
/* textarea 与 input 同一套外观，但要能竖着长、不能拖拽变形 */
.field textarea {
  width: 100%;
  font: inherit;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
  background: rgba(0, 0, 0, 0.26);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 15px;
  outline: none;
  resize: vertical;
  min-height: 88px;
  transition: border-color .2s, background .2s;
}
.field textarea:focus { border-color: var(--gold-dim); background: rgba(0, 0, 0, 0.36); }
.field textarea::placeholder { color: #6c769a; }

/* 提示与字数共用一行：左边解释规则，右边实时计数 */
.msg-hint { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; line-height: 1.6; }
.msg-hint > span:first-child { flex: 1; }
.msg-count { flex: none; color: #6c769a; font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.msg-count.warn { color: #d8b072; }
.msg-count.full { color: #ff9c9c; }

/* ---------- 定时显示 ---------- */
.sched { margin: -6px 0 20px; }
.sched-toggle { margin: 0 0 8px; }
.sched-toggle span { line-height: 1.5; }

/* 阅后即焚：紧跟在定时显示之后，是同一组"这段话怎么被读到"的设置。
   排版上与 .sched 对齐（负上边距），避免两条勾选之间出现一道突兀的空隙 */
.burn { margin: -10px 0 20px; }
.burn .check { margin: 0 0 5px; }
.burn .hint { margin: 0 0 0 24px; line-height: 1.6; }

/* 展开区左侧一道细金线：表示"这是这段话的附加设置"，不与主表单抢视线 */
.sched-panel {
  margin: 0 0 4px;
  padding: 10px 0 2px 14px;
  border-left: 2px solid rgba(243, 212, 150, .3);
  animation: schedIn .2s ease-out;
}
@keyframes schedIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sched-panel { animation: none; }
}

.sched-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  margin: 0 0 8px;
  font-size: 13.5px;
  color: #c3cbe6;
}
.sched-picks { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; }
/* 每个「下拉 + 量词」是一个整体，换行时不会被拆开 */
.sched-picks .pick { display: inline-flex; align-items: center; gap: 3px; }
.sched-picks select {
  min-width: 0;
  padding: 7px 9px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .05);
  color: var(--ink);
  font-size: 14px;
  font-family: inherit;
  appearance: none;
  -webkit-appearance: none;
  font-variant-numeric: tabular-nums;
}
/* 展开的选项列表同样要深色，否则又是白底（这个坑踩过一次） */
.sched-picks select option { background: #151b35; color: var(--ink); }
.sched-picks select:focus { outline: none; border-color: rgba(243, 212, 150, .6); }
.sched-line .unit { color: #8d97b8; font-size: 12.5px; margin-right: 2px; }
/* 英/法等语言不需要"年/月/日"量词，空串时不要留下空隙 */
.sched-line .unit:empty { display: none; }
.sched-panel .hint { margin: 0; line-height: 1.65; }

.preview .row b { font-weight: 600; text-align: right; word-break: break-all; }
/* 确认页的审核提示：醒目但不刺眼，付款前必须让人看见 */
.pay-review-tip {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(243, 212, 150, .1);
  border: 1px solid rgba(243, 212, 150, .34);
  color: var(--gold);
  font-size: 13px;
  line-height: 1.6;
}

.price-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-top: 1px dashed var(--line);
  padding-top: 16px;
  margin-bottom: 20px;
  font-size: 14px;
  color: var(--muted);
}
.price { color: var(--gold); font-size: 30px; font-weight: 800; }

.pay-box {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 22px;
  text-align: center;
  background: rgba(0, 0, 0, 0.2);
  margin-bottom: 20px;
}
.pay-box .loading, .pay-box p { color: var(--muted); margin: 0 0 14px; font-size: 14px; }
.pay-box code { color: var(--gold-dim); font-size: 12px; word-break: break-all; }

/* ---------- 跳转式 / 唤起 App 支付 ---------- */
/* 没有二维码可扫，所以把金额放大 + 一个明确的跳转按钮，视线落点更清楚 */
.pay-box .pay-amount-big {
  font-size: 28px;
  font-weight: 700;
  color: var(--gold);
  margin: 6px 0 18px;
  direction: ltr;
  unicode-bidi: embed;
}
.pay-box #ppGoBtn,
.pay-box #h5GoBtn,
.pay-box #appGoBtn { width: 100%; }

/* 说明性小字：金额下方那句"付完会自动回来"之类 */
.pay-box .pay-fineprint {
  margin-top: 12px;
  font-size: 12px;
  opacity: .75;
  line-height: 1.7;
}
.pay-box .pay-fineprint a { color: var(--gold-dim); text-decoration: underline; }

/* 换环境提示：手机上走不通时告诉用户该怎么办 */
.pay-box .pay-env-tip,
.env-blocked {
  font-size: 13px;
  line-height: 1.8;
  color: var(--muted);
}
.pay-box .pay-env-tip { margin-top: 10px; }

.pay-problem {
  color: #ffd9a1 !important;
  background: rgba(243, 212, 150, .1);
  border: 1px solid rgba(243, 212, 150, .3);
  border-radius: 10px;
  padding: 12px 14px;
  line-height: 1.7;
}

/* ---------- 当前环境一个渠道都用不了 ---------- */
/*
 * 典型场景：有人在微信里点开这个链接。与其让他填完表单再失败，
 * 不如在表单里就说清楚"在这儿付不了、请去哪儿付"。
 */
.env-blocked {
  background: rgba(243, 212, 150, .08);
  border: 1px solid rgba(243, 212, 150, .28);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 18px;
}
.env-blocked[hidden] { display: none; }
.env-blocked-title {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 600;
  color: #ffd9a1;
}
.env-blocked-item { margin: 0 0 6px; }
.env-blocked-tip {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px dashed rgba(243, 212, 150, .25);
  color: var(--gold-dim);
}
/* 「复制本页网址」：手机用户换到电脑上付款的唯一自救动作 */
.env-blocked-copy { margin-top: 12px; }

/* ---------- 完成 ---------- */
.done { text-align: center; }
.done-mark { font-size: 46px; color: var(--gold); line-height: 1; margin-bottom: 10px; }
.done .tip { font-size: 13px; color: var(--muted); margin: 18px 0 24px; }
.done .tip a { color: var(--gold); word-break: break-all; }
/* 完成页那句"请记住你的印记编号（NO.0007）"里的编号：
   用和链接一致的金色 + 等宽字，让人一眼知道这是要抄下来的那串字符 */
.done .tip .seq-hl {
  color: var(--gold);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  letter-spacing: .02em;
  /* 这里是 UUID（36 字符），手机上一行放不下：
     允许在连字符处换行，绝不 nowrap —— 否则整段会被撑出屏幕 */
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  /* 可点即复制：虚线底 + 手型，让它看起来就是个能按的东西 */
  cursor: pointer;
  padding: 0 2px;
  border-radius: 3px;
  border-bottom: 1px dashed currentColor;
  transition: background-color .15s ease, filter .15s ease;
}
.done .tip .seq-hl:hover,
.done .tip .seq-hl:focus-visible {
  background: rgba(255, 255, 255, .09);
  filter: brightness(1.2);
}
.done .tip .seq-hl:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
/* 复制成功的一瞬间亮一下，配合 toast 给个"确实按到了"的反馈 */
.done .tip .seq-hl.is-copied {
  background: rgba(255, 255, 255, .16);
  filter: brightness(1.45);
}
.done .form-actions { justify-content: center; }

/* ---------- 印记卡 ---------- */
.record-card {
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.03));
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 18px;
  text-align: left;
  transition: transform .2s, border-color .2s;
}
.record-card:hover { transform: translateY(-3px); border-color: rgba(243, 212, 150, 0.35); }
.record-card.big { padding: 24px; margin-top: 8px; }
.rc-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.rc-top-end { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.rc-top-end .rc-badge { margin-left: 0; }
.rc-seq { font-size: 11px; color: var(--gold-dim); letter-spacing: .08em; }
.rc-name { margin: 6px 0 10px; font-size: 19px; font-weight: 700; word-break: break-all; }
.rc-meta { font-size: 13px; color: #c6cde8; margin: 3px 0; display: flex; gap: 8px; }
.rc-meta i { font-style: normal; color: var(--muted); min-width: 48px; }
.rc-msg { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); font-size: 13.5px; color: #dfe4f5; font-style: italic; }
.empty { color: var(--muted); text-align: center; padding: 40px 0; }

/* ---------- 印记墙 ---------- */
.wall-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 6px; }
.wall-head h2 { margin: 0; font-size: clamp(22px, 3.4vw, 30px); }
.search { display: flex; gap: 8px; }
.search input {
  font: inherit; font-size: 14px;
  background: rgba(0, 0, 0, 0.26);
  border: 1px solid var(--line);
  color: var(--ink);
  border-radius: 999px;
  padding: 10px 16px;
  outline: none;
  min-width: 200px;
}
.search input:focus { border-color: var(--gold-dim); }
.wall-meta { color: var(--muted); font-size: 13px; margin: 0 0 22px; }
/* 搜索回退提示：字面匹配为空、改按国家展示时的说明 */
.wall-fallback {
  margin: -8px 0 18px;
  font-size: 12.5px;
  color: var(--gold-dim);
  padding: 8px 12px;
  border-left: 2px solid rgba(243, 212, 150, 0.35);
  background: rgba(243, 212, 150, 0.06);
  border-radius: 0 8px 8px 0;
}
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.more-wrap { text-align: center; margin-top: 30px; }

/* ---------- 我的印记 ---------- */
#mineInput, #view-mine .card > input {
  width: 100%;
  font: inherit;
  background: rgba(0, 0, 0, 0.26);
  border: 1px solid var(--line);
  color: var(--ink);
  border-radius: 12px;
  padding: 13px 15px;
  outline: none;
  margin-bottom: 18px;
}
#mineResult { margin-top: 22px; }

/* 找回页里的「想说的话」。
   ============================================================
   四种状态必须**一眼可分**，而且不能只靠颜色 —— 深色背景上灰阶差很小，
   远处或低亮度屏幕根本分不出哪块是"真有内容"、哪块是"还没到时候"。
   真正好读的信号是**形状**：

     有正文  → 一张信纸：亮底、衬线体、左侧粗金线、右上角大引号
     未到点  → 一条封条：虚线框 + 45° 斜纹、内容居中、锁着的圆环
     已焚    → 一个空信封：虚线更淡、居中、沙漏
     待拆    → 金色实线 + 「查看这封信」（介于两者之间：有信封的分量，但没摊开）

   实现上：底色/边框在 .mine-msg 上，正文的"纸感"全部挂在 .has-text 上，
   "封条感"挂在 .locked / .burned 上。三者互不干扰，改一处不会牵动另一处。
*/
.mine-msg {
  margin-top: 16px;
  padding: 16px 18px;
  border: 1px solid rgba(243, 212, 150, .22);
  border-left: 2px solid rgba(243, 212, 150, .55);
  border-radius: 4px 14px 14px 4px;
  background: linear-gradient(140deg, rgba(243, 212, 150, .07), rgba(255, 255, 255, .02));
}
.mine-msg-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 8px;
  font-size: 11.5px; letter-spacing: .14em;
  color: var(--gold-dim);
}
.mine-msg-head::before { content: '✦'; font-size: 10px; color: var(--gold); letter-spacing: 0; }
.mine-msg-body {
  margin: 0;
  font-size: 15px;
  line-height: 1.95;
  color: #e8ecf9;
  /* 用户敲的换行要保留，长串（网址等）不能撑破卡片 */
  white-space: pre-wrap;
  word-break: break-word;
}

/* ---------- ① 有正文：一张摊开的信纸 ---------- */
.mine-msg.has-text {
  position: relative;
  padding: 20px 22px 22px;
  border-color: rgba(243, 212, 150, .18);
  border-left-width: 3px;
  border-left-color: rgba(243, 212, 150, .85);
  border-radius: 4px 16px 16px 4px;
  /* 两层叠加：上层是"纸面反光"，下层是淡淡的暖色纸纹 */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .012)),
    linear-gradient(140deg, rgba(243, 212, 150, .09), rgba(243, 212, 150, .02));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 12px 30px rgba(0, 0, 0, .22);
}
/* 右上角一个大引号：不抢正文，只是把"这是一段话"点出来 */
.mine-msg.has-text::after {
  content: '\201D';
  position: absolute;
  top: -4px; right: 16px;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 56px; line-height: 1;
  color: rgba(243, 212, 150, .14);
  pointer-events: none;
}
.mine-msg.has-text .mine-msg-head { color: var(--gold); }
.mine-msg.has-text .mine-msg-body {
  /* 衬线体：中文落到宋体/思源宋体，英文落到 Georgia。
     系统装了哪个用哪个，都没装就交给 serif 兜底 —— 不会变成无衬线。
     日/韩/阿/印地这四种文字不在这里 —— Georgia 里没有它们的字形，
     硬排进去只会一路 fallback 到系统默认 serif，见下面的分语种覆盖。 */
  font-family: Georgia, 'Songti SC', 'Noto Serif SC', 'Source Han Serif SC',
               'Songti TC', SimSun, serif;
  font-size: 15.5px;
  line-height: 2.05;
  letter-spacing: .015em;
  color: #f0f3fb;
}

/* ---------- 分语种的正文排版 ----------
   同一套 font-family 不可能同时喂饱 12 种语言：CJK、Naskh、Devanagari
   的字面高度和笔画粗细差得很远，共用一套栈的结果是四种语区各掉各的 fallback，
   "信纸感"就散掉了。这里按 <html lang> 逐个补正，其余语种走上面的默认值。
   只写覆盖项，不动上面那套 —— 以后加语言也照这个格式续一行即可。 */
[lang="ja"] .mine-msg.has-text .mine-msg-body {
  /* 明朝体 / 游明朝；Windows 的 MS PMincho 兜住没装思源的环境 */
  font-family: Georgia, 'Hiragino Mincho ProN', 'Yu Mincho', 'YuMincho',
               'Noto Serif JP', 'Source Han Serif JP', 'MS PMincho', serif;
  line-height: 2.1;
  letter-spacing: .01em;
}
[lang="ko"] .mine-msg.has-text .mine-msg-body {
  /* 韩文明朝体：Batang / AppleMyungjo；Nanum Myeongjo 是网页字体常见备选 */
  font-family: Georgia, 'AppleMyungjo', Batang, 'Noto Serif KR',
               'Nanum Myeongjo', 'Source Han Serif KR', serif;
  line-height: 2.05;
  letter-spacing: normal;
}
[lang="ar"] .mine-msg.has-text .mine-msg-body {
  /* 阿拉伯语用 Naskh，不用 Georgia（无字形）。
     行高要更大：Naskh 的上下延伸比拉丁字母长得多，2.05 会显得挤 */
  font-family: 'Noto Naskh Arabic', 'Traditional Arabic', Amiri, 'Times New Roman', serif;
  font-size: 16.5px;
  line-height: 2.25;
  letter-spacing: normal;
}
[lang="hi"] .mine-msg.has-text .mine-msg-body {
  /* Devanagari 的字面比拉丁小一圈，同字号看起来"缩小"了，补 1px；
     行高也要够，否则上面的 matra 和下面的底线会互相压 */
  font-family: 'Noto Serif Devanagari', 'Kohinoor Devanagari', 'Nirmala UI',
               'Mangal', Georgia, serif;
  font-size: 16.5px;
  line-height: 2.2;
  letter-spacing: normal;
}
/* 阿拉伯字母是**连写**的：letter-spacing 会在字母之间插入空隙，把连笔生生拆断，
   看起来像一串散架的字母。凡是会继承字距的地方，在 RTL 下全部归零。 */
[lang="ar"] .mine-msg-head,
[lang="ar"] .mine-msg-body,
[lang="ar"] .mine-msg-lock,
[lang="ar"] .mine-msg-sub,
[lang="ar"] .mine-msg.locked .mine-msg-lock { letter-spacing: normal; }
/* 阿拉伯语的字号整体要略大：同一 px 下阿拉伯字母的视觉重量明显轻于拉丁 */
[lang="ar"] .mine-msg-lock { font-size: 15px; line-height: 1.95; }
[lang="ar"] .mine-msg-sub { font-size: 12.5px; line-height: 1.9; }
[lang="hi"] .mine-msg-lock { line-height: 1.95; }

/* ---------- ② 还没到点 / 已焚：一条封条 ---------- */
/* 这两者共用"封着"的骨架（虚线 + 居中 + 圆环图标），
   区别只在浓度：未到点是"稍后会有"，已焚是"已经空了" */
.mine-msg.locked,
.mine-msg.burned {
  padding: 22px 20px 24px;
  border: 1px dashed rgba(255, 255, 255, .2);
  border-radius: 14px;
  background-color: rgba(255, 255, 255, .014);
  text-align: center;
}
/* 45° 细斜纹 —— 封条最容易被认出来的特征，浓度压到几乎感觉不到但看得见 */
.mine-msg.locked {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(255, 255, 255, .026) 0 9px,
    transparent 9px 18px
  );
}
.mine-msg.locked .mine-msg-head,
.mine-msg.burned .mine-msg-head {
  justify-content: center;
  margin-bottom: 14px;
}
.mine-msg.locked .mine-msg-head { color: var(--muted); }
/* 标题旁的图标去掉：图标已经挪到正中间那个圆环里，旁边再来一个小符号反而乱 */
.mine-msg.locked .mine-msg-head::before,
.mine-msg.burned .mine-msg-head::before { content: none; }

.mine-msg-center {
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* 中间那个圆环：虚线圈 + 一个符号，像封口上的火漆。
   图标用内联 SVG 而不是字符 —— ⌛(U+231B) 这类符号在多数系统上会被当成
   emoji 渲染成彩色小图，深色卡片上突然跳出一个蓝黄沙漏，整块"封条"就废了。
   SVG 走 currentColor，12 种语言、所有设备上都是同一个灰色线条。 */
.mine-msg-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  margin-bottom: 12px;
  border: 1px dashed rgba(170, 179, 208, .42);
  border-radius: 50%;
  color: #aab3d0;
  font-size: 18px;
  line-height: 1;
}
.mine-msg-ico svg {
  width: 20px; height: 20px;
  display: block;
  /* 描边粗细跟着字号走，手机上（38px 圆环）不会被放大成一根粗线 */
  stroke-width: 1.6;
}

.mine-msg-lock { margin: 0; font-size: 14px; line-height: 1.7; color: #c2cae4; }
.mine-msg-lock b { color: var(--gold); font-weight: 600; }
.mine-msg-sub { margin: 6px 0 0; font-size: 12px; color: #7d87ab; line-height: 1.6; }
.mine-msg.locked .mine-msg-lock {
  font-size: 14.5px;
  color: #d3daee;
  letter-spacing: .02em;
}
/* 副说明限制行宽并居中：一行太长会破坏"一条封条"的紧凑感 */
.mine-msg.locked .mine-msg-sub { max-width: 30em; margin: 8px auto 0; }

.mine-msg.burned {
  border-color: rgba(255, 255, 255, .13);
  /* 用 background 简写而不是 background-color：
     基础样式里的暖色渐变是 background-image，只改颜色的话那层暖色还在，
     看起来仍然"有东西"，与"已经空了"相反 */
  background: rgba(255, 255, 255, .01);
}
.mine-msg.burned .mine-msg-head { color: var(--muted); }
.mine-msg.burned .mine-msg-ico {
  color: var(--muted);
  border-color: rgba(255, 255, 255, .18);
  opacity: .75;
}
.mine-msg.burned .mine-msg-lock { color: var(--muted); }

/* ---------- ③ 到点但还没点开（阅后即焚）：一封待拆的信 ---------- */
/* 不自动显示正文，只给一个按钮 —— 这是"读了才烧"的关键：
   打开页面不算读，点开才算 */
.mine-msg.sealed {
  border-left-width: 3px;
  border-left-color: rgba(243, 212, 150, .9);
  background: linear-gradient(140deg, rgba(243, 212, 150, .1), rgba(255, 255, 255, .025));
}
.mine-msg.sealed .mine-msg-head::before { content: '\2709'; }
.mine-reveal {
  display: inline-block;
  width: auto;
  margin-top: 12px;
  padding: 9px 18px;
  font-size: 13px;
  border-color: rgba(243, 212, 150, .45);
  color: var(--gold);
}
.mine-reveal:hover { border-color: var(--gold); background: rgba(243, 212, 150, .08); }
.mine-reveal[disabled] { opacity: .6; cursor: default; }

/* 完成页：告诉用户"这段话去哪儿了、什么时候能看到" */
/* ---------- 页脚 ---------- */
footer {
  text-align: center;
  padding: 34px 20px 46px;
  color: var(--muted);
  font-size: 13px;
  border-top: 1px solid var(--line);
}
footer p { margin: 4px 0; }
.foot-small { font-size: 12px; opacity: .7; }
/* ICP 备案号：法定标识，所有语言下都一样，不参与翻译。
   平时融进页脚的灰字里，hover 才亮 —— 别做成醒目的大字，但也必须可点 */
.foot-icp { font-size: 12px; opacity: .7; margin-top: 8px; }
.foot-icp a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.foot-icp a:hover,
.foot-icp a:focus-visible {
  color: var(--gold);
  border-bottom-color: currentColor;
}

/* ---------- Toast ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 34px;
  transform: translateX(-50%);
  background: rgba(18, 22, 44, 0.96);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: 12px 22px;
  border-radius: 999px;
  font-size: 14px;
  z-index: 50;
  box-shadow: var(--shadow);
  animation: fade .3s ease both;
  /* 提示语可能是一整句（"编号已经复制到粘贴板，去粘贴吧！"）：限宽换行，
     不然手机上一个 999px 圆角的长条会被撑出屏幕外 */
  max-width: min(86vw, 520px);
  text-align: center;
  line-height: 1.5;
  border-radius: 16px;
}

@media (max-width: 560px) {
  .topbar nav button { padding: 7px 10px; font-size: 13px; }
  .hero-actions .btn, .form-actions .btn { width: 100%; }
  .grid { grid-template-columns: 1fr; }
}

/* ---------- 语言选择器 ---------- */
.lang-select {
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 10px;
  outline: none;
  cursor: pointer;
  max-width: 130px;
}
.lang-select:hover { background: var(--glass-hi); }
.lang-select option { background: #151b35; color: #eef1fb; }

.qr-box {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 180px;
  color: #7d87ab;
  font-size: 13px;
}
.qr-box img, .qr-box canvas { border-radius: 10px; background: #fff; padding: 8px; }
.qr-box code { word-break: break-all; font-size: 12px; }

/* ---------- RTL（阿拉伯语） ---------- */
[dir="rtl"] .brand-mark { margin-right: 0; margin-left: 4px; }
[dir="rtl"] .rc-seq { direction: ltr; unicode-bidi: embed; }
[dir="rtl"] .stat b { direction: ltr; unicode-bidi: embed; }
[dir="rtl"] .price { direction: ltr; unicode-bidi: embed; }
[dir="rtl"] .preview .row b { text-align: left; }
/* 阿拉伯语/希伯来语的「想说的话」仍然靠右，别被上一条拉成左对齐 */
[dir="rtl"] .preview .row.msg > b { text-align: right; }
[dir="rtl"] .search input { text-align: right; }
[dir="rtl"] .done-mark { transform: scaleX(-1); }
/* 阿拉伯语：信纸的金线换到右侧，日期里的数字保持从左到右 */
[dir="rtl"] .mine-msg { border-left-width: 1px; border-right: 2px solid rgba(243, 212, 150, .55); border-radius: 14px 4px 4px 14px; }
/* 信纸的金线在 RTL 下换到右边，右上角那个引号也要翻到左上并镜像 */
[dir="rtl"] .mine-msg.has-text {
  border-right-width: 3px;
  border-right-color: rgba(243, 212, 150, .85);
  border-left-width: 1px;
  border-left-color: rgba(243, 212, 150, .18);
  border-radius: 16px 4px 4px 16px;
}
[dir="rtl"] .mine-msg.has-text::after { right: auto; left: 16px; transform: scaleX(-1); }
/* 封条在 RTL 下是四边等粗的虚线，不该留下某一侧的实线 */
[dir="rtl"] .mine-msg.locked,
[dir="rtl"] .mine-msg.burned { border: 1px dashed rgba(255, 255, 255, .2); }
/* 待拆的金线也要跟着换边：上面那条通用 RTL 规则给右边的是 2px/55%，
   sealed 需要的是 3px/90%，不覆盖的话阿拉伯语的"待拆信"金线会留在左边 */
[dir="rtl"] .mine-msg.sealed {
  border-right-width: 3px;
  border-right-color: rgba(243, 212, 150, .9);
  border-left-width: 1px;
  border-left-color: rgba(243, 212, 150, .22);
}
[dir="rtl"] .sched-panel { border-left: none; border-right: 2px solid rgba(243, 212, 150, .3); padding-left: 0; padding-right: 14px; }
[dir="rtl"] .sched-picks select { direction: ltr; }

/* ---------- 支付方式选择 ---------- */
.channel-opts { display: flex; gap: 10px; flex-wrap: wrap; }
.channel-opt {
  flex: 1 1 140px;
  display: flex; align-items: center; gap: 9px;
  background: rgba(0, 0, 0, 0.24);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 13px 15px;
  cursor: pointer;
  font-size: 14px;
  transition: border-color .2s, background .2s;
}
.channel-opt:hover { border-color: var(--gold-dim); }
.channel-opt input { accent-color: var(--gold-dim); }
.channel-opt:has(input:checked) {
  border-color: var(--gold);
  background: rgba(243, 212, 150, 0.1);
}
.channel-opt[hidden] { display: none; }

/*
 * 「能用但有坑」的渠道（PayPal 在微信/支付宝内置浏览器里）：
 * 不把选项藏掉——用户也许真能付成功——只在小字里提醒一句。
 */
.channel-opt:has(.channel-warn:not([hidden])) { flex-wrap: wrap; }
.channel-warn {
  flex: 1 1 100%;
  font-size: 11px;
  line-height: 1.5;
  color: #ffd9a1;
}
.channel-warn[hidden] { display: none; }

.channel-badge {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 12px;
  font-weight: 600;
  color: var(--gold);
  border: 1px solid rgba(243, 212, 150, .35);
  background: rgba(243, 212, 150, .1);
  border-radius: 999px;
  padding: 4px 14px;
}

/* ---------- 隐私策略 ---------- */
.privacy-doc {
  margin: 4px 0 8px;
  /* 内容较长：限高 + 内部滚动，避免把按钮顶到屏幕外 */
  max-height: 46vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 4px 14px 4px 4px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.pv-sec { padding: 14px 0; border-bottom: 1px dashed rgba(255, 255, 255, 0.07); }
.pv-sec:last-child { border-bottom: 0; }
.pv-sec h3 {
  margin: 0 0 6px;
  font-size: 14px;
  font-weight: 700;
  color: var(--gold);
  letter-spacing: .02em;
}
/* 正文用换行排列「· 」列表项，必须保留换行 */
.pv-body {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.75;
  color: #c6cde8;
  white-space: pre-line;
}
.pv-check { margin-top: 16px; }

/* ---------- 条款阅读门禁 ----------
   读完之前勾选框是"锁着"的：视觉上变灰，点下去不会勾上，而是弹一句
   「请先读到底」。注意不能用 disabled —— 禁用的框连 click 都不派发，
   用户点半天没反应，只会以为网站坏了。滚到底后提示变金色、前面多个对勾。 */
.pv-scroll-hint {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin: 10px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: #8d97ba;
  /* 提示里带箭头，读的时候不会误以为是一段正文 */
  transition: color .2s;
}
.pv-scroll-hint::before {
  content: '↓';
  flex: none;
  font-size: 12px;
  color: var(--gold-dim);
}
.pv-scroll-hint.done { color: var(--gold); }
.pv-scroll-hint.done::before { content: '✓'; color: var(--gold); }

/* 没读完就去点勾选框：提示条闪两下，把视线拉到"还差多少"这句话上。
   纯视觉提示，不改变布局（用 transform/opacity，不触发重排） */
@keyframes pvHintFlash {
  0%, 100% { transform: translateX(0); opacity: 1; }
  25%      { transform: translateX(-3px); opacity: .55; }
  75%      { transform: translateX(3px); opacity: .55; }
}
.pv-scroll-hint.flash { animation: pvHintFlash .42s ease-in-out 2; }
@media (prefers-reduced-motion: reduce) {
  .pv-scroll-hint.flash { animation: none; }
}

/* 未解锁时整块变灰：勾选框和文字一起暗下去，视觉上就是"还轮不到你"。
   仍然可点 —— 点了会告诉用户为什么勾不上（见 app.js#onPrivacyCheckGuard） */
.check.is-locked { opacity: .48; cursor: not-allowed; }
.check.is-locked input { cursor: not-allowed; }

/* 键盘用户把焦点移进条款区时给个可见的框，
   否则按 Tab 进来完全没有反馈，不知道该用方向键滚 */
.privacy-doc:focus-visible {
  outline: 2px solid rgba(243, 212, 150, .55);
  outline-offset: 2px;
}
/* 待审核印记：本人可见，用徽章标明尚未上墙，避免付了钱找不到印记的困惑 */
.rc-badge {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(243, 212, 150, .16);
  border: 1px solid rgba(243, 212, 150, .38);
  color: var(--gold);
  font-size: 11px;
  letter-spacing: .02em;
}
.rc-pending { opacity: .78; }

/* ---------- 爱心 ----------
   只显示图标、不显示数字：
   空心描边 = 还没人点过；实心红 = 已经有人点过。
   数量藏在 title / aria-label 里，悬停可得，不占版面。 */
.rc-like {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  background: none; border: 0; border-radius: 999px;
  color: var(--muted); cursor: pointer;
  transition: color .18s, background .18s;
  -webkit-tap-highlight-color: transparent;
}
.rc-like svg { width: 17px; height: 17px; display: block; }
.rc-like:hover { color: #ff8fa3; background: rgba(255, 107, 133, .1); }
.rc-like.on { color: #ff5d7a; }
.rc-like:focus-visible { outline: 2px solid rgba(243, 212, 150, .55); outline-offset: 2px; }
.rc-like:disabled { cursor: default; }
.rc-like.pop svg { animation: likePop .34s ease; }
@keyframes likePop {
  0% { transform: scale(1); }
  45% { transform: scale(1.42); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .rc-like.pop svg { animation: none; }
}
/* 退款章节：对消费者权利影响最大，单独强调。
   《消法》26 条要求以显著方式提示与消费者有重大利害关系的内容。 */
.pv-sec-terms {
  padding: 16px;
  border-radius: 12px;
  background: rgba(243, 212, 150, 0.05);
  border: 1px solid rgba(243, 212, 150, 0.18);
}
.pv-sec-terms h3 { color: var(--gold); }
