/* 小丑纸牌（/lab/balatro）的样式。
   这一页不加载 site.css —— 实验区的页面各自独立，只需要 _lab.css 那个返回入口。
   纸和墨那两个颜色在这里自己定义一次，和站点保持一致。

   原来的版本是深绿绒布 + 金色肉感描边字 + 硬投影，是街机那种味道。
   这版按站点的纸墨语言重做：卡片是白纸、边界是一根细线、主角换成衬线体，
   阴影只留一点点「纸叠在纸上」的厚度。

   只有两处保留实色：筹码的蓝和倍率的红。整页都在灰阶里的时候，
   这两个数是玩家唯一需要一眼跳出来的东西，所以它们值得破例。

   类名一个都没动 —— 页面里大半的 class 是 JS 用模板字符串拼出来的，
   改名要动逻辑；换掉的只是变量和选择器。 */

:root {
  --paper: #f7f3eb;
  --ink: #171411;
  --ink-80: #171411d1;
  --ink-70: #171411b3;
  --ink-60: #1714119e;
  --ink-55: #1714118c;
  --rule: #1714111f;
  --rule-strong: #1714114d;
  /* 比纸再白一点：卡片要能从纸上浮起来，同色就糊成一片了 */
  --card: #fffdf8;
  --table: #fbf8f1;
  /* 下面这几个全部取自站点已经在用的那套低饱和色 */
  --chip: #3f5f7a;
  --mult: #b4452f;
  --ochre: #8a5a2b;
  --ok: #2f6b4f;
  --uncommon: #2f6f5e;
  --rare: #993c1d;
  --serif: Georgia, 'Iowan Old Style', 'Times New Roman', serif;
  --sans: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
  /* 手牌宽度。8 张牌要能在一行里排开，所以上限压到 92px —— 再大中间那栏
     就会折行，出牌区一折行高度就跳，一局里跳好几次很晃眼。 */
  --cw: clamp(52px, 5.5vw, 92px);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html,
body { height: 100%; }

body {
  background-color: var(--paper);
  /* 纸的纹理：顶上一点光 + 横向帘纹 + 竖向网纹。三层都压到 1% 出头，
     单看哪一层都说不出来，合起来才让底色不像一块纯色填充。 */
  background-image:
    radial-gradient(ellipse 90% 55% at 50% 0%, rgba(255, 255, 255, 0.5), transparent 65%),
    repeating-linear-gradient(0deg, rgba(23, 20, 17, 0.014) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, rgba(23, 20, 17, 0.01) 0 1px, transparent 1px 5px);
  color: var(--ink);
  font-family: var(--serif);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden; /* 桌面是三栏一屏，滚动条会在拖牌的时候误触 */
}

/* .chunky / .chunky-sm 是原来那套肉感描边字。纸墨风里没有对应的东西，
   但这两个类名被模板字符串到处在用（弹层标题、分数大字），删掉要动 JS，
   于是就地留成近似空规则：真正决定字号字重的，是它们所在元素自己的规则。 */
.chunky,
.chunky-sm { letter-spacing: normal; }

/* =========================================================
   页面外壳
   ========================================================= */
.bl-page {
  display: flex;
  flex-direction: column;
  height: 100%;
  max-width: 1360px;
  margin: 0 auto;
  padding: 0 20px;
}

.bl-head {
  flex: 0 0 auto;
  padding: 18px 0 13px;
  border-bottom: 1px solid var(--rule);
}

.bl-head h1 {
  margin: 8px 0 0;
  font-size: 1.45rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.bl-lede {
  max-width: 46em;
  margin: 7px 0 0;
  color: var(--ink-70);
  font-size: 0.9rem;
  line-height: 1.65;
}

/* =========================================================
   牌桌：三栏
   ========================================================= */
.board {
  display: grid;
  grid-template-columns: 206px minmax(0, 1fr) 236px;
  gap: 14px;
  flex: 1;
  min-height: 0;
  padding: 16px 0;
}

.col { display: flex; flex-direction: column; gap: 11px; min-height: 0; }
.spacer { flex: 1; min-height: 0; }

/* 分数够高 / 打了不该打的牌时整块桌子抖一下 */
.board.shake { animation: shake 0.42s cubic-bezier(0.36, 0.07, 0.19, 0.97); }
@keyframes shake {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  15% { transform: translate(-7px, 3px) rotate(-0.5deg); }
  30% { transform: translate(6px, -4px) rotate(0.5deg); }
  45% { transform: translate(-5px, 2px) rotate(-0.35deg); }
  60% { transform: translate(4px, -2px) rotate(0.25deg); }
  80% { transform: translate(-2px, 1px) rotate(-0.1deg); }
}

.panel {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(23, 20, 17, 0.035);
}

/* =========================================================
   左栏：盲注 / 本轮进度 / 次数
   ========================================================= */
/* 小 / 大 / Boss 用一个色标区分：三关的目标和奖励都不一样，
   光看数字得先读一遍字，看一眼颜色就知道现在是哪种。 */
.blind { padding: 13px 14px; border-left-width: 3px; }
.blind[data-blind="small"] { border-left-color: var(--chip); }
.blind[data-blind="big"] { border-left-color: var(--ochre); }
.blind[data-blind="boss"] { border-left-color: var(--mult); }

.blind .ante {
  display: inline-block;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-55);
}

.blind .bname {
  margin: 6px 0 0;
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.2;
}

/* Boss 的说明只在 Boss 关出现，留个最小高度，免得其余关卡面板忽高忽低 */
.blind .btip {
  min-height: 1.3em;
  margin-top: 3px;
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--ochre);
}

