:root {
  --ink: #18343a;
  --muted: #60757b;
  --panel: rgba(255, 255, 255, 0.76);
  --panel-line: rgba(38, 88, 98, 0.18);
  --accent: #e45655;
  --tile-w: 54px;
  --tile-h: 62px;
  --gap-x: 39px;
  --gap-y: 51px;
  --lift-x: 7px;
  --lift-y: -8px;
}

* { box-sizing: border-box; }
html, body { width: 100%; min-height: 100%; margin: 0; overflow: hidden; }

body {
  color: var(--ink);
  font-family: Pretendard, system-ui, sans-serif;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.58), rgba(255,255,255,0.08) 42%, rgba(255,255,255,0.32)),
    linear-gradient(145deg, #c5eef0 0%, #eef2dc 46%, #f8d7ca 100%);
  isolation: isolate;
}

.app {
  position: relative;
  z-index: 1;
  height: 100dvh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: 8px;
  padding: max(10px, env(safe-area-inset-top)) 10px max(10px, env(safe-area-inset-bottom));
}

.topbar {
  display: grid;
  grid-template-columns: minmax(300px, 1fr) minmax(330px, 620px);
  align-items: center;
  gap: 10px;
  width: min(1180px, 100%);
  margin: 0 auto;
}

.brand {
  display: grid;
  grid-template-columns: auto minmax(136px, 170px);
  align-items: center;
  gap: 12px;
  min-width: 0;
}

h1 {
  margin: 0;
  font-family: Pretendard, system-ui, sans-serif;
  font-size: clamp(30px, 4vw, 50px);
  line-height: 1;
  color: #24424a;
  text-shadow: 0 2px 0 rgba(255,255,255,0.78);
  white-space: nowrap;
}

.hold-slots {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  width: min(136px, 100%);
  justify-self: center;
  padding: 4px;
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  background: rgba(255,255,255,0.52);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.82), 0 6px 14px rgba(65, 118, 126, 0.12);
}

.hold-slot {
  position: relative;
  aspect-ratio: 0.88;
  min-height: 30px;
  border: 1px dashed rgba(49, 89, 96, 0.28);
  border-radius: 6px;
  display: grid;
  place-items: center;
  background: rgba(246, 253, 251, 0.68);
}

.hold-slot.filled {
  border-style: solid;
  background: rgba(255,255,255,0.86);
  box-shadow: 0 2px 0 rgba(74, 117, 120, 0.26);
}

.slot-tile {
  position: relative;
  width: 86%;
  height: 86%;
  border-radius: 6px;
  display: grid;
  place-items: center;
  cursor: pointer;
  font-family: Pretendard, system-ui, sans-serif;
  font-size: clamp(14px, 2.2vw, 22px);
  font-weight: 800;
  line-height: 1;
  color: #24363a;
  background: linear-gradient(145deg, var(--tile-hi, #fffaf0), var(--tile-mid, #ffe5b7) 58%, var(--tile-low, #d9a96b));
  box-shadow: inset 1px 1px 0 rgba(255,255,255,0.86), inset -2px -2px 0 rgba(96,62,36,0.13);
  transition: transform 120ms ease;
}
.slot-tile:not(.matching):active { transform: scale(0.92); }

.slot-tile.matching { animation: slotMatch 260ms ease forwards; }

.stats {
  display: grid;
  grid-template-columns: repeat(5, minmax(62px, 1fr));
  gap: 7px;
}

.stats div {
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  padding: 7px 9px;
  background: var(--panel);
  box-shadow: 0 10px 24px rgba(68, 126, 141, 0.13), inset 0 1px 0 rgba(255,255,255,0.8);
  backdrop-filter: blur(8px);
}

.stats span { display: block; font-size: 11px; color: var(--muted); }
.stats strong { display: block; margin-top: 1px; font-size: 18px; color: #18343d; }

.combo-gauge {
  position: relative;
  min-height: 76px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  overflow: hidden;
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  padding: 10px 16px 13px;
  background:
    radial-gradient(circle at 18% 12%, rgba(255,255,255,0.9), transparent 32%),
    linear-gradient(180deg, rgba(255,255,255,0.92), rgba(242, 255, 249, 0.68)),
    var(--panel);
  box-shadow:
    0 12px 28px rgba(68, 126, 141, 0.16),
    inset 0 1px 0 rgba(255,255,255,0.9);
  backdrop-filter: blur(8px);
}

.combo-gauge::before {
  content: "";
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 12px;
  height: 26px;
  border-radius: 999px;
  background: rgba(33, 74, 84, 0.11);
  box-shadow:
    inset 0 3px 9px rgba(31, 75, 85, 0.22),
    0 1px 0 rgba(255,255,255,0.72);
}

.combo-gauge-fill {
  position: absolute;
  left: 16px;
  bottom: 12px;
  width: 0%;
  max-width: calc(100% - 32px);
  height: 26px;
  border-radius: 999px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.44), rgba(255,255,255,0) 42%),
    linear-gradient(90deg, #29c8d6 0%, #85dd5d 32%, #ffe15b 62%, #ff7b43 82%, #ef4f6a 100%);
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,0.78),
    inset 0 -3px 7px rgba(123, 57, 40, 0.18),
    0 6px 14px rgba(229, 113, 72, 0.28),
    0 0 18px rgba(255, 198, 79, 0.22);
  transition: width 180ms ease;
}

.combo-gauge-fill::after {
  content: "";
  position: absolute;
  inset: 2px 4px auto;
  height: 40%;
  border-radius: inherit;
  background: linear-gradient(90deg, rgba(255,255,255,0.46), rgba(255,255,255,0.12));
  opacity: 0.9;
}

.combo-gauge-label {
  position: relative;
  z-index: 1;
  min-width: 0;
  font: 800 32px Pretendard, system-ui, sans-serif;
  line-height: 1.05;
  color: #17343b;
  text-shadow:
    0 2px 0 rgba(255,255,255,0.86),
    0 8px 18px rgba(38, 91, 98, 0.16);
  white-space: nowrap;
}

.combo-gauge-score {
  position: relative;
  z-index: 1;
  justify-self: end;
  align-self: start;
  padding-top: 1px;
  font: 800 13px Pretendard, system-ui, sans-serif;
  color: rgba(36, 70, 78, 0.72);
  white-space: nowrap;
}

.combo-gauge.fever {
  transform: translateZ(0) scale(1.018);
  border-color: rgba(255, 103, 95, 0.5);
  background:
    linear-gradient(180deg, rgba(255,255,255,0.9), rgba(255, 247, 222, 0.7)),
    var(--panel);
  box-shadow:
    0 0 0 2px rgba(255, 228, 92, 0.2),
    0 10px 24px rgba(255, 138, 40, 0.2),
    inset 0 1px 0 rgba(255,255,255,0.92);
  animation: feverGaugePulse 740ms ease-in-out infinite;
  will-change: transform;
}

.combo-gauge.fever::after {
  content: "";
  position: absolute;
  inset: -40% -28%;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.75) 48%, transparent 66%);
  opacity: 0.72;
  transform: translate3d(-55%, 0, 0);
  animation: feverGaugeShine 920ms ease-in-out infinite;
  will-change: transform, opacity;
}

.combo-gauge.fever .combo-gauge-fill {
  background:
    linear-gradient(90deg, #20d5ff, #74f070 22%, #fff05c 45%, #ff8a28 66%, #ff4d86 84%, #9c5cff);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.86),
    0 4px 12px rgba(255, 129, 74, 0.28);
}

.combo-gauge.fever .combo-gauge-label {
  color: #f23c66;
  text-shadow:
    0 2px 0 rgba(255,255,255,0.95),
    0 0 12px rgba(255, 229, 74, 0.8),
    0 0 24px rgba(255, 85, 88, 0.35);
}

.combo-gauge.fever .combo-gauge-score {
  color: rgba(152, 47, 75, 0.82);
}

body.fever::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 18500;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% -10%, rgba(255, 240, 100, 0.35) 0 14%, transparent 42%),
    radial-gradient(ellipse at 50% 112%, rgba(255, 102, 60, 0.4) 0 15%, transparent 44%),
    radial-gradient(ellipse at -12% 50%, rgba(255, 86, 104, 0.32) 0 12%, transparent 38%),
    radial-gradient(ellipse at 112% 50%, rgba(255, 192, 61, 0.32) 0 12%, transparent 38%);
  opacity: 0.62;
  transform: translateZ(0);
  animation: feverEdgePulse 820ms ease-in-out infinite;
  will-change: opacity;
}


.fever-burst {
  position: fixed;
  inset: 0;
  z-index: 19500;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 52%, rgba(255,255,255,0.94) 0 6%, rgba(255, 233, 84, 0.62) 8% 16%, transparent 32%),
    conic-gradient(from 18deg at 50% 52%, transparent 0 7%, rgba(255,255,255,0.62) 8% 10%, transparent 11% 28%, rgba(255, 85, 111, 0.36) 29% 32%, transparent 33% 100%);
  mix-blend-mode: screen;
  animation: feverBurst 780ms cubic-bezier(0.12, 0.88, 0.22, 1) forwards;
  will-change: transform, opacity;
}

.fever-particle {
  position: fixed;
  left: var(--x, 50%);
  top: var(--y, 86%);
  z-index: 18600;
  width: var(--size, 8px);
  height: var(--size, 8px);
  border-radius: 999px;
  pointer-events: none;
  background: radial-gradient(circle, #fff7ae 0 18%, var(--particle-color, #ffe761) 20% 100%);
  opacity: 0;
  transform: translate3d(0, 0, 0) scale(0.45);
  animation: feverParticleFloat var(--duration, 1300ms) ease-out forwards;
  will-change: transform, opacity;
}

.table-wrap {
  min-height: 0;
  display: grid;
  place-items: center;
  padding: 0;
  overflow: hidden;
}

.board {
  position: relative;
  width: 390px;
  height: 690px;
  max-width: 100%;
  overflow: visible;
  perspective: 900px;
  border-radius: 8px;
  background:
    linear-gradient(90deg, rgba(44, 107, 122, 0.055) 1px, transparent 1px),
    linear-gradient(rgba(44, 107, 122, 0.055) 1px, transparent 1px),
    linear-gradient(160deg, rgba(255,255,255,0.48), rgba(222, 249, 246, 0.34));
  background-size: 34px 34px, 34px 34px, auto;
}

.match-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 10000;
}

.match-link {
  fill: none;
  stroke: #ff6b66;
  stroke-width: 5;
  stroke-linecap: round;
  filter: drop-shadow(0 0 7px rgba(255, 107, 102, 0.75));
  animation: linkFade 170ms ease-out forwards;
}

