  *, *::before, *::after { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }
  body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
    background: #f4f5f7;
    color: #1f2937;
    -webkit-font-smoothing: antialiased;
    padding-bottom: 80px;
  }

  .hero { padding: 56px 32px 28px; max-width: 1180px; margin: 0 auto; }
  .hero h1 { margin: 0 0 10px; font-size: 28px; letter-spacing: -0.02em; }
  .hero p { margin: 0; color: #6b7280; font-size: 14px; line-height: 1.7; }
  .hero .tag {
    display: inline-block; margin-bottom: 14px; padding: 4px 10px; border-radius: 999px;
    background: #e8f5ee; color: #1f7a4d; font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
  }
  .hero .dice-key { display: inline-flex; align-items: center; gap: 6px; margin-right: 14px; font-size: 12.5px; color: #6b7280; }
  .hero .dot { width: 12px; height: 12px; border-radius: 4px; border: 1px solid #cbd2dd; display: inline-block; }
  .hero .dot.dark { background: #14161c; border-color: #14161c; }
  .hero .dot.light { background: #fbfcfe; }

  .grid {
    max-width: 1180px; margin: 0 auto; padding: 12px 32px 40px;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 18px;
  }
  .card {
    background: #ffffff; border: 1px solid #e6e8ec; border-radius: 14px;
    padding: 20px 20px 22px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    transition: transform .28s cubic-bezier(.2, .8, .2, 1), box-shadow .28s ease, border-color .28s ease;
    cursor: pointer; will-change: transform;
  }
  .card:hover { transform: translateY(-8px); box-shadow: 0 18px 36px rgba(15, 23, 42, 0.13); border-color: #9fd8bb; }
  .card:active { transform: translateY(-3px); }
  .card .no { font-size: 12px; font-weight: 700; color: #9aa3b2; letter-spacing: .08em; }
  .card h3 { margin: 8px 0 8px; font-size: 17px; letter-spacing: -0.01em; }
  .card p { margin: 0; font-size: 13px; line-height: 1.75; color: #6b7280; }
  .card .chips { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 6px; }
  .card .chip { font-size: 11px; padding: 3px 8px; border-radius: 6px; background: #f1f3f7; color: #55607a; }
  .card.is-active { border-color: #1f7a4d; box-shadow: 0 14px 30px rgba(31, 122, 77, 0.18); }

  footer { max-width: 1180px; margin: 0 auto; padding: 8px 32px 60px; color: #9aa3b2; font-size: 12px; }

  /* 底栏里的骰子标牌：黑骰黑底白字，白骰白底黑字，数字跟着骰子本体走 */
  .die-chip {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 4px 11px 4px 9px; border-radius: 999px;
    font-size: 11.5px; font-weight: 600; letter-spacing: .02em; white-space: nowrap;
  }
  .die-chip i { font-style: normal; opacity: .68; }
  .die-chip b {
    font-size: 15px; font-weight: 800; min-width: 22px; text-align: center;
    font-variant-numeric: tabular-nums; line-height: 1;
  }
  .die-chip.dark {
    background: #14161c; color: #ffffff; border: 1px solid #3a4054;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10), 0 2px 8px rgba(0, 0, 0, .35);
  }
  .die-chip.dark b { color: #ffffff; }
  .die-chip.light {
    background: #fbfcfe; color: #14161c; border: 1px solid #c8cfdb;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9), 0 2px 8px rgba(0, 0, 0, .22);
  }
  .die-chip.light b { color: #14161c; }

  /* 底栏里的按钮：胶囊本身 pointer-events:none，只有这两个按钮吃事件 */
  .hint-btn {
    pointer-events: auto; cursor: pointer;
    appearance: none; -webkit-appearance: none;
    font: inherit; font-size: 12.5px; font-weight: 600; white-space: nowrap;
    color: #f3f4f6; background: rgba(255, 255, 255, .13);
    border: 1px solid rgba(255, 255, 255, .22); border-radius: 999px;
    padding: 6px 14px;
    transition: background .18s ease, border-color .18s ease, color .18s ease;
  }
  .hint-btn:hover { background: rgba(255, 255, 255, .24); border-color: rgba(134, 227, 176, .65); }
  .hint-btn:active { background: rgba(255, 255, 255, .32); }
  .hint-btn:disabled { opacity: .4; cursor: not-allowed; background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .12); }

  /* WebGL 画布：整屏，完全穿透。
     宽高必须显式写 100%：canvas 是替换元素，只写 inset:0 时 width:auto 取的是它的
     固有尺寸（= 绘制缓冲的像素数 ≈ 视口 × devicePixelRatio），于是整块 WebGL 画面
     被放大并向右下错位 */
  #cv {
    position: fixed; inset: 0;
    width: 100%; height: 100%; display: block;
    z-index: 9998; pointer-events: none;
  }

  /* 骰子命中区：跟骰子走，只有这一小块吃事件。两枚各有一个，互不影响。
     直径 224（半径 112）刚好裹住骰子的可见轮廓（外接半径 98.84，透视放大后约 106）。
     再放大就会在两枚靠近时互相压住 —— 想看左边那枚、点下去却触发了上面那一枚。
     小屏时由 applyScale() 把宽高与负边距按同一比例改小（写在元素 style 上，压过这里） */
  .hit {
    position: fixed; left: 0; top: 0;
    width: 224px; height: 224px;
    margin-left: -112px; margin-top: -112px;
    border-radius: 50%;
    z-index: 9999;
    pointer-events: auto;
    cursor: grab;
    touch-action: none;
    will-change: transform;
  }
  .hit.dragging { cursor: grabbing; }
  /* 掷出中的命中区不再设 pointer-events:none。设了的话指针会穿到下面的 body 上，
     点正在飞的骰子照样会冒爆字（骰子是可交互元素，不该冒）；
     「掷出中不响应」交给 pointerdown 里的模式判断去挡 */

  #hint {
    position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%);
    z-index: 9999; pointer-events: none;      /* 胶囊整体穿透，只有里面的按钮吃事件 */
    display: flex; align-items: center; gap: 9px; flex-wrap: wrap; justify-content: center;
    /* width 必须显式写 max-content。固定定位元素只给了 left 没给 right/width 时，
       shrink-to-fit 的「可用宽度」按「视口宽 − left」算 = 50vw，于是框被卡在半屏宽，
       窄屏上两枚骰子标牌挤不到同一行、各自占一条。写死 max-content 才是
       「按内容撑开，撑到 max-width 为止」 */
    width: max-content;
    max-width: calc(100vw - 24px);
    padding: 8px 12px; border-radius: 999px;
    background: rgba(28, 32, 42, 0.86); color: #f3f4f6;
    font-size: 12.5px; box-shadow: 0 8px 24px rgba(15, 23, 42, .25);
    backdrop-filter: blur(6px);
  }
  #hint .hint-tip { white-space: nowrap; }
  #hint .sep { opacity: .35; }

  /* 撞上的瞬间闪一下：碰撞本身只持续一帧，不闪一下根本注意不到 */
  #hint.hit-flash { animation: hitflash .55s ease; }
  @keyframes hitflash {
    0%   { background: rgba(28, 32, 42, .86); box-shadow: 0 8px 24px rgba(15,23,42,.25), 0 0 0 0 rgba(134,227,176,.85); }
    30%  { background: rgba(31, 122, 77, .92); box-shadow: 0 8px 24px rgba(15,23,42,.25), 0 0 0 9px rgba(134,227,176,0); }
    100% { background: rgba(28, 32, 42, .86); box-shadow: 0 8px 24px rgba(15,23,42,.25), 0 0 0 0 rgba(134,227,176,0); }
  }

  #fallback {
    display: none;
    position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
    padding: 18px 22px; border-radius: 12px; background: #fff;
    border: 1px solid #e6e8ec; box-shadow: 0 20px 50px rgba(15,23,42,.18);
    font-size: 13px; color: #b42318; z-index: 10000; max-width: 420px; line-height: 1.7;
  }

/* ===== 漫画皮肤覆盖层：只改样式，不动布局属性 ===== */
html{background:var(--paper)}
body{
  background:var(--paper);
  background-image:radial-gradient(circle,rgba(26,26,26,.13) 1px,transparent 1px);
  background-size:9px 9px;
  color:var(--ink);
  font-family:var(--body);
}
.hero h1{
  font-family:var(--display);
  text-transform:uppercase;
  letter-spacing:.04em;
  color:var(--ink);
  text-shadow:4px 4px 0 var(--yellow);
}
.hero p{color:var(--ink-2)}
.hero .tag{
  font-family:var(--display);
  text-transform:uppercase;
  letter-spacing:.06em;
  background:var(--yellow);
  color:var(--ink);
  border:var(--bw) solid var(--ink);
  border-radius:4px;
  box-shadow:var(--sh-s);
}
.card{
  background:var(--paper-2);
  border:var(--bw) solid var(--ink);
  border-radius:4px;
  box-shadow:var(--sh-m);
}
.card:hover{
  transform:translate(-3px,-3px);
  box-shadow:var(--sh-l);
  border-color:var(--ink);
}
.card:active{transform:translate(2px,2px)}
.card .no{font-family:var(--display);color:var(--red);letter-spacing:.08em}
.card h3{font-family:var(--display);text-transform:uppercase;letter-spacing:.02em}
.card p{color:var(--ink-2)}
.card .chip{
  font-family:var(--display);
  text-transform:uppercase;
  background:var(--paper);
  color:var(--ink);
  border:2px solid var(--ink);
  border-radius:4px;
}
.card.is-active{background:var(--yellow);border-color:var(--red);box-shadow:var(--sh-m)}
footer{
  color:var(--ink-2);
  font-family:var(--display);
  text-transform:uppercase;
  letter-spacing:.06em;
}
/* 悬浮提示框：对齐「手工作品」的悬浮信息框（纸底 + 墨线 + 硬阴影 + 外挂贴纸） */
#hint{
  background:var(--paper-2);
  color:var(--ink);
  border:var(--bw) solid var(--ink);
  border-radius:4px;
  box-shadow:var(--sh-m);
  font-family:var(--body);
}
#hint b{color:var(--ink)}
#hint .hint-tip{font-weight:900}
#hint .sep{opacity:.4;color:var(--ink-2)}
.hero{padding-top:18px}
.hero p{font-family:var(--body)}
#fallback{
  background:var(--paper-2);
  border:var(--bw) solid var(--ink);
  border-radius:4px;
  box-shadow:var(--sh-m);
  color:var(--red);
}
/* ---- 双骰页面专属 ---- */
.hero .dice-key{color:var(--ink-2)}
.hero .dot{border:2px solid var(--ink);border-radius:4px}
.hero .dot.dark{background:var(--ink);border-color:var(--ink)}
.hero .dot.light{background:var(--paper-2)}
/* 黑骰 / 白骰标牌：与右侧两个按钮（.hint-btn）同规格 —— 同样的字号、内边距、
   墨线、硬角、硬阴影；黑白只靠底色区分：黑骰黑底白字，白骰白底黑字。
   选择器必须带 #hint 前缀，否则压不住上方原有样式里 .die-chip.dark 的
   1px 边框与 inset 阴影（那两条的优先级比裸类名高）。 */
#hint .die-chip{
  font-family:var(--display);
  text-transform:uppercase;
  letter-spacing:.06em;
  font-size:12.5px;font-weight:600;
  padding:6px 14px;
  border:3px solid var(--ink);
  border-radius:4px;
  box-shadow:2px 2px 0 0 var(--ink);
}
#hint .die-chip i{display:inline-flex;align-items:center;gap:6px;opacity:1}
#hint .die-chip b{
  font-size:1.15em;font-weight:800;line-height:1;
  min-width:20px;text-align:center;font-variant-numeric:tabular-nums;
}
#hint .die-chip.dark{
  background:var(--ink);color:var(--paper-2);
  border:3px solid var(--ink);box-shadow:2px 2px 0 0 var(--ink);
}
#hint .die-chip.light{
  background:var(--paper-2);color:var(--ink);
  border:3px solid var(--ink);box-shadow:2px 2px 0 0 var(--ink);
}
#hint .die-chip.dark b{color:var(--paper-2)}
#hint .die-chip.light b{color:var(--ink)}
.hint-btn{
  font-family:var(--display);
  text-transform:uppercase;
  letter-spacing:.06em;
  color:var(--ink);
  background:var(--yellow);
  border:3px solid var(--ink);
  border-radius:4px;
  box-shadow:2px 2px 0 0 var(--ink);
  transition:transform .1s linear,box-shadow .1s linear,background .1s linear,color .1s linear;
}
.hint-btn:hover{background:var(--red);color:#fff;border-color:var(--ink);transform:translate(2px,2px);box-shadow:1px 1px 0 0 var(--ink)}
.hint-btn:active{transform:translate(2px,2px);box-shadow:0 0 0 0 var(--ink)}
.hint-btn:disabled{opacity:.45;background:var(--paper-2);color:var(--ink-2);border-color:var(--ink)}
@keyframes hitflash{
  0%   { background:var(--paper-2); box-shadow:var(--sh-m), 0 0 0 0 rgba(51,204,51,.85); }
  30%  { background:var(--green);   box-shadow:var(--sh-m), 0 0 0 9px rgba(51,204,51,0); }
  100% { background:var(--paper-2); box-shadow:var(--sh-m), 0 0 0 0 rgba(51,204,51,0); }
}

/* 骰子不加悬停反馈：本体是 WebGL 画在 canvas 上的，能挂的只有 `.hit` 那块命中区，
   而它比骰子可见轮廓大一圈，任何画在它上的环/描边都会飘在骰子外面。
   交互反馈改为「按下即投掷」本身的动作，不再另加视觉提示。 */

/* 窄屏：提示条按内容撑满可用宽度之后，再把内边距与间距收一档，
   两枚骰子标牌就并得到同一行（判据见上面 #hint 的注） */
@media (max-width:760px){
  #hint{gap:7px;padding:7px 10px;font-size:12px}
  #hint .die-chip{padding:5px 11px}
  #hint .hint-btn{padding:5px 11px}
}