.blind .bgoal {
  margin-top: 12px;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-55);
}

.blind .bgoal b {
  display: block;
  font-family: var(--serif);
  font-size: 1.7rem;
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1.15;
  color: var(--ink);
}

.blind .breward {
  display: inline-block;
  margin-top: 10px;
  padding: 3px 10px;
  border: 1px solid rgba(138, 90, 43, 0.4);
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 0.72rem;
  color: var(--ochre);
}

.round { padding: 13px 14px; }

.round .lab {
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-55);
}

.round .num { font-size: 2rem; font-weight: 600; line-height: 1.15; }

.round .tgt {
  font-family: var(--sans);
  font-size: 0.74rem;
  color: var(--ink-55);
}

.round.hit { animation: hitpulse 0.5s ease; }
@keyframes hitpulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.04); }
  100% { transform: scale(1); }
}

.mini { display: flex; flex-direction: column; gap: 6px; }

.minirow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 12px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 8px;
  font-family: var(--sans);
  font-size: 0.76rem;
  color: var(--ink-70);
}

.minirow b { font-family: var(--serif); font-size: 1.15rem; font-weight: 600; color: var(--ink); }
.minirow.gold { border-color: rgba(138, 90, 43, 0.32); }
.minirow.gold b { color: var(--ochre); }

/* =========================================================
   中间：出牌区 / 手牌 / 操作
   ========================================================= */
.center { min-width: 0; }

.playmat {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-height: 0;
  padding: 16px 16px 108px; /* 底下这块空出来给浮着的那两个分数框 */
  border: 1px solid var(--rule);
  border-radius: 10px;
  background-color: var(--table);
  /* 这块一开始是纯色，一屏里最大的一片区域就那么空着，看着像没加载出来。
     给一层几乎看不见的斜织纹 + 顶上一点光，空的地方也是「一张铺开的桌布」。 */
  background-image:
    radial-gradient(ellipse 70% 55% at 50% 0%, rgba(255, 255, 255, 0.55), transparent 70%),
    repeating-linear-gradient(135deg, rgba(23, 20, 17, 0.015) 0 1px, transparent 1px 7px);
}

/* 牌桌内圈那道印刷线：有它才像个「桌」，没有就是一块色块 */
.playmat::before {
  content: "";
  position: absolute;
  inset: 8px;
  border: 1px solid rgba(23, 20, 17, 0.085);
  border-radius: 6px;
  pointer-events: none;
}

