/* ==========================================================================
   兑换券体系页面样式（学生端商城 / 我的兑换券 / 口令码兑换 + 管理端券列表）
   --------------------------------------------------------------------------
   约定（见 docs/FRONTEND-CONTRACT.md 与 docs/V4-CONTRACT.md §6）：
   · 本文件只补充「现有类名无法表达」的样式，统一使用 `cp-` 前缀，禁止新建其它前缀；
     组件级外观（按钮 / 徽章 / 输入框 / 卡片 / 键值条）一律复用 components.css。
   · 颜色 / 间距 / 圆角 / 阴影 / 字号只使用 tokens.css 的 CSS 变量，
     因此浅色与深色主题自动适配，仅个别品牌色底需要 `[data-theme='dark']` 微调。
   · 不新增 animation / keyframes：动效由框架（animations.css）统一提供。

   类名前缀清单（与页面里实际使用的类名一一对应）：
     .cp-balance              行规分余额横幅（商城 / 我的兑换券顶部）
       __icon / __value / __unit
     .cp-card                 券卡片（商城与「我的兑换券」共用）
       --muted                已使用 / 已过期：置灰、虚线边框、无悬浮位移
       __head / __title / __badges / __desc / __note
       __meta / __meta-item（--warn / --danger 为库存 / 到期提示预留）
       __actions / __hint
     .cp-price / __value / __unit      券价格（行规分）
     .cp-expiry--warn / --danger       到期提示文字色（剩余 ≤3 天 / 已过期）
     .cp-code                          口令码等宽小标签（管理端券列表）
     .cp-redeem                        口令码兑换的居中大卡片
       __hero / __icon / __title / __desc / __form / __field / __submit
       __tips / __tips-item
     .cp-code-input                    口令码大号输入框
     .cp-result                        兑换成功结果卡片
       __head / __icon / __label / __title / __meta / __actions
   ========================================================================== */

/* --------------------------------------------------------------------------
   券卡片网格
   .grid-2 的 280px 最小列宽对券卡片偏窄（标题 + 徽章 + 价格 + 按钮会挤在一起），
   这里只对「直接装着券卡片的网格」放宽列宽：不新增容器类，也不改动既有 .grid 定义。
   -------------------------------------------------------------------------- */
.grid:has(> .cp-card) {
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  align-items: stretch;
}

/* --------------------------------------------------------------------------
   行规分余额横幅
   页面顶部需要一条比 <div class="card"> 更轻、更像「钱包」的横幅。
   -------------------------------------------------------------------------- */
.cp-balance {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle);
  background: var(--tint-brand),
    var(--bg-surface);
  box-shadow: var(--shadow-sm);
}

.cp-balance__icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-full);
  background: var(--bg-active);
  color: var(--brand-500);
}

.cp-balance__value {
  display: inline-flex;
  align-items: baseline;
  font-size: var(--text-3xl);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.cp-balance__unit {
  margin-left: 4px;
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text-secondary);
}

/* --------------------------------------------------------------------------
   券卡片
   比普通 .card 更紧凑、更像「一张券」：顶部品牌色票边 + 虚线分隔的操作区。
   -------------------------------------------------------------------------- */
.cp-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

/* 顶部票边（券面识别用的装饰条，纯装饰不承载信息） */
.cp-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--fill-brand);
}

.cp-card:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--brand-400) 32%, var(--border-default));
  box-shadow: var(--shadow-md);
}

/* 已使用 / 已过期：整体降权，不再有「可点」的暗示 */
.cp-card--muted {
  background: var(--bg-muted);
  border-style: dashed;
  box-shadow: none;
}

.cp-card--muted::before {
  background: var(--border-strong);
}

.cp-card--muted:hover {
  transform: none;
  border-color: var(--border-default);
  box-shadow: var(--shadow-xs);
}

.cp-card--muted .cp-card__title {
  color: var(--text-secondary);
}

.cp-card--muted .cp-card__badges,
.cp-card--muted .cp-card__meta,
.cp-card--muted .cp-price {
  opacity: 0.72;
}

.cp-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.cp-card__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--text-lg);
  font-weight: 650;
  line-height: 1.35;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

/* 券样式徽章：徽章本身沿用 .badge，这里只做卡片内的紧凑化与换行 */
.cp-card__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.cp-card__badges .badge {
  padding: 2px 8px;
  font-size: var(--text-xs);
}

.cp-card__desc {
  font-size: var(--text-sm);
  line-height: 1.7;
  color: var(--text-secondary);
}

.cp-card__note {
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border-left: 3px solid var(--brand-400);
  border-radius: var(--radius-sm);
  background: var(--bg-muted);
  font-size: var(--text-sm);
  line-height: 1.7;
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

.cp-card--muted .cp-card__note {
  border-left-color: var(--text-tertiary);
}

/* 库存 / 到期等元信息 */
.cp-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.cp-card__meta-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.cp-card__meta-item svg {
  flex-shrink: 0;
  color: var(--text-tertiary);
}

/* 库存不足 / 即将到期等需要提醒的元信息（页面按需加到 .cp-card__meta-item 上） */
.cp-card__meta-item--warn {
  color: var(--warning);
  font-weight: 600;
}

.cp-card__meta-item--danger {
  color: var(--danger);
  font-weight: 600;
}

/* 剩余 ≤3 天：警告色；已过期：危险色 */
.cp-expiry--warn {
  color: var(--warning);
  font-weight: 600;
}

.cp-expiry--danger {
  color: var(--danger);
  font-weight: 600;
}

/* 券价格（行规分）：金额右对齐、品牌色、等宽数字 */
.cp-price {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 6px;
}

.cp-price__value {
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--brand-500);
}

