.gv {
  /* 紫色系主色（竞技场底） */
  --gv-p1: #6c63ff;
  --gv-p2: #8b5cf6;
  --gv-p3: #4f46e5;
  --gv-p-deep: #2f2b8f;
  /* 毛玻璃 */
  --gv-glass: rgba(255, 255, 255, .15);
  --gv-glass2: rgba(255, 255, 255, .26);
  --gv-glass-line: rgba(255, 255, 255, .38);
  /* 深蓝描边 + 硬投影（题目卡 / 3D 按钮） */
  --gv-edge: #2b2a7a;
  --gv-hard: rgba(0, 0, 0, .2);
  --gv-hard2: rgba(0, 0, 0, .28);
  /* 紫底上的文字层级（白字，不用深灰 —— 深灰在紫底上根本看不清） */
  --gv-ink: #ffffff;
  --gv-ink2: rgba(255, 255, 255, .84);
  --gv-ink3: rgba(255, 255, 255, .58);
  /* 语义色 */
  --gv-ok: #22c55e;
  --gv-bad: #ef4444;
  --gv-gold: #fbbf24;
  --gv-warn: #f59e0b;
  /* 兼容旧名（game-view.js / build 胶水里还在用） */
  --gv-brand: #a78bfa;
  --gv-brand-soft: rgba(255, 255, 255, .18);
  --gv-brand-deep: #7c3aed;
  --gv-ok-soft: rgba(34, 197, 94, .22);
  --gv-bad-soft: rgba(239, 68, 68, .22);
  --gv-t1: #ffffff;
  --gv-t2: rgba(255, 255, 255, .84);
  --gv-t3: rgba(255, 255, 255, .58);
  --gv-bg: rgba(255, 255, 255, .12);
  --gv-card: rgba(255, 255, 255, .16);
  --gv-line: rgba(255, 255, 255, .3);
  --gv-r-card: 20px;
  --gv-r-item: 18px;
  --gv-r-opt: 14px;
  --gv-pad-x: 18px;
}

.gv *, .gv *::before, .gv *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

.gv button { font-family: inherit; font-size: inherit; color: inherit; background: none; border: 0; }

.gv .stack { display: flex; flex-direction: column; align-self: stretch; gap: 10px; }

.gv .col-center { display: flex; flex-direction: column; align-items: center; align-self: stretch; gap: 13px; }

.gv .bgfx { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }

.gv .bgfx i { position: absolute; display: block; opacity: .3;
  animation: gvFloat 14s ease-in-out infinite; }

.gv .bgfx .sh-circle { width: 96px; height: 96px; border-radius: 50%;
  background: rgba(255, 255, 255, .5); }

.gv .bgfx .sh-tri { width: 74px; height: 64px;
  background: rgba(255, 255, 255, .45);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%); }

.gv .bgfx .sh-star { width: 52px; height: 52px;
  background: rgba(251, 191, 36, .75);
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }

.gv .bgfx .sh-ring { width: 120px; height: 120px; border-radius: 50%;
  border: 10px solid rgba(255, 255, 255, .35); background: transparent; }

.gv .screen { position: relative; z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: calc(30px + env(safe-area-inset-top)) var(--gv-pad-x)
    calc(32px + env(safe-area-inset-bottom));
  gap: 0; }

.gv .hd { display: flex; flex-direction: row; align-items: flex-start; align-self: stretch; gap: 11px; }

.gv .hd-close { display: flex; align-items: center; justify-content: center; flex: none;
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(255, 255, 255, .18); border: 1px solid var(--gv-glass-line); padding: 0; cursor: pointer; }