.playarea {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  min-height: 40px;
}

.playarea .hint {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--sans);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-55);
}

/* 两侧各一条细线，把这句话摆成一块印在桌面上的标牌 */
.playarea .hint::before,
.playarea .hint::after {
  content: "";
  width: 30px;
  height: 1px;
  background: var(--rule-strong);
}

/* 空桌面：一个大到快要淡出纸面的目标分，压着下面那句提示 */
.emptytable {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.emptytable .ghost {
  font-size: clamp(2.6rem, 6vw, 4.6rem);
  font-weight: 600;
  line-height: 0.9;
  letter-spacing: -0.02em;
  color: var(--ink);
  opacity: 0.08;
}

.playarea .lead {
  margin-right: 6px;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ochre);
}

.scorepanel {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 4;
  display: flex;
  align-items: flex-start;
  gap: 9px;
}

.sbox {
  min-width: 86px;
  padding: 9px 13px 8px;
  border-radius: 8px;
  text-align: center;
  line-height: 1;
  position: relative;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}

.sbox .v { display: block; font-size: 1.9rem; font-weight: 600; line-height: 1.05; }

.sbox .k {
  display: block;
  margin-top: 4px;
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.8;
}

.sbox.chips { background: var(--chip); color: #f4f7fa; }
.sbox.mult { background: var(--mult); color: #fdf5f2; }
.sbox.bump { animation: bump 0.22s ease; }
@keyframes bump {
  0% { transform: scale(1); }
  40% { transform: scale(1.14) rotate(-1.5deg); }
  100% { transform: scale(1); }
}

.sx { align-self: center; font-size: 1.35rem; color: var(--ink-60); }

.scoretotal {
  position: absolute;
  left: 16px;
  bottom: 16px;
  transform: translateY(-78px);
  display: none;
  z-index: 4;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-55);
}

.scoretotal b {
  display: block;
  font-family: var(--serif);
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1.1;
  color: var(--ink);
}

.scoretotal.on { display: block; animation: totalin 0.4s ease; }
@keyframes totalin {
  0% { transform: translateY(-66px) scale(0.85); opacity: 0; }
  60% { transform: translateY(-80px) scale(1.06); }
  100% { transform: translateY(-78px) scale(1); opacity: 1; }
}

/* 加分飘字。原来靠一圈黑描边压在绒布上，纸底上那套会糊成一团黑边，
   改成深色字 + 一层纸色光晕：落在牌面上也读得清。 */
.pop {
  position: fixed;
  z-index: 90;
  font-size: 1.5rem;
  font-weight: 600;
  pointer-events: none;
  color: var(--ink);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.92), 0 1px 10px rgba(255, 255, 255, 0.95);
  animation: popup 0.85s ease forwards;
}

.pop.plus { color: var(--ok); }
.pop.x { color: var(--mult); }
@keyframes popup {
  0% { transform: translate(0, 0) scale(0.6); opacity: 0; }
  25% { transform: translate(0, -16px) scale(1.15); opacity: 1; }
  100% { transform: translate(0, -64px) scale(1); opacity: 0; }
}

.handinfo {
  min-height: 28px;
  padding: 2px 0;
  text-align: center;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
}

.handinfo .sub {
  margin-left: 10px;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--ochre);
}

.handinfo.idle {
  font-family: var(--sans);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-55);
}

.handarea {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: 7px;
  min-height: calc(var(--cw) * 1.42);
  /* 上面留出抬牌要用的那一截，不然选中的牌会盖住牌型提示 */
  padding: 26px 0 6px;
}

.actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 9px; padding-bottom: 4px; }

/* =========================================================
   扑克牌
   ========================================================= */