.cp-price__unit {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

/* 卡片操作区：主操作整行 + 下方一行灰色说明（可用 / 不可用都能看清原因） */
.cp-card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 1px dashed var(--border-default);
}

.cp-card__actions .btn {
  flex: 1 1 100%;
  justify-content: center;
}

/* 商城卡片按钮态：可兑换为主按钮，其余状态（未开始 / 已结束 / 已兑完 / 已拥有 / 行规分不足）
   都是 disabled 的次按钮，这里让它明确「看得见但点不动」 */
.cp-card__actions .btn[disabled],
.cp-card__actions .btn:disabled {
  opacity: 0.72;
  box-shadow: none;
  cursor: not-allowed;
}

.cp-card__hint {
  flex: 1 1 100%;
  font-size: var(--text-xs);
  line-height: 1.65;
  color: var(--text-tertiary);
}

.cp-card__hint:empty {
  display: none;
}

/* --------------------------------------------------------------------------
   口令码等宽小标签（管理端券列表里的 code 列）
   -------------------------------------------------------------------------- */
.cp-code {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-xs);
  background: var(--bg-surface-sunken);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   口令码兑换：居中大卡片
   -------------------------------------------------------------------------- */
.cp-redeem {
  width: 100%;
  max-width: 620px;
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) var(--space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xl);
  background: var(--bg-surface);
  box-shadow: var(--shadow-md);
  text-align: center;
}

.cp-redeem__hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}

.cp-redeem__icon {
  display: grid;
  place-items: center;
  width: 78px;
  height: 78px;
  border: 2px dashed color-mix(in srgb, var(--brand-400) 42%, transparent);
  border-radius: var(--radius-full);
  background: var(--bg-active);
  color: var(--brand-500);
  box-shadow: var(--shadow-brand);
}

.cp-redeem__title {
  font-size: var(--text-2xl);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text-primary);
}

.cp-redeem__desc {
  max-width: 36ch;
  font-size: var(--text-sm);
  line-height: 1.7;
  color: var(--text-tertiary);
}

.cp-redeem__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-6);
  text-align: left;
}

/* 居中卡片里的字段：标签 / 提示 / 错误都居中，输入框保持满宽 */
.cp-redeem__field .field__label,
.cp-redeem__field .field__hint {
  justify-content: center;
  text-align: center;
}

.cp-redeem__field .field__error {
  justify-content: center;
  text-align: center;
}

.cp-redeem__submit {
  min-height: 54px;
  border-radius: var(--radius-md);
  font-size: var(--text-lg);
  font-weight: 650;
}

.cp-redeem__tips {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  max-width: 620px;
  margin: 0 auto;
}

.cp-redeem__tips-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-xs);
  line-height: 1.7;
  color: var(--text-tertiary);
}

.cp-redeem__tips-item svg {
  flex-shrink: 0;
  margin-top: 3px;
}

.cp-redeem__tips-item:first-child svg {
  color: var(--info);
}

.cp-redeem__tips-item:last-child svg {
  color: var(--warning);
}

/* --------------------------------------------------------------------------
   口令码大号输入框
   口令码是一串大写字母数字，需要一眼看清、居中、等宽，普通 .input 达不到。
   -------------------------------------------------------------------------- */
.cp-code-input {
  min-height: 62px;
  padding: var(--space-3) var(--space-4);
  border-width: 2px;
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-align: center;
  text-transform: uppercase;
}

.cp-code-input::placeholder {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: none;
}

/* --------------------------------------------------------------------------
   兑换成功结果卡片
   -------------------------------------------------------------------------- */
.cp-result {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-5);
  padding: var(--space-5);
  border: 1px solid color-mix(in srgb, var(--success) 34%, transparent);
  border-radius: var(--radius-lg);
  background: var(--success-soft);
  text-align: left;
}

.cp-result__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.cp-result__icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  background: var(--bg-surface);
  color: var(--success);
  box-shadow: var(--shadow-xs);
}

.cp-result__label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--success);
}

.cp-result__title {
  font-size: var(--text-lg);
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.cp-result__meta .info-item__value {
  font-size: var(--text-base);
  font-weight: 600;
}

.cp-result__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.cp-result__actions .btn {
  flex: 1 1 auto;
  justify-content: center;
}

/* --------------------------------------------------------------------------
   深色主题微调
   tokens 已经覆盖了绝大多数颜色；这里只调「品牌色底」的对比度
   （与 behavior.css 里 .bhv-wheel__icon 的处理保持一致）。
   -------------------------------------------------------------------------- */
[data-theme='dark'] .cp-redeem__icon,
[data-theme='dark'] .cp-balance__icon {
  background: color-mix(in srgb, var(--brand-500) 22%, transparent);
  border-color: color-mix(in srgb, var(--brand-400) 55%, transparent);
}

[data-theme='dark'] .cp-result__icon {
  background: color-mix(in srgb, var(--bg-surface) 88%, var(--success) 12%);
}

/* 窄屏：卡片与居中大卡片都收一收内边距，避免内容被挤压 */
@media (max-width: 560px) {
  .cp-card,
  .cp-redeem {
    padding: var(--space-4);
  }

  .cp-redeem {
    padding: var(--space-6) var(--space-4) var(--space-4);
  }

  .cp-balance {
    padding: var(--space-4);
  }

  .cp-code-input {
    font-size: var(--text-xl);
    letter-spacing: 0.1em;
  }
}
