/* ============================================================
   reset + 基础排版 + 通用工具类
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: var(--font-family);
  font-size: var(--fs-md);
  color: var(--c-text);
  background: var(--c-bg);
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}

#root { min-height: 100vh; }

h1, h2, h3, h4, p { margin: 0; }

button {
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  border: none;
  background: none;
  padding: 0;
  color: inherit;
}
button:disabled { cursor: not-allowed; opacity: 0.4; }

input, select, textarea {
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--c-text);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-sm);
  padding: 7px 10px;
  outline: none;
  background: #fff;
  transition: border-color 0.15s, box-shadow 0.15s;
  will-change: border-color, box-shadow;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--c-primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
input::placeholder, textarea::placeholder { color: var(--c-text-3); }
input.is-error, textarea.is-error { border-color: var(--c-danger); }
input[type="number"] { -moz-appearance: textfield; }
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; }

a { color: var(--c-primary); text-decoration: none; }

/* 数字防跳动 */
.num, .price, .countdown { font-variant-numeric: tabular-nums; }

/* 通用工具类 */
.flex { display: flex; }
.flex-center { display: flex; align-items: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.gap-1 { gap: var(--sp-1); } .gap-2 { gap: var(--sp-2); } .gap-3 { gap: var(--sp-3); } .gap-4 { gap: var(--sp-4); }
.mt-2 { margin-top: var(--sp-2); } .mt-3 { margin-top: var(--sp-3); } .mt-4 { margin-top: var(--sp-4); } .mt-6 { margin-top: var(--sp-6); }
.text-2 { color: var(--c-text-2); }
.text-3 { color: var(--c-text-3); }
.text-sm { font-size: var(--fs-sm); }
.text-xs { font-size: var(--fs-xs); }
.ellipsis { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.bold { font-weight: 600; }

/* 滚动条 */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: #D4D7DD; border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: #B9BEC8; }
::-webkit-scrollbar-track { background: transparent; }

/* 呼吸闪烁动画（紧迫倒计时 / 骨架屏共用基调） */
@keyframes tk-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
@keyframes tk-shimmer {
  0% { background-position: -200px 0; }
  100% { background-position: 200px 0; }
}
@keyframes tk-shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-6px); }
  40%, 80% { transform: translateX(6px); }
}
@keyframes tk-fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes tk-slide-down {
  from { opacity: 0; transform: translate(-50%, -14px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