.card {
  --cw2: var(--cw);
  position: relative;
  width: var(--cw2);
  aspect-ratio: 5 / 7;
  flex: 0 0 auto;
  overflow: hidden;
  background: linear-gradient(168deg, #fffefa 0%, #faf4e6 58%, #f1e7d0 100%);
  border: 1px solid rgba(23, 20, 17, 0.34);
  border-radius: 6px;
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 1px 0 rgba(23, 20, 17, 0.07), 0 3px 8px rgba(23, 20, 17, 0.1);
  transition: transform 0.13s cubic-bezier(0.2, 1.5, 0.5, 1), box-shadow 0.13s;
}

/* 牌面里那一圈印刷细线——真扑克牌都有。少了它，一张牌就是个圆角白块。 */
.card::before {
  content: "";
  position: absolute;
  inset: 3px;
  z-index: 1;
  border: 1px solid rgba(23, 20, 17, 0.12);
  border-radius: 3px;
  pointer-events: none;
}

/* 点数和花色合成一组，左上、右下各放一组；右下那组转 180°，
   两个方向都能读 —— 这是扑克牌最好认的一个特征。 */
.idx {
  position: absolute;
  top: 3px;
  left: 5px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
}

.idx .rk {
  font-size: calc(var(--cw2) * 0.29);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.idx .su {
  margin-top: 1px;
  font-size: calc(var(--cw2) * 0.18);
  line-height: 1;
}

.card .big {
  position: absolute;
  left: 50%;
  top: 54%;
  transform: translate(-50%, -50%);
  z-index: 2;
  font-size: calc(var(--cw2) * 0.5);
  opacity: 0.9;
  line-height: 1;
}

/* 红桃方块用站点那个暗红，不是荧光红 —— 纸上的红墨水就是这个色 */
.card.red { color: var(--mult); }

/* 抬升的高度跟着牌宽走，不写死像素：手机上牌只有 40px 宽，
   固定抬 24px 会直接顶穿上面那行牌型提示。 */
.card:hover { transform: translateY(calc(var(--cw2) * -0.13)) rotate(-1.2deg); box-shadow: 0 6px 14px rgba(23, 20, 17, 0.16); }

/* 选中用一圈墨线，不用发光：印刷品没有辉光 */
.card.sel { transform: translateY(calc(var(--cw2) * -0.28)); box-shadow: 0 0 0 2px var(--ink), 0 7px 16px rgba(23, 20, 17, 0.16); }
.card.sel:hover { transform: translateY(calc(var(--cw2) * -0.33)); }

.card.inplay { cursor: default; }
.card.inplay:hover { transform: none; }

.card.small { --cw2: clamp(44px, 4vw, 68px); }
.card.mini { --cw2: 36px; }

.card.deal { animation: dealIn 0.34s cubic-bezier(0.2, 1.5, 0.5, 1) backwards; }
@keyframes dealIn {
  0% { transform: translateY(-140px) scale(0.5) rotate(-14deg); opacity: 0; }
  70% { opacity: 1; }
  100% { transform: translateY(0) scale(1) rotate(0); opacity: 1; }
}

.card.score-pop { animation: scorePop 0.34s cubic-bezier(0.2, 1.6, 0.5, 1); }
@keyframes scorePop {
  0% { transform: translateY(0) scale(1); }
  45% { transform: translateY(-30px) scale(1.18) rotate(2.5deg); box-shadow: 0 8px 18px rgba(23, 20, 17, 0.18), 0 0 0 2px var(--ink); }
  100% { transform: translateY(0) scale(1); }
}

.card.debuff { filter: grayscale(0.7) brightness(0.7); }
.card.debuff::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(45deg, rgba(153, 60, 29, 0.22) 0 7px, transparent 7px 15px);
}

.card.hi { box-shadow: 0 0 0 2px var(--ink-60), 0 4px 12px rgba(23, 20, 17, 0.14); }

/* =========================================================
   按钮
   ========================================================= */
.btn {
  padding: 10px 22px;
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  color: var(--paper);
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.15s;
}

.btn:hover:not(:disabled) { background: #000; border-color: #000; }
.btn:disabled { opacity: 0.3; cursor: not-allowed; }

.btn.red { background: var(--mult); border-color: var(--mult); color: #fdf5f2; }
.btn.red:hover:not(:disabled) { background: #9d3a26; border-color: #9d3a26; }

.btn.blue { background: var(--chip); border-color: var(--chip); color: #f4f7fa; }
.btn.blue:hover:not(:disabled) { background: #35516a; border-color: #35516a; }

.btn.ghost {
  padding: 8px 15px;
  background: transparent;
  border-color: var(--rule-strong);
  color: var(--ink-70);
  font-size: 0.75rem;
}

.btn.ghost:hover:not(:disabled) { background: rgba(23, 20, 17, 0.05); color: var(--ink); }

.btn.sm { padding: 8px 16px; font-size: 0.75rem; }

/* =========================================================
   右栏：金钱 / 小丑牌 / 玩法
   ========================================================= */
.moneybar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 14px;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 8px;
}

.moneybar .m-lab {
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-55);
}

.moneybar .m-val { font-size: 1.75rem; font-weight: 600; line-height: 1; color: var(--ochre); }
.moneybar.bump { animation: bump 0.3s ease; }

.jokerwrap { display: flex; flex-direction: column; flex: 1; min-height: 0; padding: 12px; }

.jokerwrap__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }

.jokerwrap__lab {
  padding: 0;
  border: 0;
  border-bottom: 1px dotted var(--rule-strong);
  background: none;
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-55);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.15s;
}

.jokerwrap__lab:hover {
  color: var(--ink);
}

/* 图鉴里按稀有度分段，每段一行小标题 */
.cattitle {
  margin: 18px 0 -4px;
  font-family: var(--sans);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-60);
}

.jokerlist { display: flex; flex-direction: column; gap: 8px; overflow: auto; padding-right: 3px; padding-bottom: 4px; }
.jokerlist::-webkit-scrollbar { width: 6px; }
.jokerlist::-webkit-scrollbar-thumb { background: var(--rule-strong); border-radius: 99px; }

/* 空位画成一张牌背：斜织纹 + 外圈留白 + 一道内线。
   原来是五个虚线框，一排摆下来像五个报错的占位符。 */
.jslot {
  position: relative;
  min-height: 80px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background-color: #f2ebdf;
  background-image:
    repeating-linear-gradient(45deg, rgba(23, 20, 17, 0.022) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(-45deg, rgba(23, 20, 17, 0.022) 0 1px, transparent 1px 5px);
  box-shadow: inset 0 0 0 3px #f8f4ec;
}

.jslot::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid rgba(23, 20, 17, 0.1);
  border-radius: 5px;
}

/* 稀有度用三个色阶：蓝 → 青 → 暗红。都是站点里已有的颜色，
   所以三张牌摆一起的时候是「深浅不一样」，而不是「三块荧光贴纸」。 */
.joker {
  position: relative;
  min-height: 72px;
  padding: 9px 11px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--chip);
  color: #f6fbf9;
  box-shadow: 0 1px 0 rgba(23, 20, 17, 0.08), 0 3px 10px rgba(23, 20, 17, 0.12);
  transition: transform 0.12s cubic-bezier(0.2, 1.5, 0.5, 1), box-shadow 0.12s;
}