.tile {
  position: absolute;
  --depth-bright: calc(1 + var(--tile-z, 0) * 0.025);
  --depth-shadow-x: calc(6px + var(--tile-z, 0) * 0.7px);
  --depth-shadow-y: calc(9px + var(--tile-z, 0) * 1.35px);
  --depth-shadow-blur: calc(14px + var(--tile-z, 0) * 1.8px);
  --free-bright: calc(1.06 + var(--tile-z, 0) * 0.03);
  --free-shadow-x: calc(7px + var(--tile-z, 0) * 0.85px);
  --free-shadow-y: calc(13px + var(--tile-z, 0) * 1.7px);
  --free-shadow-blur: calc(18px + var(--tile-z, 0) * 2.1px);
  --covered-bright: calc(0.82 + var(--tile-z, 0) * 0.018);
  --covered-shadow-x: calc(5px + var(--tile-z, 0) * 0.45px);
  --covered-shadow-y: calc(8px + var(--tile-z, 0) * 0.8px);
  --covered-shadow-blur: calc(12px + var(--tile-z, 0) * 1.1px);
  width: var(--tile-w);
  height: var(--tile-h);
  border: 1px solid rgba(86, 75, 58, 0.2);
  border-radius: 8px;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  color: #26363a;
  font-family: Pretendard, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", system-ui, sans-serif;
  font-size: calc(var(--tile-w) * 0.56);
  font-weight: 800;
  line-height: 1;
  background:
    radial-gradient(circle at 30% 24%, rgba(255,255,255,0.9), transparent 29%),
    linear-gradient(145deg, var(--tile-hi, #fffaf0), var(--tile-mid, #ffe5b7) 58%, var(--tile-low, #d9a96b));
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.82),
    inset -2px -2px 0 rgba(96,62,36,0.14),
    2px 3px 0 var(--tile-edge, #b9814c),
    var(--depth-shadow-x) var(--depth-shadow-y) var(--depth-shadow-blur) rgba(45, 82, 94, 0.28);
  text-shadow: 0 1px 0 rgba(255,255,255,0.65);
  filter: brightness(var(--depth-bright));
  transition: transform 140ms ease, opacity 220ms ease;
  transform-style: preserve-3d;
  transform-origin: center center;
  backface-visibility: hidden;
  will-change: transform, opacity;
}

.tile::before {
  content: "";
  position: absolute;
  inset: 5px 5px auto auto;
  width: 18%;
  height: 20%;
  border-radius: 999px;
  background: rgba(255,255,255,0.42);
}

.tile::after {
  content: attr(data-label);
  position: absolute;
  right: 5px;
  bottom: 4px;
  max-width: calc(100% - 10px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: Pretendard, system-ui, sans-serif;
  font-size: calc(var(--tile-w) * 0.12);
  font-weight: 800;
  color: rgba(42, 48, 52, 0.48);
}

.tile.fruit, .slot-tile.fruit { --tile-hi: #fff7db; --tile-mid: #ffd88d; --tile-low: #ec9d63; --tile-edge: #c87545; }
.tile.weather, .slot-tile.weather { --tile-hi: #effcff; --tile-mid: #bfe9ff; --tile-low: #8fc9e7; --tile-edge: #5b9fbd; }
.tile.flower, .slot-tile.flower { --tile-hi: #fff4fb; --tile-mid: #ffc7df; --tile-low: #df92bd; --tile-edge: #ba6699; }
.tile.food, .slot-tile.food { --tile-hi: #fff8e8; --tile-mid: #f4dfa6; --tile-low: #c9ab72; --tile-edge: #9f8352; }
.tile.lucky, .slot-tile.lucky { --tile-hi: #f7fff2; --tile-mid: #bfeab2; --tile-low: #89c97c; --tile-edge: #629f5e; }
.tile.number, .slot-tile.number { --tile-hi: #fffdf2; --tile-mid: #ffd36e; --tile-low: #ea9b4e; --tile-edge: #bc7440; }
.tile.letter, .slot-tile.letter { --tile-hi: #f0fbff; --tile-mid: #aacdf4; --tile-low: #7ba5dc; --tile-edge: #5d7fb5; }

.tile.face-down {
  --tile-edge: #7a2f9f;
  cursor: pointer;
  color: transparent;
  font-size: 0;
  text-shadow: none;
  border-color: rgba(78, 49, 164, 0.34);
  background:
    linear-gradient(180deg, rgba(255,255,255,0.38), rgba(255,255,255,0.08) 34%, rgba(78, 24, 116, 0.16) 100%),
    linear-gradient(145deg, #4e63e6 0%, #a53fe0 48%, #ec4c9a 100%);
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.42),
    inset -2px -2px 0 rgba(58, 19, 101, 0.28),
    2px 3px 0 var(--tile-edge),
    var(--depth-shadow-x) var(--depth-shadow-y) var(--depth-shadow-blur) rgba(45, 82, 94, 0.28);
}

.tile.face-down::before {
  inset: 7px 7px auto;
  width: auto;
  height: 32%;
  border-radius: 7px 7px 14px 14px;
  background: linear-gradient(180deg, rgba(255,255,255,0.42), rgba(255,255,255,0.08));
  opacity: 0.82;
}

.tile.face-down::after {
  content: "";
}

.tile.revealed {
  outline: 2px solid rgba(255, 190, 94, 0.78);
  outline-offset: 2px;
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.9),
    inset -2px -2px 0 rgba(96,62,36,0.12),
    2px 3px 0 var(--tile-edge, #b9814c),
    0 0 0 5px rgba(255, 190, 94, 0.14),
    7px 12px 18px rgba(142, 92, 43, 0.2);
}

.tile.flip-out {
  pointer-events: none;
  animation: tileFlipOut 120ms ease-in both;
}

.tile.flip-in {
  pointer-events: none;
  animation: tileFlipIn 125ms ease-out both;
}

.tile.is-free,
.tile:not(.blocked):not(.is-covered) {
  cursor: pointer;
  filter: saturate(1.12) brightness(var(--free-bright));
  transform: translateY(-2px);
  /* 흰 테두리 링은 오히려 납작해 보여서 뺐다. 두꺼운 옆면(2px 4px 0)이 입체감의 핵심. */
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.9),
    inset -2px -2px 0 rgba(96,62,36,0.12),
    2px 4px 0 var(--tile-edge, #b9814c),
    var(--free-shadow-x) var(--free-shadow-y) var(--free-shadow-blur) rgba(37, 78, 91, 0.33);
}
.tile.is-covered,
.tile.blocked {
  cursor: default;
  /* 너무 세게 누르면 빽빽한 배치에서 보드 전체가 회색 덩어리로 뭉개진다.
     자유 타일과 구분은 되되 그림은 살아 있을 정도로만. */
  filter: saturate(0.68) brightness(var(--covered-bright));
  /* 옆면을 얇게(1px 2px) 바꿨더니 판 전체가 납작해 보였다. 보드의 대부분이 덮인 타일이라
     여기 두께가 곧 판 전체의 입체감이다 — 원래 두께(2px 3px)를 유지하고 색만 죽인다. */
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.62),
    inset -2px -2px 0 rgba(96,62,36,0.14),
    2px 3px 0 var(--tile-edge, #b9814c),
    var(--covered-shadow-x) var(--covered-shadow-y) var(--covered-shadow-blur) rgba(55, 88, 98, 0.23);
}
.tile.face-down.is-free,
.tile.face-down:not(.blocked):not(.is-covered) {
  cursor: pointer;
  /* 자유 뒷면을 네온처럼 밝히면 앞면 패보다 튀어서 보드가 뒤집힌 패 천지로 보인다.
     구분은 "자유를 밝히는" 게 아니라 "막힌 걸 가라앉히는" 쪽으로 만든다. */
  filter: saturate(1.05) brightness(calc(0.98 + var(--tile-z, 0) * 0.025));
  transform: translateY(-2px);
  border-color: rgba(170, 99, 225, 0.46);
  background:
    linear-gradient(180deg, rgba(255,255,255,0.46), rgba(255,255,255,0.1) 34%, rgba(78, 24, 116, 0.13) 100%),
    linear-gradient(145deg, #5571f2 0%, #b247e7 48%, #f052a2 100%);
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.48),
    inset -2px -2px 0 rgba(58, 19, 101, 0.25),
    2px 4px 0 var(--tile-edge),
    var(--free-shadow-x) var(--free-shadow-y) var(--free-shadow-blur) rgba(37, 78, 91, 0.32);
}
.tile.face-down.is-free::before,
.tile.face-down:not(.blocked):not(.is-covered)::before {
  opacity: 0.92;
}
.tile.face-down.is-covered,
.tile.face-down.blocked {
  cursor: default;
  filter: saturate(0.62) brightness(calc(0.76 + var(--tile-z, 0) * 0.016)) contrast(0.92);
  transform: none;
  border-color: rgba(54, 34, 112, 0.42);
  background:
    linear-gradient(180deg, rgba(255,255,255,0.24), rgba(255,255,255,0.04) 34%, rgba(38, 18, 82, 0.2) 100%),
    linear-gradient(145deg, #4a5dc7 0%, #8336b8 48%, #bd3b7d 100%);
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.24),
    inset -2px -2px 0 rgba(40, 15, 82, 0.34),
    2px 3px 0 var(--tile-edge),
    var(--covered-shadow-x) var(--covered-shadow-y) var(--covered-shadow-blur) rgba(45, 70, 84, 0.22);
}
.tile.face-down.is-covered::before,
.tile.face-down.blocked::before {
  opacity: 0.36;
}
.tile.hint { animation: hintPulse 720ms ease-in-out 3; }
.tile.removing { pointer-events: none; animation: tilePop 340ms ease forwards; }
.tile.wrong { animation: wrongShake 260ms ease; }
.tile.moving { pointer-events: none; animation: tileMoveOut 230ms ease forwards; }
.tile.flying {
  pointer-events: none;
  z-index: 18000 !important;
  transition:
    transform 260ms cubic-bezier(0.18, 0.84, 0.25, 1),
    left 260ms cubic-bezier(0.18, 0.84, 0.25, 1),
    top 260ms cubic-bezier(0.18, 0.84, 0.25, 1),
    opacity 180ms ease;
  filter: brightness(1.16) saturate(1.18);
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,0.9),
    inset -2px -2px 0 rgba(96,62,36,0.12),
    3px 5px 0 var(--tile-edge, #b9814c),
    10px 18px 24px rgba(33, 73, 84, 0.35);
}
.tile.idle-shimmer::before {
  animation: idleShimmer 3.6s ease-in-out infinite;
  will-change: transform, opacity;
}

.tile .shard,
.slot-tile .shard {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 18%;
  height: 18%;
  background: var(--shard-color, #ffd166);
  clip-path: polygon(50% 0, 100% 38%, 82% 100%, 15% 82%, 0 24%);
  transform: translate(-50%, -50%);
  animation: shardFly 420ms ease-out forwards;
}

.tile.removing .spark,
.slot-tile .spark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--spark-color);
  transform: translate(-50%, -50%);
  animation: sparkFly 360ms ease-out forwards;
}

.controls {
  width: min(620px, 100%);
  margin: 0 auto;
  display: grid;
  /* 되돌리기 · 힌트 · 셔플 · 새 게임 · 음소거 — 양 끝은 아이콘 버튼이라 고정폭 */
  grid-template-columns: 54px repeat(3, 1fr) 54px 54px;
  gap: 9px;
}

button {
  min-height: 46px;
  border: 1px solid rgba(32, 75, 86, 0.18);
  border-radius: 8px;
  color: #17313a;
  background: linear-gradient(#ffffff, #dff6f3);
  box-shadow: 0 4px 0 #96c7c7, 0 10px 20px rgba(75, 125, 136, 0.17);
  font: 800 16px Pretendard, system-ui, sans-serif;
}
button:disabled { opacity: 0.48; cursor: not-allowed; }
button:not(:disabled):active { transform: translateY(2px); box-shadow: 0 2px 0 #96c7c7, 0 6px 14px rgba(75,125,136,0.14); }

.toast {
  position: fixed;
  left: 50%;
  bottom: 82px;
  transform: translateX(-50%) translateY(12px);
  opacity: 0;
  z-index: 30000;
  max-width: min(90vw, 420px);
  padding: 9px 13px;
  border: 1px solid rgba(32, 75, 86, 0.18);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.94);
  color: #17313a;
  box-shadow: 0 14px 34px rgba(70, 124, 138, 0.18);
  pointer-events: none;
  transition: opacity 160ms ease, transform 160ms ease;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

.fx-flash,
body.fx-flash::after,
.board.fx-flash::after {
  pointer-events: none;
  animation: fxFlash 200ms ease-out forwards;
}
.fx-flash:not(body):not(.board) {
  position: fixed;
  inset: 0;
  z-index: 19000;
  background: rgba(255,255,255,0.72);
  mix-blend-mode: screen;
}
body.fx-flash::after,
.board.fx-flash::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 19000;
  background: rgba(255,255,255,0.72);
  mix-blend-mode: screen;
}
.board.fx-flash::after {
  position: absolute;
  border-radius: inherit;
}

.fx-shake { animation: fxShake 150ms ease-in-out both; }

.score-pop { animation: scorePop 300ms cubic-bezier(0.18, 0.9, 0.22, 1) both; }

.float-score {
  position: absolute;
  z-index: 21000;
  pointer-events: none;
  font: 800 20px Pretendard, system-ui, sans-serif;
  color: #e45655;
  text-shadow: 0 2px 0 #fff, 0 8px 18px rgba(185, 73, 65, 0.25);
  animation: floatScore 800ms ease-out forwards;
  will-change: transform, opacity;
}

.slot.is-danger,
.hold-slot.is-danger {
  border-color: rgba(229, 65, 76, 0.72);
  background: rgba(255, 232, 230, 0.78);
  animation: slotDanger 1050ms ease-in-out infinite;
}

.slot.just-filled,
.hold-slot.just-filled {
  animation: slotJustFilled 420ms ease-out both;
}

.combo-pop {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 20000;
  transform: translate(-50%, -50%) scale(0.82);
  opacity: 0;
  pointer-events: none;
  font: 800 34px Pretendard, system-ui, sans-serif;
  color: #ff5d57;
  text-shadow: 0 3px 0 #fff, 0 10px 26px rgba(196, 61, 61, 0.22);
}
.combo-pop.tier1 {
  --combo-scale: 1;
  --combo-peak-scale: 1.22;
  --combo-end-scale: 1.08;
  color: #ff675f;
  text-shadow: 0 3px 0 #fff, 0 10px 24px rgba(205, 72, 64, 0.24);
}
.combo-pop.tier2 {
  --combo-scale: 1.16;
  --combo-peak-scale: 1.42;
  --combo-end-scale: 1.25;
  color: #ff8a28;
  text-shadow: 0 3px 0 #fff8de, 0 0 18px rgba(255, 188, 74, 0.42), 0 14px 30px rgba(206, 94, 37, 0.28);
}
.combo-pop.tier3 {
  --combo-scale: 1.34;
  --combo-peak-scale: 1.64;
  --combo-end-scale: 1.45;
  color: #f23c66;
  text-shadow: 0 3px 0 #fff5d7, 0 0 18px rgba(255, 219, 78, 0.62), 0 0 36px rgba(255, 88, 70, 0.36), 0 18px 38px rgba(154, 46, 72, 0.34);
}
.combo-pop.show { animation: comboFloat 880ms cubic-bezier(0.16, 1.05, 0.24, 1) forwards; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.modal {
  position: fixed;
  inset: 0;
  z-index: 25000;
  display: grid;
  place-items: center;
  padding: 18px;
  background: rgba(37, 70, 78, 0.36);
}
.modal[hidden] { display: none; }
.modal-panel {
  position: relative;
  width: min(430px, 100%);
  overflow: hidden;
  border: 1px solid rgba(32, 75, 86, 0.18);
  border-radius: 8px;
  padding: 34px 22px 24px;
  text-align: center;
  background: linear-gradient(160deg, rgba(255,255,255,0.98), rgba(220, 249, 245, 0.96));
  box-shadow: 0 30px 90px rgba(64, 112, 124, 0.28);
}
.modal h2 { margin: 0; font-family: Pretendard, system-ui, sans-serif; font-size: 56px; color: #e45655; }
.modal p { margin: 8px 0 22px; font-size: 22px; font-weight: 800; }
#confetti { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.game-over-panel h2 { color: #374951; }

#nickDialog.modal,
#rankDialog.modal {
  padding: max(18px, env(safe-area-inset-top)) 18px max(18px, env(safe-area-inset-bottom));
  background:
    linear-gradient(180deg, rgba(6, 10, 28, 0.44), rgba(6, 10, 28, 0.8)),
    radial-gradient(ellipse at 50% 42%, rgba(5, 8, 24, 0.78) 0 28%, rgba(5, 8, 24, 0.46) 52%, rgba(8, 12, 35, 0.72) 100%),
    url("assets/onboard-bg.jpg") center / cover no-repeat,
    linear-gradient(160deg, #081126, #24104d 58%, #080b1b);
}

.nick-panel,
.rank-panel,
.code-panel {
  border: 1px solid rgba(201, 232, 255, 0.18);
  color: #f4fbff;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.035) 28%, rgba(255,255,255,0.07)),
    linear-gradient(160deg, rgba(9, 16, 42, 0.86), rgba(22, 12, 54, 0.88) 62%, rgba(8, 12, 34, 0.9));
  box-shadow:
    0 28px 70px rgba(0, 0, 0, 0.42),
    inset 0 1px 0 rgba(255,255,255,0.18);
  backdrop-filter: blur(10px);
  animation: dialogEnter 320ms cubic-bezier(0.18, 0.9, 0.22, 1) both;
  will-change: transform, opacity;
}

.nick-panel {
  width: min(480px, 100%);
  padding: clamp(34px, 8dvh, 58px) clamp(18px, 6vw, 30px) 24px;
  text-align: center;
}

.nick-title {
  position: relative;
  margin: 0 0 14px;
  font: 900 clamp(58px, 15vw, 92px) Pretendard, system-ui, sans-serif;
  font-style: italic;
  line-height: 0.88;
  letter-spacing: 0;
  color: transparent;
  background:
    linear-gradient(98deg, #ffffff 0 12%, #5ce8ff 29%, #fff06a 52%, #ff9871 72%, #ff4c76 100%);
  -webkit-background-clip: text;
  background-clip: text;
  text-shadow:
    -10px 0 0 rgba(83, 232, 255, 0.12),
    -20px 0 0 rgba(255, 76, 118, 0.08),
    0 18px 34px rgba(255, 76, 118, 0.24);
}

.nick-sub {
  margin: 0 0 20px;
  color: rgba(244, 251, 255, 0.95);
  font-size: 20px;
  font-weight: 900;
  line-height: 1.35;
}

.nick-sub span {
  display: block;
  margin-top: 5px;
  color: rgba(220, 241, 255, 0.66);
  font-size: 13px;
  font-weight: 800;
}

#nickInput {
  width: 100%;
  min-height: 56px;
  border: 2px solid rgba(181, 224, 255, 0.2);
  border-radius: 8px;
  padding: 0 16px;
  color: #ffffff;
  background: rgba(5, 10, 28, 0.72);
  box-shadow:
    inset 0 2px 5px rgba(0, 0, 0, 0.3),
    0 0 0 1px rgba(255,255,255,0.04);
  font: 900 22px Pretendard, system-ui, sans-serif;
  text-align: center;
  outline: none;
  transition: border-color 140ms ease, background-color 140ms ease, transform 140ms ease;
}

#nickInput::placeholder {
  color: rgba(226, 240, 255, 0.42);
}

#nickInput:focus {
  border-color: rgba(255, 223, 87, 0.9);
  background: rgba(8, 16, 38, 0.9);
  transform: translateY(-1px);
}

.nick-error {
  min-height: 18px;
  margin: 8px 0 12px;
  color: #ff8a97;
  font-size: 12px;
  font-weight: 900;
  line-height: 1.25;
}

.nick-save {
  width: 100%;
  min-height: 58px;
  color: #220c19;
  border-color: rgba(255, 236, 127, 0.46);
  background:
    linear-gradient(180deg, rgba(255,255,255,0.44), rgba(255,255,255,0) 38%),
    linear-gradient(92deg, #5ce8ff 0%, #fff06a 45%, #ff6c7f 100%);
  box-shadow: 0 5px 0 #a43159, 0 18px 32px rgba(255, 76, 118, 0.26);
  font-size: 19px;
}

.nick-save:not(:disabled):active {
  box-shadow: 0 2px 0 #a43159, 0 9px 18px rgba(255, 76, 118, 0.18);
}

.nick-title,
.nick-sub,
#nickInput,
.nick-error,
.nick-save {
  opacity: 0;
  animation: onboardStep 360ms cubic-bezier(0.18, 0.9, 0.22, 1) both;
  will-change: transform, opacity;
}

.nick-title { animation-delay: 70ms; }
.nick-sub { animation-delay: 150ms; }
#nickInput { animation-delay: 230ms; }
.nick-error { animation-delay: 270ms; }
.nick-save { animation-delay: 320ms; }

.nick-save:disabled {
  color: rgba(244, 251, 255, 0.52);
  border-color: rgba(181, 224, 255, 0.12);
  background: rgba(10, 20, 44, 0.72);
  box-shadow: none;
}

.rank-panel {
  width: min(560px, 100%);
  max-height: min(82dvh, 760px);
  padding: 24px 18px 16px;
  display: grid;
  /* 제목·요약·시상대는 제 높이대로, **순위 목록만 남은 공간을 먹고 스크롤**한다.
     예전엔 1fr이 시상대에 걸려 있어서 목록이 패널 밖으로 밀려나 겹쳤다. */
  grid-template-rows: auto auto auto minmax(0, 1fr) auto auto;
  text-align: left;
}

.rank-title {
  margin: 0;
  color: #f4fbff;
  font: 900 clamp(30px, 7vw, 44px) Pretendard, system-ui, sans-serif;
  line-height: 1;
  letter-spacing: 0;
  text-shadow: -8px 0 0 rgba(83, 232, 255, 0.1), 0 10px 24px rgba(255, 76, 118, 0.18);
}

.rank-sub {
  margin: 6px 0 14px;
  color: rgba(220, 241, 255, 0.66);
  font-size: 13px;
  font-weight: 900;
}

.rank-list {
  margin: 0;
  padding: 0;
  list-style: none;
  /* 패널 그리드가 남는 높이를 정해주므로 목록은 그 안에서만 스크롤하면 된다.
     고정 max-height를 같이 주면 패널 높이와 어긋나서 아래 요소를 밀어낸다. */
  min-height: 0;
  overflow-y: auto;
  display: grid;
  gap: 7px;
  scrollbar-color: rgba(92, 232, 255, 0.36) rgba(255,255,255,0.08);
}

.rank-row {
  min-width: 0;
  min-height: 48px;
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) max-content 48px;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border: 1px solid rgba(181, 224, 255, 0.14);
  border-radius: 8px;
  color: #f4fbff;
  background: linear-gradient(180deg, rgba(255,255,255,0.1), rgba(255,255,255,0.045));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}

.rank-no {
  color: rgba(220, 241, 255, 0.56);
  font-size: 14px;
  font-weight: 900;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.rank-nick {
  min-width: 0;
  overflow: hidden;
  color: #f4fbff;
  font-size: 16px;
  font-weight: 900;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rank-time {
  color: #ff7e93;
  font-size: 22px;
  font-weight: 900;
  line-height: 1;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.rank-combo {
  color: rgba(220, 241, 255, 0.56);
  font-size: 13px;
  font-weight: 900;
  text-align: right;
  white-space: nowrap;
}

.rank-row.is-me {
  border-color: rgba(92, 232, 255, 0.58);
  background:
    linear-gradient(90deg, rgba(92, 232, 255, 0.2), rgba(255,255,255,0.08) 48%, rgba(255, 240, 106, 0.14)),
    linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.05));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.14), 0 0 0 2px rgba(92, 232, 255, 0.12);
}

.rank-row.top1,
.rank-row.top2,
.rank-row.top3 {
  min-height: 52px;
}

.rank-row.top1 {
  border-color: rgba(255, 223, 87, 0.62);
  background: linear-gradient(180deg, rgba(255, 223, 87, 0.22), rgba(255, 169, 72, 0.12));
}

.rank-row.top2 {
  border-color: rgba(201, 232, 255, 0.42);
  background: linear-gradient(180deg, rgba(201, 232, 255, 0.18), rgba(141, 177, 208, 0.08));
}

.rank-row.top3 {
  border-color: rgba(255, 157, 103, 0.5);
  background: linear-gradient(180deg, rgba(255, 157, 103, 0.2), rgba(255, 108, 127, 0.08));
}

.rank-row.top1 .rank-no,
.rank-row.top1 .rank-time { color: #fff06a; }
.rank-row.top2 .rank-no,
.rank-row.top2 .rank-time { color: #d7eeff; }
.rank-row.top3 .rank-no,
.rank-row.top3 .rank-time { color: #ffb086; }

.rank-row.top1 .rank-time,
.rank-row.top2 .rank-time,
.rank-row.top3 .rank-time {
  font-size: 24px;
}

.rank-empty {
  min-height: 96px;
  display: grid;
  place-items: center;
  padding: 22px;
  border: 1px dashed rgba(181, 224, 255, 0.22);
  border-radius: 8px;
  color: rgba(220, 241, 255, 0.6);
  background: rgba(255,255,255,0.06);
  font-size: 14px;
  font-weight: 900;
  text-align: center;
}

.rank-actions {
  display: flex;
  justify-content: flex-end;
  gap: 9px;
  margin-top: 14px;
}

.rank-actions button {
  min-width: 104px;
  min-height: 46px;
  padding: 0 16px;
  color: #f4fbff;
  border-color: rgba(181, 224, 255, 0.18);
  background: linear-gradient(180deg, rgba(255,255,255,0.16), rgba(255,255,255,0.07));
  box-shadow: 0 4px 0 rgba(22, 44, 76, 0.8), 0 12px 24px rgba(0, 0, 0, 0.22);
}

#winDialog .modal-panel {
  width: min(540px, 100%);
  padding: 28px 22px 22px;
  color: #17343b;
  background:
    radial-gradient(circle at 50% 0%, rgba(255,255,255,0.92), transparent 38%),
    linear-gradient(160deg, rgba(255,255,255,0.98), rgba(222, 251, 247, 0.96));
}

#winDialog .modal-panel::before,
#winDialog .modal-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

#winDialog .modal-panel::before {
  z-index: 0;
  background:
    linear-gradient(118deg, transparent 10%, rgba(255,255,255,0.62) 18%, transparent 29%),
    radial-gradient(circle at 50% 8%, rgba(255, 221, 111, 0.2), transparent 44%);
  opacity: 0.38;
}

#winDialog .modal-panel::after {
  z-index: 0;
  border-radius: inherit;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.88);
}

#winDialog .win-hero,
#winDialog .win-stats,
#winDialog .win-record-line,
#winDialog .win-actions {
  position: relative;
  z-index: 1;
}

.win-hero {
  display: grid;
  justify-items: center;
  gap: 6px;
  margin-bottom: 16px;
}

.win-badge {
  display: inline-grid;
  place-items: center;
  min-width: 82px;
  min-height: 32px;
  padding: 5px 14px 6px;
  border: 1px solid rgba(32, 75, 86, 0.16);
  border-radius: 999px;
  color: #26454d;
  background: linear-gradient(180deg, #ffffff, #dff7f0);
  box-shadow: 0 6px 16px rgba(63, 116, 125, 0.14), inset 0 1px 0 rgba(255,255,255,0.88);
  font: 900 15px Pretendard, system-ui, sans-serif;
  letter-spacing: 0;
}

.win-time {
  font: 900 clamp(72px, 16vw, 122px) Pretendard, system-ui, sans-serif;
  line-height: 0.9;
  letter-spacing: 0;
  color: #e45655;
  text-shadow: 0 3px 0 rgba(255,255,255,0.92), 0 16px 36px rgba(190, 77, 75, 0.2);
  font-variant-numeric: tabular-nums;
}

.win-time-sub {
  color: rgba(38, 72, 80, 0.68);
  font-size: 13px;
  font-weight: 900;
}

.win-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 9px;
  margin: 0 0 14px;
}

.win-stat {
  min-width: 0;
  padding: 12px 8px 10px;
  border: 1px solid rgba(32, 75, 86, 0.15);
  border-radius: 8px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.86), rgba(238, 250, 246, 0.76));
  box-shadow: 0 10px 22px rgba(70, 124, 138, 0.13), inset 0 1px 0 rgba(255,255,255,0.88);
}

.win-stat-label {
  display: block;
  color: rgba(37, 76, 84, 0.62);
  font-size: 11px;
  font-weight: 900;
  white-space: nowrap;
}

.win-stat-value {
  display: block;
  margin-top: 3px;
  color: #18343d;
  font: 900 22px Pretendard, system-ui, sans-serif;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.win-stat-delta {
  display: inline-block;
  min-height: 18px;
  margin-top: 5px;
  padding: 2px 7px;
  border-radius: 999px;
  color: rgba(46, 74, 80, 0.66);
  background: rgba(45, 91, 100, 0.08);
  font-size: 12px;
  font-weight: 900;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.win-stat-delta.up {
  color: #13784f;
  background: rgba(28, 174, 111, 0.14);
}

.win-stat-delta.up::before {
  content: "↑ ";
}

.win-stat-delta.down {
  color: #a2464d;
  background: rgba(172, 69, 79, 0.12);
}

.win-stat-delta.down::before {
  content: "↓ ";
}

.win-record-line {
  margin: 2px 0 16px;
  padding: 9px 12px;
  border: 1px solid rgba(236, 173, 54, 0.4);
  border-radius: 8px;
  color: #7a4d09;
  background: linear-gradient(180deg, rgba(255, 248, 218, 0.94), rgba(255, 229, 145, 0.62));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.78);
  font-size: 15px;
  font-weight: 900;
}

.win-actions {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: 10px;
}

.win-actions button {
  min-height: 48px;
  padding: 0 14px;
}

.win-actions button:first-child,
.win-actions .primary,
.win-actions [data-action="restart"] {
  min-height: 56px;
  color: #fff;
  border-color: rgba(174, 54, 54, 0.28);
  background: linear-gradient(180deg, #ff8175, #e45655);
  box-shadow: 0 5px 0 #b93a43, 0 16px 28px rgba(202, 62, 67, 0.26);
  font-size: 18px;
}

.win-actions button:first-child:not(:disabled):active,
.win-actions .primary:not(:disabled):active,
.win-actions [data-action="restart"]:not(:disabled):active {
  box-shadow: 0 2px 0 #b93a43, 0 9px 18px rgba(202, 62, 67, 0.2);
}

#winDialog.is-record .modal-panel {
  border-color: rgba(235, 179, 54, 0.84);
  background:
    radial-gradient(circle at 50% 0%, rgba(255, 248, 198, 0.92), transparent 36%),
    conic-gradient(from -18deg at 50% 6%, rgba(255, 231, 122, 0.28), transparent 8%, rgba(255,255,255,0.42) 12%, transparent 18%, rgba(255, 206, 80, 0.22) 24%, transparent 34%),
    linear-gradient(160deg, rgba(255,255,255,0.98), rgba(255, 245, 203, 0.96) 52%, rgba(228, 252, 245, 0.96));
  box-shadow:
    0 0 0 2px rgba(255, 220, 91, 0.28),
    0 30px 90px rgba(153, 102, 20, 0.26),
    0 0 46px rgba(255, 204, 73, 0.34);
}

#winDialog.is-record .modal-panel::before {
  opacity: 0.72;
  background:
    linear-gradient(112deg, transparent 18%, rgba(255,255,255,0.72) 27%, transparent 37%),
    linear-gradient(68deg, transparent 12%, rgba(255, 224, 94, 0.34) 25%, transparent 39%),
    radial-gradient(circle at 50% 0%, rgba(255, 238, 116, 0.56), transparent 46%);
  animation: winRaySweep 5.8s linear infinite;
  will-change: transform, opacity;
}

#winDialog.is-record .win-badge.is-record {
  position: relative;
  min-width: 104px;
  color: #5b3700;
  border-color: rgba(154, 100, 11, 0.34);
  border-radius: 8px;
  background:
    linear-gradient(180deg, #fff8c6 0%, #ffd86b 54%, #f0a72c 100%);
  box-shadow:
    0 3px 0 rgba(145, 91, 8, 0.48),
    0 12px 24px rgba(199, 128, 19, 0.28),
    inset 0 1px 0 rgba(255,255,255,0.84);
  text-shadow: 0 1px 0 rgba(255,255,255,0.58);
  /* 등장 애니메이션(winReveal)이 opacity 0에서 시작하는데, 여기서 animation을 통째로
     덮어쓰면 그 등장이 사라져 배지가 투명한 채로 굳는다(실제로 안 보였음).
     둘을 같이 돌린다 — 먼저 나타나고(winReveal), 그 뒤로 계속 둥둥 뜬다(winMedalFloat). */
  animation:
    winReveal 360ms cubic-bezier(0.18, 0.9, 0.22, 1) 40ms both,
    winMedalFloat 2.6s ease-in-out 420ms infinite;
  will-change: transform, opacity;
}

#winDialog.is-record .win-badge.is-record::before,
#winDialog.is-record .win-badge.is-record::after {
  content: "";
  position: absolute;
  bottom: -10px;
  width: 18px;
  height: 18px;
  background: #d94755;
  clip-path: polygon(0 0, 100% 0, 72% 100%, 50% 68%, 24% 100%);
  z-index: 0;
}

#winDialog.is-record .win-badge.is-record::before {
  left: 15px;
  transform: rotate(7deg);
}

#winDialog.is-record .win-badge.is-record::after {
  right: 15px;
  transform: rotate(-7deg);
}

#winDialog.is-record .win-time {
  color: transparent;
  background: linear-gradient(180deg, #fff7b0 0%, #ffd65a 32%, #f3a82b 62%, #fff2a0 100%);
  -webkit-background-clip: text;
  background-clip: text;
  text-shadow:
    0 2px 0 rgba(112, 70, 8, 0.18),
    0 0 20px rgba(255, 212, 73, 0.56),
    0 16px 34px rgba(182, 101, 15, 0.24);
}

#winDialog.is-record .win-stat {
  border-color: rgba(218, 171, 68, 0.3);
  background: linear-gradient(180deg, rgba(255,255,255,0.92), rgba(255, 246, 210, 0.76));
}

#winDialog .win-badge,
#winDialog .win-time,
#winDialog .win-time-sub,
#winDialog .win-stat,
#winDialog .win-record-line,
#winDialog .win-actions {
  opacity: 0;
  animation: winReveal 360ms cubic-bezier(0.18, 0.9, 0.22, 1) both;
  will-change: transform, opacity;
}

#winDialog .win-badge { animation-delay: 40ms; }
#winDialog .win-time { animation-delay: 120ms; }
#winDialog.is-record .win-time { animation-name: winRecordTimePop; animation-duration: 520ms; }
#winDialog .win-time-sub { animation-delay: 190ms; }
#winDialog .win-stat:nth-child(1) { animation-delay: 250ms; }
#winDialog .win-stat:nth-child(2) { animation-delay: 310ms; }
#winDialog .win-stat:nth-child(3) { animation-delay: 370ms; }
#winDialog .win-stat:nth-child(4) { animation-delay: 430ms; }
#winDialog .win-record-line { animation-delay: 490ms; }
#winDialog .win-actions { animation-delay: 560ms; }

@keyframes linkFade {
  0% { opacity: 0; stroke-dasharray: 0 520; stroke-width: 7; }
  22% { opacity: 1; stroke-width: 6; }
  68% { opacity: 0.9; }
  100% { opacity: 0; stroke-dasharray: 520 0; stroke-width: 2; }
}
@keyframes tileMoveOut {
  0% { opacity: 1; transform: translateY(0) scale(1) rotate(0); filter: brightness(1); }
  38% { opacity: 1; transform: translateY(-9px) scale(1.04) rotate(-1.5deg); filter: brightness(1.2); }
  100% { opacity: 0; transform: translateY(-24px) scale(0.82) rotate(3deg); filter: brightness(1.08); }
}
@keyframes tilePop {
  0% { filter: brightness(1.16) saturate(1.1); opacity: 1; transform: translateY(0) scale(1) rotate(0); }
  30% { filter: brightness(1.7) saturate(1.25); transform: translateY(-7px) rotate(-2deg) scale(1.12); }
  62% { opacity: 0.92; transform: translateY(-12px) rotate(2deg) scale(0.94); }
  100% { transform: translateY(-24px) rotate(5deg) scale(0.68); opacity: 0; filter: brightness(1.22) saturate(1.1); }
}
@keyframes shardFly {
  0% { opacity: 1; filter: brightness(1.25); }
  65% { opacity: 0.95; }
  to {
    opacity: 0;
    transform: translate(calc(-50% + var(--shard-x)), calc(-50% + var(--shard-y))) rotate(var(--shard-rot)) scale(0.22);
  }
}
@keyframes sparkFly {
  0% { opacity: 1; filter: brightness(1.8); }
  45% { opacity: 0.95; transform: translate(-50%, -50%) scale(1.12); }
  to {
    opacity: 0;
    transform: translate(calc(-50% + var(--spark-x)), calc(-50% + var(--spark-y))) scale(0.2);
  }
}
@keyframes hintPulse {
  0%, 100% { filter: brightness(1.04) saturate(1.05); box-shadow: 0 0 0 0 rgba(255, 107, 102, 0); }
  50% {
    filter: brightness(1.34) saturate(1.22);
    outline: 3px solid #ff6b66;
    outline-offset: 2px;
    box-shadow:
      inset 1px 1px 0 rgba(255,255,255,0.9),
      0 0 0 5px rgba(255, 107, 102, 0.12),
      0 14px 24px rgba(196, 72, 76, 0.24);
  }
}
@keyframes wrongShake {
  15% { transform: translateX(-5px) rotate(-1deg); }
  35% { transform: translateX(5px) rotate(1deg); }
  55% { transform: translateX(-3px) rotate(-0.5deg); }
  75% { transform: translateX(2px) rotate(0.4deg); }
}
@keyframes slotMatch {
  0% { opacity: 1; transform: translateY(0) scale(1); filter: brightness(1); }
  42% { transform: translateY(-7px) scale(1.14); filter: brightness(1.46) saturate(1.18); }
  68% { opacity: 0.9; transform: translateY(-10px) scale(0.9); }
  100% { transform: translateY(-20px) scale(0.62); opacity: 0; filter: brightness(1.15); }
}
@keyframes comboFloat {
  0% { opacity: 0; transform: translate(-50%, -38%) scale(0.62) rotate(-2deg); filter: brightness(1); }
  18% { opacity: 1; transform: translate(-50%, -54%) scale(var(--combo-peak-scale, 1.22)) rotate(1deg); filter: brightness(1.28); }
  34% { opacity: 1; transform: translate(-50%, -58%) scale(var(--combo-scale, 1)) rotate(0); }
  56% { opacity: 0.95; transform: translate(-50%, -68%) scale(var(--combo-scale, 1)); }
  100% { opacity: 0; transform: translate(-50%, -102%) scale(var(--combo-end-scale, 1.08)); filter: brightness(1.06); }
}
@keyframes fxFlash {
  0% { opacity: 0; }
  28% { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes fxShake {
  0%, 100% { transform: translate3d(0, 0, 0); }
  20% { transform: translate3d(-3px, 2px, 0); }
  40% { transform: translate3d(4px, -1px, 0); }
  60% { transform: translate3d(-4px, 1px, 0); }
  80% { transform: translate3d(3px, 0, 0); }
}
@keyframes scorePop {
  0% { transform: scale(1); filter: brightness(1); }
  46% { transform: scale(1.25); filter: brightness(1.2); }
  100% { transform: scale(1); filter: brightness(1); }
}
@keyframes floatScore {
  0% { opacity: 0; transform: translate3d(-50%, 4px, 0) scale(0.86); }
  18% { opacity: 1; transform: translate3d(-50%, -8px, 0) scale(1.08); }
  100% { opacity: 0; transform: translate3d(-50%, -48px, 0) scale(0.96); }
}
@keyframes slotDanger {
  0%, 100% { transform: translateZ(0) scale(1); box-shadow: inset 0 1px 0 rgba(255,255,255,0.85), 0 0 0 0 rgba(229, 65, 76, 0.08); }
  50% { transform: translateZ(0) scale(1.025); box-shadow: inset 0 1px 0 rgba(255,255,255,0.9), 0 0 0 5px rgba(229, 65, 76, 0.16), 0 10px 22px rgba(180, 61, 66, 0.16); }
}
@keyframes slotJustFilled {
  0% { transform: scale(0.98); box-shadow: inset 0 0 0 0 rgba(255,255,255,0), 0 0 0 0 rgba(255, 213, 93, 0); }
  38% { transform: scale(1.045); box-shadow: inset 0 0 0 2px rgba(255,255,255,0.9), 0 0 0 5px rgba(255, 213, 93, 0.36), 0 10px 20px rgba(192, 119, 48, 0.2); }
  100% { transform: scale(1); box-shadow: inset 0 1px 0 rgba(255,255,255,0.82), 0 12px 22px rgba(65, 118, 126, 0.12); }
}
@keyframes idleShimmer {
  0%, 86%, 100% { opacity: 0.42; transform: translateZ(0) scale(1); }
  90% { opacity: 0.86; transform: translate3d(-2px, 1px, 0) scale(1.08); }
  94% { opacity: 0.56; transform: translateZ(0) scale(1.02); }
}
@keyframes tileFlipOut {
  0% {
    transform: rotateY(0deg);
    filter: brightness(1.05) saturate(1.06);
  }
  100% {
    transform: rotateY(90deg);
    filter: brightness(0.96) saturate(0.92);
  }
}
@keyframes tileFlipIn {
  0% {
    transform: rotateY(-90deg) scale(1);
    filter: brightness(0.98) saturate(0.96);
    box-shadow:
      inset 1px 1px 0 rgba(255,255,255,0.7),
      inset -2px -2px 0 rgba(96,62,36,0.12),
      1px 2px 0 var(--tile-edge, #b9814c),
      3px 5px 9px rgba(59, 92, 101, 0.2);
  }
  72% {
    transform: rotateY(5deg) scale(1.04);
    filter: brightness(1.08) saturate(1.04);
  }
  100% {
    transform: rotateY(0deg) scale(1);
  }
}
@keyframes feverGaugePulse {
  0%, 100% { transform: translateZ(0) scale(1.012); }
  50% { transform: translateZ(0) scale(1.032); }
}
@keyframes feverGaugeShine {
  0% { transform: translate3d(-55%, 0, 0) rotate(0.001deg); opacity: 0; }
  28% { opacity: 0.72; }
  100% { transform: translate3d(55%, 0, 0) rotate(0.001deg); opacity: 0; }
}
@keyframes feverEdgePulse {
  0%, 100% {
    opacity: 0.42;
  }
  50% {
    opacity: 0.84;
  }
}
@keyframes feverBurst {
  0% { opacity: 0; transform: scale(0.55) rotate(-8deg); }
  18% { opacity: 1; transform: scale(0.86) rotate(4deg); }
  62% { opacity: 0.7; transform: scale(1.28) rotate(18deg); }
  100% { opacity: 0; transform: scale(1.75) rotate(34deg); }
}
@keyframes feverParticleFloat {
  0% {
    opacity: 0;
    transform: translate3d(0, 10px, 0) scale(0.45);
  }
  18% {
    opacity: 0.95;
  }
  100% {
    opacity: 0;
    transform: translate3d(var(--drift-x, 18px), var(--rise, -96px), 0) scale(1);
  }
}
@keyframes winReveal {
  0% { opacity: 0; transform: translate3d(0, 14px, 0) scale(0.96); }
  72% { opacity: 1; transform: translate3d(0, -2px, 0) scale(1.01); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes winRecordTimePop {
  0% { opacity: 0; transform: translate3d(0, 22px, 0) scale(0.76); }
  54% { opacity: 1; transform: translate3d(0, -8px, 0) scale(1.11); }
  78% { opacity: 1; transform: translate3d(0, 2px, 0) scale(0.98); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes winRaySweep {
  0% { opacity: 0.38; transform: translate3d(-18%, 0, 0) rotate(0.001deg); }
  45% { opacity: 0.74; }
  100% { opacity: 0.38; transform: translate3d(18%, 0, 0) rotate(0.001deg); }
}
@keyframes winMedalFloat {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(-1deg); }
  50% { transform: translate3d(0, -3px, 0) rotate(1deg); }
}
@keyframes dialogEnter {
  0% { opacity: 0; transform: translate3d(0, 16px, 0) scale(0.96); }
  72% { opacity: 1; transform: translate3d(0, -2px, 0) scale(1.01); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes onboardStep {
  0% { opacity: 0; transform: translate3d(0, 18px, 0); }
  72% { opacity: 1; transform: translate3d(0, -2px, 0); }
  100% { opacity: 1; transform: translate3d(0, 0, 0); }
}

@media (prefers-color-scheme: dark) {
  #nickDialog.modal,
  #rankDialog.modal {
    background:
      linear-gradient(180deg, rgba(4, 8, 22, 0.5), rgba(4, 8, 22, 0.86)),
      radial-gradient(ellipse at 50% 42%, rgba(3, 6, 18, 0.82) 0 28%, rgba(3, 6, 18, 0.48) 52%, rgba(7, 10, 30, 0.78) 100%),
      url("assets/onboard-bg.jpg") center / cover no-repeat,
      linear-gradient(160deg, #070f22, #211044 58%, #070916);
  }

  .nick-panel,
  .rank-panel,
  .code-panel {
    color: #effcf9;
    border-color: rgba(188, 231, 228, 0.18);
    background:
      radial-gradient(circle at 50% 0%, rgba(137, 227, 213, 0.16), transparent 40%),
      linear-gradient(160deg, rgba(23, 45, 52, 0.98), rgba(14, 37, 45, 0.96));
    box-shadow: 0 30px 90px rgba(2, 12, 16, 0.5);
  }

  .nick-title {
    background: linear-gradient(95deg, #effcf9 0 10%, #5de3ee 30%, #ffe277 54%, #ff8b7e 78%, #ff6c74 100%);
    -webkit-background-clip: text;
    background-clip: text;
    text-shadow:
      -10px 0 0 rgba(93, 227, 238, 0.12),
      -20px 0 0 rgba(255, 108, 116, 0.08),
      0 16px 34px rgba(255, 108, 116, 0.18);
  }

  .nick-sub,
  .rank-title,
  .rank-nick {
    color: #effcf9;
  }

  .nick-sub span,
  .rank-sub,
  .rank-combo {
    color: rgba(224, 249, 245, 0.62);
  }

  #nickInput {
    color: #effcf9;
    border-color: rgba(188, 231, 228, 0.18);
    background: rgba(7, 26, 32, 0.68);
    box-shadow: inset 0 2px 5px rgba(1, 10, 13, 0.32), 0 10px 22px rgba(0, 0, 0, 0.22);
  }

  #nickInput:focus {
    border-color: rgba(255, 108, 116, 0.78);
    background: rgba(10, 34, 41, 0.86);
  }

  .nick-error {
    color: #ff9aa1;
  }

  .rank-list {
    scrollbar-color: rgba(199, 237, 233, 0.35) rgba(199, 237, 233, 0.08);
  }

  .rank-row {
    color: #effcf9;
    border-color: rgba(188, 231, 228, 0.14);
    background: linear-gradient(180deg, rgba(41, 71, 77, 0.88), rgba(23, 55, 62, 0.76));
  }

  .rank-no {
    color: rgba(224, 249, 245, 0.58);
  }

  .rank-time {
    color: #ff8b7e;
  }

  .rank-row.is-me {
    border-color: rgba(93, 227, 238, 0.54);
    background:
      linear-gradient(90deg, rgba(93, 227, 238, 0.16), rgba(41, 71, 77, 0.86) 48%, rgba(255, 226, 102, 0.12)),
      linear-gradient(180deg, rgba(42, 76, 82, 0.9), rgba(24, 58, 64, 0.78));
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 0 0 2px rgba(93, 227, 238, 0.1);
  }

  .rank-row.top1 {
    border-color: rgba(255, 213, 83, 0.58);
    background: linear-gradient(180deg, rgba(103, 75, 21, 0.82), rgba(88, 63, 18, 0.72));
  }

  .rank-row.top2 {
    border-color: rgba(194, 215, 222, 0.44);
    background: linear-gradient(180deg, rgba(66, 83, 89, 0.88), rgba(42, 62, 68, 0.76));
  }

  .rank-row.top3 {
    border-color: rgba(224, 145, 83, 0.5);
    background: linear-gradient(180deg, rgba(101, 61, 36, 0.84), rgba(72, 48, 35, 0.72));
  }

  .rank-row.top1 .rank-no,
  .rank-row.top1 .rank-time { color: #ffe07a; }
  .rank-row.top2 .rank-no,
  .rank-row.top2 .rank-time { color: #d9edf1; }
  .rank-row.top3 .rank-no,
  .rank-row.top3 .rank-time { color: #ffbd89; }

  .rank-empty {
    color: rgba(224, 249, 245, 0.6);
    border-color: rgba(188, 231, 228, 0.2);
    background: rgba(213, 248, 241, 0.08);
  }

  #winDialog.modal {
    background: rgba(8, 19, 24, 0.58);
  }

  #winDialog .modal-panel {
    color: #effcf9;
    border-color: rgba(188, 231, 228, 0.18);
    background:
      radial-gradient(circle at 50% 0%, rgba(137, 227, 213, 0.16), transparent 40%),
      linear-gradient(160deg, rgba(23, 45, 52, 0.98), rgba(14, 37, 45, 0.96));
    box-shadow: 0 30px 90px rgba(2, 12, 16, 0.5);
  }

  #winDialog .win-badge {
    color: #dff7f1;
    border-color: rgba(183, 232, 225, 0.22);
    background: linear-gradient(180deg, rgba(58, 91, 96, 0.96), rgba(31, 69, 75, 0.96));
  }

  #winDialog .win-time-sub,
  #winDialog .win-stat-label {
    color: rgba(224, 249, 245, 0.68);
  }

  #winDialog .win-stat {
    border-color: rgba(188, 231, 228, 0.14);
    background: linear-gradient(180deg, rgba(41, 71, 77, 0.88), rgba(23, 55, 62, 0.76));
  }

  #winDialog .win-stat-value {
    color: #f1fffb;
  }

  #winDialog .win-stat-delta {
    color: rgba(228, 248, 245, 0.72);
    background: rgba(213, 248, 241, 0.1);
  }

  #winDialog .win-stat-delta.up {
    color: #7ff0ba;
    background: rgba(59, 214, 143, 0.18);
  }

  #winDialog .win-stat-delta.down {
    color: #f0a1a8;
    background: rgba(222, 98, 109, 0.16);
  }

  #winDialog .win-record-line {
    color: #ffe7a0;
    border-color: rgba(247, 205, 86, 0.34);
    background: linear-gradient(180deg, rgba(103, 75, 21, 0.78), rgba(83, 59, 19, 0.62));
  }

  #winDialog.is-record .modal-panel {
    border-color: rgba(255, 213, 83, 0.74);
    background:
      radial-gradient(circle at 50% 0%, rgba(255, 223, 97, 0.34), transparent 36%),
      conic-gradient(from -18deg at 50% 6%, rgba(255, 231, 122, 0.18), transparent 8%, rgba(255,255,255,0.18) 12%, transparent 18%, rgba(255, 206, 80, 0.16) 24%, transparent 34%),
      linear-gradient(160deg, rgba(42, 37, 25, 0.98), rgba(30, 44, 49, 0.96));
    box-shadow:
      0 0 0 2px rgba(255, 220, 91, 0.22),
      0 30px 90px rgba(2, 12, 16, 0.58),
      0 0 46px rgba(255, 204, 73, 0.24);
  }

  #winDialog.is-record .win-stat {
    border-color: rgba(247, 205, 86, 0.24);
    background: linear-gradient(180deg, rgba(68, 61, 35, 0.88), rgba(34, 61, 60, 0.74));
  }
}