.gv .hd-close svg { width: 16px; height: 16px; display: block; stroke: #fff; }

.gv .hd-tt { display: flex; flex-direction: column; flex: 1; gap: 3px; min-width: 0; }

.gv .hd-title { margin: 0; font-size: 19px; line-height: 25px; font-weight: 800; color: var(--gv-ink); }

.gv .hd-sub { margin: 0; font-size: 12px; line-height: 16px; font-weight: 400; color: var(--gv-ink3); }

.gv .hd-title.is-ok { color: #4ade80; }

.gv .hd-title.is-bad { color: #fca5a5; }

.gv .steps { display: flex; flex-direction: row; align-items: center; align-self: stretch; gap: 7px; }

.gv .step { display: flex; align-items: center; justify-content: center; flex: 1;
  height: 32px; border-radius: 999px; background: rgba(255, 255, 255, .14);
  font-size: 12px; font-weight: 600; color: var(--gv-ink3); }

.gv .step.done { color: var(--gv-ink2); }

.gv .step.now { background: #fff; color: var(--gv-p3); font-weight: 800; }

.gv .card { display: flex; flex-direction: column; align-self: stretch; border-radius: var(--gv-r-card); }

.gv .card.soft { background: var(--gv-bg); }

.gv .match { display: flex; flex-direction: column; align-items: center; align-self: stretch; gap: 18px; padding: 26px 0; }

.gv .match-radar { position: relative; width: 168px; height: 168px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .28);
  display: flex; align-items: center; justify-content: center; }

.gv .match-radar b { position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .55);
  animation: gvRadar 1.6s ease-out infinite; opacity: 0; }

.gv .match-radar b:nth-child(2) { animation-delay: .5s; }

.gv .match-radar b:nth-child(3) { animation-delay: 1s; }

.gv .match-av { display: flex; align-items: center; justify-content: center;
  width: 74px; height: 74px; border-radius: 50%;
  background: #fff; font-size: 38px; line-height: 1;
  box-shadow: 0 6px 0 var(--gv-hard); }

.gv .match-t { margin: 0; font-size: 17px; line-height: 23px; font-weight: 800; color: var(--gv-ink); }

.gv .match-s { margin: 0; font-size: 12px; line-height: 17px; color: var(--gv-ink3); text-align: center; }

.gv .match-tick { font-size: 12px; font-weight: 700; color: var(--gv-gold); }

.gv .arena { display: flex; flex-direction: row; align-items: center; align-self: stretch; justify-content: space-between; }

.gv .side { display: flex; flex-direction: column; align-items: center; gap: 9px; }

.gv .avatar { display: flex; align-items: center; justify-content: center; flex: none;
  width: 64px; height: 64px; border-radius: 50%;
  background: #fff; border: 3px solid var(--gv-edge); box-shadow: 0 4px 0 var(--gv-hard);
  font-size: 32px; }

.gv .side.me .avatar { background: #fff; }

.gv .side-name { font-size: 13px; line-height: 19px; font-weight: 600; color: var(--gv-ink2); }

.gv .side.me .side-name { color: var(--gv-ink); }

.gv .hand { display: flex; align-items: center; justify-content: center; flex: none;
  width: 126px; height: 126px; border-radius: 19px;
  background: var(--gv-glass); border: 3px solid var(--gv-edge); box-shadow: 0 6px 0 var(--gv-hard);
  font-size: 62px; line-height: 1; }

.gv .hand.q { color: rgba(255, 255, 255, .45); font-weight: 700; }

.gv .hand.hero { background: var(--gv-glass2); border-color: #fff; }

.gv .vs-col { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: none; width: 53px; }

.gv .vs { font-size: 24px; line-height: 29px; font-weight: 800; color: var(--gv-gold); }

.gv .rps-hint { margin: 0; align-self: stretch; text-align: center; font-size: 12px; line-height: 16px; font-weight: 500; color: var(--gv-ink2); }

.gv .throw { display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 16px; }

.gv .throw button { display: flex; align-items: center; justify-content: center; flex: none;
  width: 72px; height: 72px; border-radius: 50%;
  background: #fff; border: 0; font-size: 36px; padding: 0; cursor: pointer;
  box-shadow: 0 5px 0 var(--gv-hard2);
  transition: transform .1s ease; }

.gv .throw button:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--gv-hard2); }

.gv .throw button.sel { width: 86px; height: 86px; font-size: 44px; background: #fff; border: 3px solid var(--gv-gold); }

.gv .throw button:disabled { opacity: .55; }

.gv .grid { display: flex; flex-direction: row; flex-wrap: wrap; align-self: stretch; gap: 9px; }

.gv .item { display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between;
  width: calc((100% - 9px) / 2); min-height: 128px; padding: 12px;
  border-radius: var(--gv-r-item);
  background: var(--gv-glass); border: 3px solid var(--gv-edge); box-shadow: 0 5px 0 var(--gv-hard);
  gap: 5px; cursor: pointer; text-align: left; }

.gv .item .ico { display: flex; align-items: center; justify-content: center; flex: none;
  width: 29px; height: 29px; border-radius: 50%; background: #fff; font-size: 16px; }

.gv .item .nm { font-size: 13px; line-height: 17px; font-weight: 700; color: var(--gv-ink); }

.gv .item .ds { font-size: 11px; line-height: 14px; font-weight: 400; color: var(--gv-ink2); }

.gv .item .tag { display: inline-flex; align-items: center; height: 15px; padding: 0 7px;
  border-radius: 999px; background: rgba(255, 255, 255, .3); color: var(--gv-ink);
  font-size: 9px; font-weight: 600; }

.gv .item.sel { background: var(--gv-glass2); border-color: #fff; }

.gv .item.sel .ico { background: var(--gv-gold); }

.gv .item.sel .tag { background: var(--gv-gold); color: #4f46e5; }

.gv .vsbar { display: flex; flex-direction: row; align-items: stretch; align-self: stretch; gap: 6px;
  padding: 10px 12px; border-radius: var(--gv-r-item);
  background: var(--gv-glass); border: 3px solid var(--gv-edge); box-shadow: 0 6px 0 var(--gv-hard); }

.gv .vside { display: flex; flex-direction: column; align-items: center; gap: 3px; flex: 1; min-width: 0; }

.gv .vside .vav { display: flex; align-items: center; justify-content: center; flex: none;
  width: 40px; height: 40px; border-radius: 50%; background: #fff; font-size: 21px;
  border: 2px solid rgba(0, 0, 0, .12); }

.gv .vside.op .vav { background: #fff; }

.gv .vside .vn { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11px; line-height: 15px; font-weight: 600; color: var(--gv-ink2); }

.gv .vside .vsc { font-size: 19px; line-height: 23px; font-weight: 800; color: var(--gv-ink); }

.gv .vside .vsc-u { font-size: 10px; font-weight: 600; color: var(--gv-ink3); margin-left: 2px; }

.gv .vside.me .vsc { color: var(--gv-gold); }

.gv .dots { display: flex; flex-direction: row; gap: 3px; justify-content: center; flex-wrap: wrap; }

.gv .dots i { display: block; width: 6px; height: 6px; border-radius: 50%;
  background: rgba(255, 255, 255, .28); }

.gv .dots i.on { background: var(--gv-ok); }

.gv .dots i.no { background: var(--gv-bad); }

.gv .dots i.op { background: var(--gv-gold); }

.gv .vmid { display: flex; flex-direction: column; align-items: center; justify-content: center;
  flex: none; width: 62px; gap: 3px; }

.gv .vmid .vs { font-size: 17px; line-height: 21px; font-weight: 800; color: var(--gv-gold); letter-spacing: 1px; }

.gv .vmid .opstat { font-size: 9px; line-height: 12px; font-weight: 600; color: var(--gv-ink3);
  text-align: center; max-width: 62px; }

.gv .combo { display: inline-flex; align-items: center; height: 17px; padding: 0 8px;
  border-radius: 999px; background: var(--gv-gold); color: #4f46e5;
  font-size: 9px; font-weight: 800; white-space: nowrap; }

.gv .timer { display: flex; flex-direction: row; align-items: center; align-self: stretch; gap: 9px; }

.gv .timer-track { flex: 1; height: 12px; border-radius: 999px; overflow: hidden;
  background: rgba(0, 0, 0, .22); border: 1px solid rgba(255, 255, 255, .22); }

.gv .timer-fill { height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #34d399, #22c55e);
  transition: width .1s linear; }

.gv .timer-fill.low { background: linear-gradient(90deg, #f87171, #ef4444); animation: gvPulse .6s ease-in-out infinite; }

.gv .timer-num { font-size: 13px; line-height: 17px; font-weight: 800; color: #fff; min-width: 34px; text-align: right; }

.gv .timer-num.low { color: var(--gv-bad); animation: gvPulse .6s ease-in-out infinite; }

.gv .qbox { padding: 15px 16px; border-radius: var(--gv-r-card); align-self: stretch;
  background: var(--gv-glass); border: 3px solid var(--gv-edge);
  box-shadow: 0 6px 0 var(--gv-hard);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  animation: gvIn .3s ease both; }

.gv .qt { margin: 0; font-size: 15px; line-height: 22px; font-weight: 700; color: var(--gv-ink); }

.gv .qimg { display: block; width: 100%; max-height: 118px; object-fit: contain;
  border-radius: 10px; background: #fff; margin-top: 9px; }

.gv .qtip { margin: 7px 0 0; font-size: 11px; line-height: 15px; color: var(--gv-gold); }

.gv .opts { display: flex; flex-direction: column; align-self: stretch; gap: 9px; }

.gv .opt { position: relative;
  display: flex; flex-direction: row; align-items: center; gap: 10px; align-self: stretch;
  min-height: 52px; padding: 0 13px; border-radius: var(--gv-r-opt);
  background: linear-gradient(180deg, #ffffff, #ece9ff);
  color: #241f5e; border: 0; cursor: pointer; text-align: left;
  box-shadow: 0 4px 0 var(--gv-hard2);
  transition: transform .08s ease, box-shadow .08s ease; }

.gv .opt:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--gv-hard2); }

.gv .opt-k { display: flex; align-items: center; justify-content: center; flex: none;
  width: 27px; height: 27px; border-radius: 50%;
  background: var(--gv-p3); color: #fff;
  font-size: 12px; font-weight: 800; }

.gv .opt-v { flex: 1; font-size: 13px; line-height: 17px; font-weight: 600; color: #241f5e; }

.gv .opt-mark { display: inline-flex; align-items: center; flex: none; height: 17px; padding: 0 8px;
  border-radius: 999px; font-size: 9px; font-weight: 700; color: #fff; }

.gv .opt.sel { background: linear-gradient(180deg, #fde68a, #fbbf24); }

.gv .opt.sel .opt-k { background: #4f46e5; }

.gv .opt.ok { background: linear-gradient(180deg, #86efac, #22c55e); }

.gv .opt.ok .opt-k { background: #15803d; }

.gv .opt.bad { background: linear-gradient(180deg, #fca5a5, #ef4444); }

.gv .opt.bad .opt-k { background: #b91c1c; }

.gv .opt.ok .opt-v, .gv .opt.bad .opt-v { color: #fff; }

.gv .opt-mark.ok { background: #15803d; }

.gv .opt-mark.bad { background: #b91c1c; }

.gv .opt.shake { animation: gvShake .6s ease both; }

.gv .opt.pop { animation: gvPop .45s cubic-bezier(.34, 1.56, .64, 1) both; }

.gv .floatscore { position: absolute; right: 12px; top: -6px; z-index: 5;
  font-size: 19px; font-weight: 900; color: var(--gv-gold);
  text-shadow: 0 2px 0 rgba(0, 0, 0, .35);
  pointer-events: none; animation: gvFloatUp 1s ease-out both; }

.gv .fb { align-self: stretch; display: flex; flex-direction: column; gap: 9px;
  padding: 13px 15px; border-radius: var(--gv-r-item);
  animation: gvIn .3s ease both; }

.gv .fb.ok { background: var(--gv-ok-soft); border: 2px solid var(--gv-ok); }

.gv .fb.bad { background: var(--gv-bad-soft); border: 2px solid var(--gv-bad); }

.gv .fb-row { display: flex; flex-direction: row; align-items: center; justify-content: space-between; align-self: stretch; }

.gv .fb-l { display: flex; flex-direction: row; align-items: center; gap: 7px; }

.gv .fb-ico { display: flex; align-items: center; justify-content: center; flex: none; width: 26px; height: 26px; border-radius: 50%; }

.gv .fb.ok .fb-ico { background: var(--gv-ok); }

.gv .fb.bad .fb-ico { background: var(--gv-bad); }

.gv .fb-ico svg { width: 14px; height: 14px; display: block; }

.gv .fb-t { font-size: 16px; line-height: 20px; font-weight: 800; }

.gv .fb.ok .fb-t { color: #bbf7d0; }

.gv .fb.bad .fb-t { color: #fecaca; }

.gv .fb-g { font-size: 22px; line-height: 26px; font-weight: 900; }

.gv .fb.ok .fb-g { color: var(--gv-ok); }

.gv .fb.bad .fb-g { color: var(--gv-bad); }

.gv .fb-pills { display: flex; flex-direction: row; flex-wrap: wrap; gap: 5px; }

.gv .fb-pill { display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
  border-radius: 999px; background: rgba(255, 255, 255, .2);
  font-size: 9px; font-weight: 600; color: #fff; }

.gv .fb.ok .fb-pill { color: #dcfce7; }

.gv .fb.bad .fb-pill { color: #fee2e2; }

.gv .myitems { display: flex; flex-direction: row; align-items: center; align-self: stretch;
  gap: 9px; min-height: 44px; padding: 0 13px; border-radius: var(--gv-r-opt);
  background: var(--gv-glass); border: 2px solid var(--gv-glass-line); }

.gv .myitems .lb { font-size: 10px; font-weight: 500; color: var(--gv-ink2); flex: none; }

.gv .chip { display: inline-flex; align-items: center; gap: 5px; flex: none;
  height: 27px; padding: 0 10px; border-radius: 999px;
  background: #fff; border: 0; font-size: 10px; font-weight: 700; color: #241f5e; cursor: pointer;
  box-shadow: 0 3px 0 var(--gv-hard2); }

.gv .chip:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--gv-hard2); }

.gv .chip.used { opacity: .5; }

.gv .chip.used .chip-n { text-decoration: line-through; }

.gv .chip .chip-i { font-size: 13px; }

.gv .res { position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  align-self: stretch; gap: 13px; padding: 34px 16px; border-radius: var(--gv-r-card);
  background: var(--gv-glass); border: 3px solid var(--gv-edge); box-shadow: 0 6px 0 var(--gv-hard); }

.gv .res-ico { font-size: 74px; line-height: 1; animation: gvDrop .8s cubic-bezier(.34, 1.56, .64, 1) both; }

.gv .res-t { font-size: 28px; line-height: 36px; font-weight: 900; color: var(--gv-gold); }

.gv .res-d { font-size: 12px; line-height: 16px; font-weight: 600; color: var(--gv-ink2); }

.gv .res-scores { display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 16px; }

.gv .res-s { display: flex; flex-direction: column; align-items: center; gap: 3px; }

.gv .res-s-n { font-size: 12px; line-height: 16px; font-weight: 600; color: var(--gv-ink2); }

.gv .res-s-v { font-size: 29px; line-height: 35px; font-weight: 900; color: var(--gv-ink); }

.gv .res-s-v.me { color: var(--gv-gold); }

.gv .res-colon { font-size: 19px; line-height: 24px; font-weight: 800; color: var(--gv-ink3); }

.gv .stats { display: flex; flex-direction: row; align-self: stretch; gap: 7px; }

.gv .stat { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1;
  min-height: 70px; border-radius: var(--gv-r-opt);
  background: var(--gv-glass); border: 2px solid var(--gv-glass-line); gap: 3px; }

.gv .stat-v { font-size: 19px; line-height: 23px; font-weight: 800; color: var(--gv-ink); }

.gv .stat-n { font-size: 10px; line-height: 13px; font-weight: 500; color: var(--gv-ink2); }

.gv .confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 3; }

.gv .confetti i { position: absolute; top: -14px; display: block; width: 8px; height: 14px; border-radius: 2px;
  animation: gvConfetti 2.2s linear infinite; }

.gv .confetti b { position: absolute; top: -28px; display: block; width: 22px; height: 22px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fde68a, #f59e0b);
  box-shadow: 0 2px 0 rgba(0, 0, 0, .2);
  animation: gvDrop 2s cubic-bezier(.4, .1, .8, .9) infinite; }

.gv .btns { display: flex; flex-direction: row; align-self: stretch; gap: 9px; }

.gv .btn { display: flex; align-items: center; justify-content: center; flex: 1;
  height: 48px; border-radius: 999px; border: 0; padding: 0;
  font-size: 15px; font-weight: 800; cursor: pointer;
  transition: transform .1s ease, box-shadow .1s ease; }

.gv .btn:active { transform: translateY(3px); }

.gv .btn.primary { background: linear-gradient(180deg, #fbbf24, #f59e0b); color: #3b2a00;
  box-shadow: 0 4px 0 rgba(0, 0, 0, .28); }

.gv .btn.primary:active { box-shadow: 0 1px 0 rgba(0, 0, 0, .28); }

.gv .btn.ghost { background: rgba(255, 255, 255, .18); border: 2px solid var(--gv-glass-line);
  color: #fff; font-weight: 700; box-shadow: 0 4px 0 var(--gv-hard); }

.gv .btn.ghost:active { box-shadow: 0 1px 0 var(--gv-hard); }

.gv .btn[disabled] { opacity: .45; }

.gv .btn.wide { align-self: stretch; flex: none; width: 100%; }

.gv .toast.on { opacity: 1; }

[dir="rtl"] .gv .hd, [dir="rtl"] .gv .opt, [dir="rtl"] .gv .fb-row, [dir="rtl"] .gv .fb-l, [dir="rtl"] .gv .myitems, [dir="rtl"] .gv .timer, [dir="rtl"] .gv .vsbar, [dir="rtl"] .gv .throw, [dir="rtl"] .gv .grid, [dir="rtl"] .gv .stats, [dir="rtl"] .gv .btns, [dir="rtl"] .gv .dots, [dir="rtl"] .gv .res-scores { flex-direction: row-reverse; }

[dir="rtl"] .gv .vside { align-items: center; }

[dir="rtl"] .gv .timer-num { text-align: left; }

[dir="rtl"] .gv .fb-pills { flex-direction: row-reverse; }

[dir="rtl"] .gv .floatscore { right: auto; left: 12px; }

[dir="rtl"] .gv .item { align-items: flex-start; }

/* ============================================================
   以下是接进主站才需要的部分（game.src.css 里没有）
   ============================================================ */

/* 外壳：#app 是 app.css 的容器（max-width 520、灰底、阴影）。
   游戏两页要变成 414 宽的手机壳；第六批起壳底是紫色渐变（竞技场）。
   【这里必须写字面量，不能写 var(--gv-*)】——
   #app 是 .gv 的父节点，自定义属性只往下继承，父节点取不到子节点上的变量，
   结果是 var() 失效、背景退回 body 的灰色（踩过：整页灰底，白卡片浮在灰底上）。 */
body.in-game #app {
  max-width: 414px;
  background: linear-gradient(160deg, #6c63ff 0%, #8b5cf6 52%, #4f46e5 100%);
  box-shadow: none;
}
/* 渐变要同时铺到 body 上：只铺 #app 的话，游戏页一滚动（题库选择页就能滚），
   橡皮筋/越界回弹露出来的就是 app.css 那层灰底，非常突兀。 */
body.in-game {
  background: linear-gradient(160deg, #6c63ff 0%, #8b5cf6 52%, #4f46e5 100%);
}
/* 对局页底部有操作区、选择页底部有开始按钮，右下角浮动的字号条会压住它们 */
body.in-game .fontbar { display: none; }

/* .gv 顶上要撑满 #app（#app 是 flex column），.screen 的 flex:1 才有空间可吃。
   position:relative + overflow:hidden 是给 .bgfx 漂浮层和 .confetti 纸屑层做定位父级。 */
.gv {
  flex: 1; display: flex; flex-direction: column; min-height: 0;
  position: relative; overflow: hidden;
}

/* ============================================================
   动画 keyframes —— 只写在这里，不写进 game.src.css
   ------------------------------------------------------------
   原因：build-game-css.js 是按「最外层大括号」切块的正则，
   @keyframes 里的嵌套块（0% { ... }）会被当成独立规则切坏，
   生成出「.gv 0% { transform: ... }」这种废规则。
   下面这段是原样输出，不经过那道正则，所以可以放心写嵌套。
   命名全部 gv 开头，避免和 app.css 的动画重名。
   ============================================================ */
@keyframes gvFloat {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  50%  { transform: translate3d(14px, -26px, 0) rotate(18deg); }
  100% { transform: translate3d(0, 0, 0) rotate(0deg); }
}
@keyframes gvRadar {
  0%   { transform: scale(.35); opacity: .85; }
  100% { transform: scale(1); opacity: 0; }
}
/* 题目/反馈卡入场：从下方滑入 + 淡入 */
@keyframes gvIn {
  0%   { opacity: 0; transform: translateY(16px); }
  100% { opacity: 1; transform: translateY(0); }
}
/* 切换题目：旧题淡出上移、新题淡入上移（stagger 由 DOM 顺序 + 同动画制造） */
@keyframes gvSwap {
  0%   { opacity: .25; transform: translateY(12px); }
  100% { opacity: 1; transform: translateY(0); }
}
/* 答错：左右抖动 3 次（每次约 100ms，共 600ms） */
@keyframes gvShake {
  0%, 100% { transform: translateX(0); }
  16%  { transform: translateX(-9px); }
  33%  { transform: translateX(8px); }
  50%  { transform: translateX(-7px); }
  66%  { transform: translateX(6px); }
  83%  { transform: translateX(-3px); }
}
/* 答对：弹性放大到 1.05 再回落 */
@keyframes gvPop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}
/* 飘分 +10：上浮淡出 */
@keyframes gvFloatUp {
  0%   { opacity: 0; transform: translateY(6px) scale(.8); }
  25%  { opacity: 1; transform: translateY(-2px) scale(1.15); }
  100% { opacity: 0; transform: translateY(-38px) scale(1); }
}
/* 倒计时 ≤5s：脉冲 */
@keyframes gvPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.05); }
}
/* 胜利纸屑：从顶部飘落（带横向摆动 + 自转） */
@keyframes gvConfetti {
  0%   { opacity: 0; transform: translate3d(0, -20px, 0) rotate(0deg); }
  10%  { opacity: 1; }
  100% { opacity: 1; transform: translate3d(var(--gv-dx, 10px), 460px, 0) rotate(720deg); }
}
/* 奖杯 / 金币：从顶部掉落，落地轻弹 */
@keyframes gvDrop {
  0%   { opacity: 0; transform: translateY(-40px) scale(.6); }
  60%  { opacity: 1; transform: translateY(0) scale(1.08); }
  75%  { transform: translateY(-10px) scale(.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
/* 匹配等待：转圈 */
@keyframes gvSpin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* ---------- 选择页（game 视图）----------
   第六批：跟着对局页一起换成紫底毛玻璃，白字。卡片一律「半透明白 + 白描边」，
   不要再写死白色背景 —— 白卡片浮在紫底上会像贴纸。 */
.gv .gs-body {
  display: flex; flex-direction: column; align-self: stretch; gap: 9px;
  flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain; padding: 2px 0;
}
.gv .gs-card {
  display: flex; flex-direction: column; align-self: stretch; gap: 9px;
  padding: 15px 16px; border-radius: var(--gv-r-item);
  background: rgba(255, 255, 255, .14); border: 2px solid rgba(255, 255, 255, .3);
}
.gv .gs-sec { display: flex; flex-direction: row; align-items: baseline; gap: 6px; }
.gv .gs-sec-t { font-size: 13px; line-height: 17px; font-weight: 800; color: #ffffff; }
.gv .gs-sec-s { font-size: 9px; line-height: 13px; font-weight: 400; color: var(--gv-t3); }
.gv .gs-row { display: flex; flex-direction: row; flex-wrap: wrap; gap: 7px; }
.gv .gs-chip {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  min-height: 32px; padding: 0 13px; border-radius: 999px;
  background: rgba(255, 255, 255, .16); border: 1px solid rgba(255, 255, 255, .26);
  font-size: 12px; font-weight: 600; color: var(--gv-t2); cursor: pointer;
}
.gv .gs-chip.on {
  background: #ffffff; border-color: #ffffff;
  color: #4f46e5; font-weight: 800;
}
.gv .gs-meta {
  display: flex; flex-direction: row; align-items: center; justify-content: space-between;
  align-self: stretch; gap: 7px; padding-top: 9px; border-top: 1px solid rgba(255, 255, 255, .22);
  font-size: 10px; line-height: 14px; color: var(--gv-t3);
}
.gv .gs-tip {
  align-self: stretch; padding: 9px 11px; border-radius: 10px;
  background: rgba(251, 191, 36, .22); color: #fde68a; font-size: 10px; line-height: 15px;
}
.gv .gs-rule { align-self: stretch; font-size: 11px; line-height: 17px; color: var(--gv-t2); }
.gv .gs-items { display: flex; flex-direction: row; flex-wrap: wrap; align-self: stretch; gap: 7px; }
.gv .gs-item {
  display: flex; flex-direction: column; gap: 3px; width: calc((100% - 14px) / 3);
  padding: 9px 8px; border-radius: 12px; background: rgba(255, 255, 255, .14);
}
.gv .gs-item.atk { background: rgba(239, 68, 68, .22); }
.gv .gs-i-ic { font-size: 17px; line-height: 20px; }
.gv .gs-i-nm { font-size: 10px; line-height: 13px; font-weight: 700; color: #ffffff; }
.gv .gs-i-ds { font-size: 9px; line-height: 12px; color: var(--gv-t2); }
.gv .gs-kv { display: flex; flex-direction: row; align-self: stretch; gap: 7px; }
.gv .gs-kv-i {
  display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1;
  gap: 2px; min-height: 56px; border-radius: 12px; background: rgba(255, 255, 255, .14);
}
.gv .gs-kv-v { font-size: 17px; line-height: 21px; font-weight: 900; color: #ffffff; }
.gv .gs-kv-v.win { color: #4ade80; }
.gv .gs-kv-v.best { color: var(--gv-gold); }
.gv .gs-kv-n { font-size: 9px; line-height: 12px; color: var(--gv-t2); }
.gv .gs-last {
  display: flex; flex-direction: row; align-items: center; justify-content: space-between;
  align-self: stretch; gap: 7px; padding-top: 9px; border-top: 1px solid rgba(255, 255, 255, .22);
  font-size: 10px; line-height: 14px; color: var(--gv-t2);
}
.gv .gs-diff { font-size: 13px; line-height: 17px; font-weight: 900; }
.gv .gs-diff.up { color: #4ade80; }
.gv .gs-diff.dn { color: #fca5a5; }
.gv .gs-foot { display: flex; flex-direction: column; align-self: stretch; gap: 7px; }

/* ---------- 自绘确认弹窗 ----------
   移动端浏览器 / 微信内核会直接拦掉原生 confirm()，表现是「点了没反应」且不报错，
   所以退出对局这种确认一律用页面内自绘。 */
.gv .gvc {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(26, 26, 26, .45);
  display: flex; flex-direction: column; justify-content: center; align-items: stretch;
  padding: 0 32px;
}
.gv .gvc-box {
  display: flex; flex-direction: column; gap: 16px;
  padding: 20px 18px; border-radius: var(--gv-r-item);
  background: #ffffff; border: 3px solid var(--gv-edge); box-shadow: 0 6px 0 var(--gv-hard);
}
.gv .gvc-msg { margin: 0; font-size: 13px; line-height: 19px; color: #1a1a1a; }
.gv .gvc-btns { display: flex; flex-direction: row; gap: 8px; }

/* ---------- RTL 补充（game.src.css 里没有的选择页 / 弹窗）---------- */
[dir="rtl"] .gv .gs-row,
[dir="rtl"] .gv .gs-kv,
[dir="rtl"] .gv .gs-meta,
[dir="rtl"] .gv .gs-last,
[dir="rtl"] .gv .gs-sec,
[dir="rtl"] .gv .gvc-btns { flex-direction: row-reverse; }
[dir="rtl"] .gv .gs-item { text-align: right; }