.joker.uncommon { background: var(--uncommon); }
.joker.rare { background: var(--rare); }

/* 和扑克牌面上那圈内线同一套：小丑牌也该像一张印出来的卡 */
.joker::after {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 5px;
  pointer-events: none;
}

.joker .jn { font-size: 0.92rem; font-weight: 600; line-height: 1.2; }

.joker .jt {
  margin-top: 5px;
  padding: 4px 7px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.14);
  font-family: var(--sans);
  font-size: 0.68rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.94);
}

.joker .jc {
  position: absolute;
  right: 9px;
  bottom: 6px;
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.72);
}

/* 卖出键只在鼠标悬停时露出来：它是破坏性操作，不该常驻在牌面上 */
.joker .sell {
  position: absolute;
  top: 5px;
  right: 6px;
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  color: var(--ink);
  font-size: 11px;
  line-height: 18px;
  text-align: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, transform 0.15s;
}

.joker:hover .sell { opacity: 1; }
.joker .sell:hover { transform: scale(1.12); }

.joker.trigger { animation: jtrigger 0.45s cubic-bezier(0.2, 1.6, 0.5, 1); box-shadow: 0 0 0 3px var(--ink); }
@keyframes jtrigger {
  0% { transform: scale(1) rotate(0); }
  35% { transform: scale(1.08) rotate(-2deg); }
  70% { transform: scale(1.02) rotate(1.2deg); }
  100% { transform: scale(1) rotate(0); }
}