@media (max-width: 860px) {
  .app { gap: 7px; padding-left: 8px; padding-right: 8px; }
  .topbar { grid-template-columns: 1fr; }
  .brand { grid-template-columns: 1fr; justify-items: center; }
  .hold-slots { width: min(132px, 100%); }
  .stats { grid-template-columns: repeat(5, 1fr); min-width: 0; }
  .stats div { padding: 6px; }
  .stats strong { font-size: 14px; }
  .combo-gauge { width: min(620px, 100%); justify-self: center; }
  .controls { grid-template-columns: 44px repeat(3, 1fr) 44px 44px; gap: 6px; }
  button { min-height: 42px; font-size: 14px; }
  .combo-pop { font-size: 28px; }
  .nick-panel { width: min(440px, 100%); }
  .rank-panel { width: min(520px, 100%); }
  #winDialog .modal-panel { width: min(500px, 100%); }
  .win-time { font-size: clamp(66px, 18vw, 106px); }
}

/* 폰 세로화면에서는 제목·슬롯·스탯이 세로의 절반을 먹어서 정작 보드가 좁아진다.
   상단을 눌러 담아 보드에 높이를 몰아주면, 판 구조를 안 바꾸고도 타일이 그만큼 커진다. */
/* 폰 세로화면에서는 상단이 화면을 크게 잡아먹어서 정작 마작판이 좁아진다.
   "마작패가 작아서 불편하다"는 피드백에 따라 제목을 아예 숨기고 게이지를 얇은 띠로 눌러서,
   확보한 세로 공간을 전부 보드에 넘긴다. (.app이 grid 1fr이라 상단이 줄면 보드가 자동으로 커짐) */
@media (max-width: 620px) {
  .app { gap: 3px; padding-left: 6px; padding-right: 6px; }

  /* 제목은 장식이라 폰에서는 숨긴다(탭 제목에 이미 있음). 스크린리더는 계속 읽는다. */
  h1 { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .brand { gap: 0; }
  .topbar { gap: 4px; }

  .hold-slots { width: min(116px, 100%); gap: 3px; padding: 3px; }
  .hold-slot { min-height: 24px; border-radius: 5px; }
  .slot-tile { border-radius: 5px; font-size: clamp(12px, 3.8vw, 16px); }

  /* 게이지: 76px짜리 패널 → 26px짜리 얇은 띠. 막대 자체가 배경이 되고 글자는 그 위에 얹는다. */
  .combo-gauge {
    min-height: 26px;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 6px;
    padding: 0 9px;
    border-radius: 999px;
  }
  .combo-gauge::before,
  .combo-gauge-fill {
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    height: auto;
    border-radius: 999px;
  }
  .combo-gauge-fill { max-width: 100%; opacity: .55; }
  .combo-gauge-label { font-size: 14px; line-height: 26px; }
  .combo-gauge-score { font-size: 11px; align-self: center; padding-top: 0; }

  .controls { gap: 4px; grid-template-columns: 38px repeat(3, 1fr) 38px 38px; }
  button { min-height: 34px; font-size: 13px; }
  #nickDialog.modal,
  #rankDialog.modal { padding: 12px; }
  .nick-panel { padding: 28px 14px 16px; }
  .nick-title { font-size: clamp(44px, 15vw, 62px); }
  .nick-sub { font-size: 17px; }
  #nickInput { min-height: 52px; font-size: 20px; }
  .nick-save { min-height: 54px; font-size: 17px; }
  .rank-panel {
    max-height: min(86dvh, 720px);
    padding: 20px 10px 12px;
  }
  .rank-sub { margin-bottom: 10px; }
  .rank-list { max-height: min(62dvh, 520px); gap: 6px; }
  .rank-row {
    grid-template-columns: 30px minmax(0, 1fr) 66px 34px;
    gap: 5px;
    min-height: 46px;
    padding: 7px 6px;
  }
  .rank-no { font-size: 12px; }
  .rank-nick { font-size: 14px; }
  .rank-time { font-size: 18px; text-align: right; }
  .rank-combo { font-size: 12px; }
  .rank-row.top1 .rank-time,
  .rank-row.top2 .rank-time,
  .rank-row.top3 .rank-time {
    font-size: 20px;
  }
  .rank-actions { margin-top: 10px; }
  .rank-actions button {
    min-width: 88px;
    min-height: 40px;
  }
  #winDialog.modal { padding: 12px; }
  #winDialog .modal-panel { padding: 24px 14px 16px; }
  .win-hero { margin-bottom: 12px; }
  .win-time { font-size: clamp(58px, 24vw, 88px); }
  .win-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; }
  .win-stat { padding: 10px 7px 9px; }
  .win-stat-value { font-size: 20px; }
  .win-actions { grid-template-columns: 1fr; }
  .win-actions button:first-child,
  .win-actions .primary,
  .win-actions [data-action="restart"] {
    min-height: 52px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fx-shake,
  .tile.idle-shimmer,
  .tile.idle-shimmer::before,
  .slot.is-danger,
  .hold-slot.is-danger,
  .combo-gauge.fever,
  .combo-gauge.fever::after,
  body.fever,
  body.fever::before,
  .fever-burst,
  .fever-particle,
  .nick-panel,
  .nick-title,
  .nick-sub,
  #nickInput,
  .nick-error,
  .nick-save,
  .rank-panel,
  #winDialog .modal-panel::before,
  #winDialog .win-badge,
  #winDialog .win-time,
  #winDialog .win-time-sub,
  #winDialog .win-stat,
  #winDialog .win-record-line,
  #winDialog .win-actions,
  #winDialog.is-record .win-badge.is-record {
    animation: none !important;
  }

  #winDialog .win-badge,
  #winDialog .win-time,
  #winDialog .win-time-sub,
  #winDialog .win-stat,
  #winDialog .win-record-line,
  #winDialog .win-actions {
    opacity: 1;
    transform: none;
  }

  .nick-panel,
  .rank-panel,
  .nick-title,
  .nick-sub,
  #nickInput,
  .nick-error,
  .nick-save {
    opacity: 1;
    transform: none;
  }

  .combo-gauge.fever {
    transform: none;
    border-color: rgba(255, 103, 95, 0.58);
    box-shadow:
      0 0 0 2px rgba(255, 228, 92, 0.18),
      0 0 18px rgba(255, 88, 91, 0.24),
      inset 0 1px 0 rgba(255,255,255,0.92);
  }

  body.fever::before,
  .fever-burst {
    display: none;
    opacity: 0;
  }


  .fever-particle {
    display: none;
  }

  .tile .shard,
  .slot-tile .shard,
  .tile.removing .spark,
  .slot-tile .spark {
    display: none;
  }

  .tile,
  .slot-tile {
    transition-duration: 80ms;
  }

  .tile.flip-out,
  .tile.flip-in {
    animation-duration: 1ms !important;
  }
}