.joker.fresh { animation: jin 0.55s cubic-bezier(0.2, 1.5, 0.5, 1); }
@keyframes jin {
  0% { transform: translateX(70px) scale(0.6) rotate(10deg); opacity: 0; }
  60% { opacity: 1; }
  100% { transform: translateX(0) scale(1) rotate(0); opacity: 1; }
}

.jrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0;
  border-bottom: 1px dashed var(--rule);
  font-family: var(--sans);
  font-size: 0.76rem;
  color: var(--ink-70);
}

.jrow:last-child { border-bottom: 0; }
.jrow b { font-family: var(--serif); font-size: 1.1rem; font-weight: 600; color: var(--ink); }

.help {
  padding: 11px 13px;
  font-family: var(--sans);
  font-size: 0.72rem;
  line-height: 1.75;
  color: var(--ink-70);
}

.help b { font-weight: 600; color: var(--ink); }

/* =========================================================
   弹层
   ========================================================= */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(247, 243, 235, 0.84);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* display:flex 会盖掉 hidden 属性的 display:none，得自己兜一句 */
.overlay.hidden { display: none; }

.modal {
  max-width: min(940px, 94vw);
  max-height: 90vh;
  padding: 26px 30px;
  overflow: auto;
  background: var(--card);
  border: 1px solid var(--rule-strong);
  border-radius: 10px;
  box-shadow: 0 20px 50px rgba(23, 20, 17, 0.16);
  animation: modalin 0.3s cubic-bezier(0.2, 1.4, 0.5, 1);
}

@keyframes modalin {
  0% { transform: scale(0.94) translateY(14px); opacity: 0; }
  100% { transform: scale(1) translateY(0); opacity: 1; }
}

.modal h2 { margin-bottom: 8px; font-size: 1.35rem; font-weight: 600; color: var(--ink); }
.modal p.desc { margin-bottom: 16px; font-size: 0.86rem; line-height: 1.65; color: var(--ink-70); }
.modal .mrow { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; margin: 18px 0; }
.modal .mfoot { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 18px; }

.cashrow {
  display: flex;
  justify-content: space-between;
  gap: 30px;
  padding: 9px 4px;
  border-bottom: 1px dashed var(--rule);
  font-size: 0.86rem;
  color: var(--ink-70);
}

.cashrow b { font-weight: 600; color: var(--ochre); }

/* =========================================================
   商店
   ========================================================= */
.shopcard {
  position: relative;
  width: 198px;
  padding: 13px;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 10px;
  color: var(--ink);
  transition: transform 0.14s cubic-bezier(0.2, 1.5, 0.5, 1), box-shadow 0.14s;
}

.shopcard:hover { transform: translateY(-5px); box-shadow: 0 8px 20px rgba(23, 20, 17, 0.12); }

/* 稀有度只染那一行小字：卡片本身保持白纸，一屏三张的时候不打架 */
.shopcard .r {
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-55);
}

.shopcard.common .r { color: var(--chip); }
.shopcard.uncommon .r { color: var(--uncommon); }
.shopcard.rare .r { color: var(--rare); }
.shopcard.planet .r { color: var(--ochre); }

.shopcard .t { margin-top: 5px; font-size: 1.05rem; font-weight: 600; }