/* Hall of Fame podium */
.rank-podium {
  position: relative;
  display: grid;
  gap: 8px;
  margin: 0 0 14px;
  padding: 4px 0 0;
  list-style: none;
}

.podium-row {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-width: 0;
  min-height: 48px;
  padding: 10px 13px;
  overflow: hidden;
  white-space: nowrap;
  border: 1px solid rgba(255,255,255,0.44);
  border-radius: 14px;
  color: rgba(34, 28, 22, 0.95);
  background:
    linear-gradient(135deg, rgba(255,255,255,0.84), rgba(255,255,255,0.42)),
    linear-gradient(135deg, rgba(245, 236, 216, 0.92), rgba(214, 202, 186, 0.84));
  box-shadow:
    0 10px 24px rgba(42, 31, 21, 0.12),
    inset 0 1px 0 rgba(255,255,255,0.78);
}

.podium-row::before {
  content: "";
  position: absolute;
  inset: 1px;
  z-index: -1;
  border-radius: inherit;
  opacity: 0.5;
  background: linear-gradient(110deg, rgba(255,255,255,0.62), rgba(255,255,255,0));
  pointer-events: none;
}

.podium1 {
  min-height: 62px;
  padding: 13px 15px;
  border: 1px solid rgba(255, 216, 77, 0.92);
  color: rgba(48, 31, 4, 0.98);
  background:
    linear-gradient(135deg, rgba(255,255,255,0.7), rgba(255,255,255,0.12)),
    linear-gradient(135deg, #fff7b8 0%, #ffd955 38%, #f3a928 72%, #9b5c00 100%);
  box-shadow:
    0 16px 34px rgba(154, 99, 0, 0.23),
    0 3px 0 rgba(136, 80, 0, 0.18),
    inset 0 1px 0 rgba(255,255,255,0.82);
  transform: translateY(-2px);
}

.podium1::after {
  content: "";
  position: absolute;
  inset: -2px -55%;
  z-index: -1;
  opacity: 0.26;
  background: linear-gradient(
    90deg,
    rgba(255, 61, 111, 0) 0%,
    rgba(255, 61, 111, 0.9) 13%,
    rgba(255, 176, 56, 0.9) 27%,
    rgba(255, 238, 88, 0.8) 41%,
    rgba(89, 216, 128, 0.85) 55%,
    rgba(55, 185, 255, 0.9) 69%,
    rgba(130, 99, 255, 0.86) 83%,
    rgba(255, 61, 111, 0) 100%
  );
  transform: translateX(-28%);
  animation: podiumRainbowSweep 8s ease-in-out infinite;
  pointer-events: none;
}

.podium2 {
  border-color: rgba(211, 220, 230, 0.94);
  color: rgba(36, 43, 50, 0.96);
  background:
    linear-gradient(135deg, rgba(255,255,255,0.8), rgba(255,255,255,0.16)),
    linear-gradient(135deg, #f7fbff 0%, #dce5ee 42%, #aebac8 100%);
  box-shadow:
    0 10px 22px rgba(58, 69, 82, 0.14),
    inset 0 1px 0 rgba(255,255,255,0.82);
}

.podium3 {
  border-color: rgba(207, 136, 80, 0.84);
  color: rgba(56, 31, 13, 0.96);
  background:
    linear-gradient(135deg, rgba(255,255,255,0.66), rgba(255,255,255,0.12)),
    linear-gradient(135deg, #ffd8ad 0%, #c9823d 48%, #8d4f23 100%);
  box-shadow:
    0 10px 22px rgba(103, 59, 25, 0.16),
    inset 0 1px 0 rgba(255,255,255,0.72);
}

.podium-medal {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 34px;
  font-size: 1.42rem;
  line-height: 1;
  text-shadow: 0 2px 8px rgba(0,0,0,0.18);
}

.podium1 .podium-medal {
  width: 42px;
  font-size: 2.05rem;
  transform: translateY(-1px);
}

.podium-nick {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 900;
  letter-spacing: 0;
}

.podium1 .podium-nick {
  font-size: 1.08rem;
}

.podium-time {
  flex: 0 0 auto;
  justify-self: end;
  font-variant-numeric: tabular-nums;
  font-weight: 950;
  letter-spacing: 0;
  padding: 5px 9px;
  border-radius: 999px;
  color: rgba(24, 20, 16, 0.94);
  background: rgba(255,255,255,0.56);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.62);
}

.podium1 .podium-time {
  font-size: 1.04rem;
  color: rgba(62, 36, 0, 0.98);
  background: rgba(255,255,255,0.68);
}

.podium-row.is-me {
  outline: 2px solid rgba(55, 185, 255, 0.72);
  outline-offset: 2px;
  box-shadow:
    0 0 0 4px rgba(55, 185, 255, 0.14),
    0 14px 28px rgba(32, 115, 184, 0.2),
    inset 0 1px 0 rgba(255,255,255,0.78);
}

.podium-row.is-me .podium-nick::after {
  content: " ME";
  display: inline-block;
  margin-left: 7px;
  padding: 2px 6px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 950;
  vertical-align: 0.08em;
  color: #06334f;
  background: rgba(131, 224, 255, 0.8);
}

.rank-divider {
  height: 1px;
  margin: 14px 2px;
  border: 0;
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(123, 139, 158, 0.5), rgba(255,255,255,0));
}

@keyframes podiumRainbowSweep {
  0%, 100% {
    transform: translateX(-28%);
    opacity: 0.18;
  }

  50% {
    transform: translateX(28%);
    opacity: 0.3;
  }
}

@media (prefers-color-scheme: dark) {
  .podium-row {
    color: rgba(255, 250, 238, 0.96);
    border-color: rgba(255,255,255,0.2);
    background:
      linear-gradient(135deg, rgba(255,255,255,0.12), rgba(255,255,255,0.04)),
      linear-gradient(135deg, rgba(75, 68, 61, 0.96), rgba(43, 39, 36, 0.98));
    box-shadow:
      0 12px 28px rgba(0,0,0,0.34),
      inset 0 1px 0 rgba(255,255,255,0.16);
  }

  .podium1 {
    color: rgba(255, 249, 218, 0.99);
    border-color: rgba(255, 218, 83, 0.88);
    background:
      linear-gradient(135deg, rgba(255,255,255,0.16), rgba(255,255,255,0.03)),
      linear-gradient(135deg, #8c5a04 0%, #d7991d 42%, #704100 100%);
    box-shadow:
      0 18px 36px rgba(0,0,0,0.36),
      0 0 0 1px rgba(255, 230, 119, 0.22),
      inset 0 1px 0 rgba(255,255,255,0.22);
  }

  .podium2 {
    color: rgba(244, 250, 255, 0.97);
    border-color: rgba(207, 220, 233, 0.58);
    background:
      linear-gradient(135deg, rgba(255,255,255,0.14), rgba(255,255,255,0.03)),
      linear-gradient(135deg, #5e6976 0%, #2f3843 100%);
  }

  .podium3 {
    color: rgba(255, 235, 215, 0.97);
    border-color: rgba(220, 139, 75, 0.64);
    background:
      linear-gradient(135deg, rgba(255,255,255,0.13), rgba(255,255,255,0.03)),
      linear-gradient(135deg, #7b421f 0%, #3d2417 100%);
  }

  .podium-time {
    color: rgba(255,255,255,0.96);
    background: rgba(0,0,0,0.24);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.12);
  }

  .podium1 .podium-time {
    color: rgba(255, 246, 202, 0.99);
    background: rgba(0,0,0,0.22);
  }

  .podium-row.is-me .podium-nick::after {
    color: #dff7ff;
    background: rgba(19, 135, 188, 0.82);
  }

  .rank-divider {
    background: linear-gradient(90deg, rgba(255,255,255,0), rgba(199, 213, 230, 0.32), rgba(255,255,255,0));
  }
}

@media (max-width: 420px) {
  .rank-podium {
    gap: 7px;
  }

  .podium-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 7px;
    min-height: 44px;
    padding: 9px 10px;
    border-radius: 12px;
  }

  .podium1 {
    min-height: 56px;
    padding: 11px 11px;
  }

  .podium-medal {
    width: 28px;
    font-size: 1.22rem;
  }

  .podium1 .podium-medal {
    width: 34px;
    font-size: 1.72rem;
  }

  .podium-nick,
  .podium1 .podium-nick {
    font-size: 0.94rem;
  }

  .podium-time,
  .podium1 .podium-time {
    padding: 4px 7px;
    font-size: 0.88rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .podium1::after {
    animation: none !important;
    transform: translateX(0);
    opacity: 0.18;
  }
}

/* ── 복구 코드 ────────────────────────────────────────────────────────────
   닉네임 소유는 브라우저마다 따로 저장되는 토큰으로 증명한다. 그래서 같은 사람이라도
   다른 브라우저에서는 "이미 사용 중"으로 막혔다(실제로 겪은 문제). 기존 기기에서 이 코드를
   확인해 새 기기에 입력하면 같은 닉네임을 이어서 쓸 수 있다. */
.nick-recover {
  margin: 10px 0 4px;
  padding: 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  text-align: left;
}
.nick-recover-msg {
  margin: 0 0 8px;
  font-size: 13px;
  line-height: 1.5;
  opacity: 0.85;
}
#nickCodeInput {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(0, 0, 0, 0.22);
  color: inherit;
  font: 600 14px Pretendard, system-ui, sans-serif;
  text-align: center;
}
#nickCodeInput:focus { outline: 2px solid #ffd45e; outline-offset: 1px; }

/* 복구 코드 — 기기를 옮길 때만 필요한 정보라 순위표 안에 두지 않는다.
   순위 패널 하단에는 작은 글자 링크만 두고, 실제 코드는 별도 창에서 보여준다.
   (패널 안에서 펼치면 패널 높이가 변하면서 순위 목록을 밀어냈다) */
.rank-code-link {
  margin-right: auto;               /* 닫기 버튼과 반대쪽 끝으로 */
  min-width: 0;
  min-height: 46px;
  padding: 0 4px;
  font-size: 12px;
  font-weight: 500;
  opacity: 0.6;
  border: none;
  background: none;
  box-shadow: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.rank-code-link:hover, .rank-code-link:focus-visible { opacity: 0.95; }

.code-panel {
  width: min(400px, 100%);
  padding: 26px 22px 18px;
  display: grid;
  gap: 12px;
  text-align: center;
}
.code-title {
  margin: 0;
  color: inherit;                    /* 패널 색을 그대로 따라가게(기본 h2 색이 튀었다) */
  font: 800 20px Pretendard, system-ui, sans-serif;
}
.code-panel code {
  font: 800 clamp(34px, 11vw, 44px) ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.18em;
  padding: 14px 8px;
  border-radius: 12px;
  background: rgba(255, 212, 94, 0.14);
  border: 1px dashed rgba(255, 212, 94, 0.5);
  color: #ffd45e;
  user-select: all;
}
.code-hint {
  margin: 0;
  font-size: 12px;
  opacity: 0.65;
  line-height: 1.5;
}
.code-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 4px;
}
.code-actions button { min-height: 48px; font-size: 14px; font-weight: 700; }

/* 순위표에 콤보·점수 추가되면서 한 줄이 5칸이 됐다. 좁은 화면에서 닉네임만 줄어들고
   순위·기록은 안 눌리도록 폭을 고정한다. */
.rank-row {
  grid-template-columns: 2.2em minmax(0, 1fr) auto auto auto;
  gap: 8px;
}
.rank-score {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  opacity: 0.62;
  white-space: nowrap;
  min-width: 3.4em;
  text-align: right;
}
.podium-meta {
  grid-column: 2 / -1;
  font-size: 11px;
  opacity: 0.72;
  font-variant-numeric: tabular-nums;
  margin-top: -2px;
}

/* (복구 코드 스타일은 .rank-mycode 정의부에 통합했다 — 접이식으로 바꾸면서
    여기 있던 '크게 보여주기' 덮어쓰기가 순위표를 밀어내는 원인이 됐다) */

@media (max-width: 420px) {
  .rank-score { display: none; }   /* 아주 좁으면 점수는 접는다(기록·콤보가 우선) */
}

/* ── 순위 줄의 콤보·점수 알약 배지 ────────────────────────────────────────
   이름 아래 작은 글씨로 두니 안 보인다는 피드백. 이름 오른쪽에 기록과 같은 크기의
   알약 배지로 올리되, 색을 달리해서 기록(시간)과 구분되게 한다. */
.pill {
  display: inline-grid;
  place-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font: 800 15px Pretendard, system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  line-height: 1.25;
}
.pill-combo {
  color: #7c4dff;
  background: rgba(124, 77, 255, 0.14);
  border: 1px solid rgba(124, 77, 255, 0.3);
}
.pill-score {
  color: #0e9f6e;
  background: rgba(14, 159, 110, 0.14);
  border: 1px solid rgba(14, 159, 110, 0.3);
}
@media (prefers-color-scheme: dark) {
  .pill-combo { color: #b39dff; background: rgba(124, 77, 255, 0.22); border-color: rgba(160, 130, 255, 0.4); }
  .pill-score { color: #5fe0ad; background: rgba(14, 159, 110, 0.22); border-color: rgba(60, 210, 160, 0.4); }
}

/* 한 줄 배치: 순위 · 닉네임 · 콤보 · 점수 · 기록 */
.rank-row { grid-template-columns: 2.2em minmax(0, 1fr) auto auto auto; gap: 7px; align-items: center; }
.podium-row { grid-template-columns: auto minmax(0, 1fr) auto auto auto; gap: 7px; align-items: center; }
.podium-meta { display: none; }   /* 알약으로 대체됐다 */

@media (max-width: 430px) {
  .pill { padding: 2px 8px; font-size: 13px; }
  .rank-row, .podium-row { gap: 5px; }
  .pill-score { display: none; }   /* 아주 좁으면 점수는 접는다(기록·콤보 우선) */
}