.shopcard .d {
  min-height: 64px;
  margin: 8px 0 12px;
  padding: 8px 10px;
  border-radius: 6px;
  background: rgba(23, 20, 17, 0.04);
  font-family: var(--sans);
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--ink-70);
}

.shopcard.sold { opacity: 0.42; }
.shopcard.sold .t { color: var(--ink-55); }
/* 卖掉的位子只剩一句「已售出」，那块说明的灰底还留着就是个空洞 */
.shopcard .d:empty { display: none; }

/* =========================================================
   牌堆一览 / 提示条
   ========================================================= */
.deckgrid { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 12px; max-width: 760px; }

.badge {
  padding: 3px 8px;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--ink-80);
}

.badge.br { border-color: rgba(180, 69, 47, 0.45); color: var(--mult); }

.toast {
  position: fixed;
  left: 50%;
  bottom: 11vh;
  z-index: 99;
  padding: 11px 24px;
  transform: translateX(-50%) scale(0.94);
  background: var(--ink);
  border-radius: 999px;
  color: var(--paper);
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  box-shadow: 0 10px 24px rgba(23, 20, 17, 0.22);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
}

.toast.show { transform: translateX(-50%) scale(1); opacity: 1; }

/* =========================================================
   窄屏
   ========================================================= */
@media (max-width: 1180px) {
  .board { grid-template-columns: 184px minmax(0, 1fr) 212px; gap: 11px; }
  :root { --cw: clamp(48px, 5.1vw, 80px); }
}

/* 三栏在手机上必然是挤爆的 —— 这不是「窄一点」而是「换个摆法」：
   原来是三栏一屏、不许滚动；这里改成一条纵向的流水，页面恢复滚动。
   左右两栏各自压扁：盲注和本轮进度并排，三个计数器横着摊开。 */
@media (max-width: 1000px) {
  html,
  body { height: auto; }

  body { overflow: visible; }

  .bl-page { height: auto; min-height: 100%; padding: 0 14px 40px; }
  .bl-head { padding: 16px 0 12px; }

  .board { grid-template-columns: 1fr; gap: 11px; flex: 0 0 auto; padding: 13px 0; }

  /* align-items:start 是必要的：默认的 stretch 会把「本轮得分」拉到和
     「盲注」一样高，那张卡下半截就空出一大块 */
  .col--left { display: grid; grid-template-columns: 1fr 1fr; align-items: start; gap: 11px; }
  .col--left .spacer { display: none; }
  .col--left .mini { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
  /* 三格横排之后一个字一行太窄，标签上、数字下 */
  .col--left .minirow { flex-direction: column; align-items: flex-start; gap: 2px; padding: 8px 10px; }

  .col--center { order: 2; }
  .col--right { order: 3; }
  .col--left { order: 1; }

  /* 纵向上不再有「剩下多少高度」这种东西，出牌区自己给一个下限，
     不然 flex:1 在没有确定高度的父级里会缩成一条 */
  .playmat { min-height: 240px; padding: 14px 14px 100px; }

  /* 手牌变小以后 8 张才排得进一行 */
  :root { --cw: clamp(40px, 10.4vw, 62px); }
  .handarea { gap: 5px; padding: 18px 0 6px; }

  .jokerlist { overflow: visible; }
  /* 五个空位横过来占满整行，每个再留 80px 就是一大片废墟，压矮一点 */
  .jslot { min-height: 56px; }
  .joker { min-height: 56px; }
}

@media (max-width: 480px) {
  .blind .bname { font-size: 1.15rem; }
  .blind .bgoal b { font-size: 1.5rem; }
  .round .num { font-size: 1.7rem; }
  .sbox { min-width: 74px; padding: 8px 11px 7px; }
  .sbox .v { font-size: 1.6rem; }
  /* 六个按钮各占一行宽会碎成 5 + 1，两个短行看着像漏了一个；
     摊成 3 × 2 的格子，正好是两行齐的 */
  .actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
  .btn { width: 100%; padding: 9px 10px; font-size: 0.76rem; }
  .modal { padding: 22px 18px; }
  .shopcard { width: 100%; }
}
