/* Hallmark · genre: playful · macrostructure: single-screen game (bespoke) · theme: carnival/diner-sign · tone: playful · anchor hue: 25 · enrichment: Tier A CSS art · nav: none · footer: none */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: clip;
  overscroll-behavior: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

body {
  background:
    radial-gradient(var(--color-dot) 1.5px, transparent 1.5px) 0 0 / 14px 14px,
    var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-display);
  display: flex;
  flex-direction: column;
}

/* 屋台の日よけ */
.awning {
  --stripe: clamp(28px, 7vw, 56px);
  position: relative;
  z-index: 2;
  flex: none;
  height: clamp(44px, 9dvh, 88px);
  padding-top: env(safe-area-inset-top);
  background: repeating-linear-gradient(90deg,
    var(--color-accent) 0 var(--stripe),
    var(--color-paper) var(--stripe) calc(var(--stripe) * 2));
  filter: drop-shadow(0 4px 0 var(--color-ink));
}
.awning::after {
  content: "";
  position: absolute;
  inset: 100% 0 auto;
  height: calc(var(--stripe) / 2);
  background:
    radial-gradient(circle at 25% 0, var(--color-accent) calc(var(--stripe) / 2), transparent calc(var(--stripe) / 2 + 0.5px)),
    radial-gradient(circle at 75% 0, var(--color-paper) calc(var(--stripe) / 2), transparent calc(var(--stripe) / 2 + 0.5px));
  background-size: calc(var(--stripe) * 2) 100%;
}

.booth {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: calc(5dvh + env(safe-area-inset-bottom));
}
/* カウンター */
.booth::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: calc(10dvh + env(safe-area-inset-bottom));
  background:
    radial-gradient(var(--color-dot) 1.6px, transparent 1.6px) 0 0 / 9px 9px,
    var(--color-paper-3);
  border-top: 4px solid var(--color-ink);
}

/* ===== マシン (日本型のカプセル自販機をプラ素材でシンプルに) ===== */
.machine {
  --line: 0.8cqw;
  position: relative;
  z-index: 1;
  width: min(92vw, 46dvh, 480px);
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* 本体の背板 (天板の下から台の上まで) */
.machine::before {
  content: "";
  position: absolute;
  top: 8cqw;
  bottom: 10cqw;
  left: 5cqw;
  right: 5cqw;
  background: var(--color-shell);
  border: var(--line) solid var(--color-ink);
  border-radius: 2cqw 2cqw 4cqw 4cqw;
  box-shadow: 2cqw 2cqw 0 var(--color-ink), inset -3.5cqw 0 0 var(--color-shell-shade);
}

.top {
  position: relative;
  z-index: 2;
  width: 96cqw;
  height: 12cqw;
  background: var(--color-shell);
  border: var(--line) solid var(--color-ink);
  border-radius: 5cqw 5cqw 2.4cqw 2.4cqw;
  box-shadow: 2cqw 2cqw 0 var(--color-ink), inset 0 -2.2cqw 0 var(--color-shell-shade);
}

/* 透明窓: 左右がふくらんだアクリルの筒 */
.window {
  position: relative;
  z-index: 1;
  width: 100cqw;
  height: 70cqw;
  margin-top: -1.6cqw;
  overflow: hidden;
  background: var(--color-glass);
  border: var(--line) solid var(--color-ink);
  border-radius: 16cqw / 50%;
  box-shadow: inset 5cqw 0 0 var(--color-glass-shade), inset -5cqw 0 0 var(--color-glass-shade);
}
.pile { position: absolute; inset: 0; }
.sheen, .sheen::after {
  position: absolute;
  top: 12%;
  bottom: 12%;
  border-radius: 999px;
  background: var(--color-shell);
  opacity: 0.85;
  pointer-events: none;
}
.sheen { left: 9%; width: 3%; z-index: 2; }

/* 台紙: 窓の上部に差し込まれたラインナップ */
.card {
  position: absolute;
  z-index: 1;
  top: 7%;
  left: 15%;
  right: 15%;
  height: 30%;
  display: grid;
  place-items: center;
  background:
    radial-gradient(var(--color-dot) 0.45cqw, transparent 0.45cqw) 0 0 / 2cqw 2cqw,
    var(--color-accent);
  border: var(--line) solid var(--color-ink);
  border-radius: 3cqw;
  box-shadow: 1cqw 1cqw 0 var(--color-ink);
}
.lineup {
  display: flex;
  gap: 1.6cqw;
  margin: 0;
  padding: 1.6cqw 2.2cqw 1.4cqw;
  list-style: none;
  background: var(--color-shell);
  border: var(--line) solid var(--color-ink);
  border-radius: 2cqw;
}
.lineup li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9cqw;
  font: 900 3.4cqw/1 var(--font-display);
  color: var(--color-ink);
}
.lineup i {
  width: 6cqw;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 0.5cqw solid var(--color-ink);
  background: linear-gradient(var(--r) 0 50%, var(--color-shell) 50%);
}
.lineup [data-r="c"] { --r: var(--r-c); }
.lineup [data-r="b"] { --r: var(--r-b); }
.lineup [data-r="a"] { --r: var(--r-a); }
.lineup [data-r="s"] { --r: var(--r-s); }
.lineup [data-r="ss"] { --r: var(--r-ss); }
.lineup [data-r="sss"] { --r: var(--cap-4); }
.lineup [data-r="sss"] i { background: linear-gradient(90deg, var(--cap-5) 0 33%, var(--r-s) 33% 66%, var(--cap-4) 66%) 0 0 / 100% 50% no-repeat, var(--color-shell); }
.lineup [data-r="secret"] { --r: var(--r-secret); }
.lineup :is([data-r="s"], [data-r="ss"], [data-r="sss"], [data-r="secret"]) i { box-shadow: 0 0 1.4cqw 0.2cqw var(--r); }
.sheen::after { content: ""; left: 160%; width: 50%; top: 6%; bottom: 30%; opacity: 1; }

/* 操作パネル: 背板から一段せり出したブロック */
.body {
  position: relative;
  z-index: 1;
  width: 94cqw;
  height: 66cqw;
  margin-top: -1cqw;
  background: var(--color-shell);
  border: var(--line) solid var(--color-ink);
  border-radius: 3cqw 3cqw 4cqw 4cqw;
  box-shadow: 1.6cqw 1.6cqw 0 var(--color-ink), inset 0 2cqw 0 var(--color-shell), inset -3cqw 0 0 var(--color-shell-shade);
}
/* 集金扉 */
.door {
  position: absolute;
  right: 8cqw;
  bottom: 5cqw;
  width: 34cqw;
  height: 10cqw;
  border: var(--line) solid var(--color-ink);
  border-radius: 2cqw;
  background: var(--color-shell-recess);
}
.door::after {
  content: "";
  position: absolute;
  right: 3cqw;
  top: 50%;
  width: 3cqw;
  aspect-ratio: 1;
  margin-top: -1.5cqw;
  border-radius: 50%;
  background: var(--color-shell-shade);
  border: 0.5cqw solid var(--color-ink);
}

/* ハンドル: くぼんだ台座 + ランプ 8 個 + 回るプラのつまみ */
.handle {
  position: absolute;
  top: 6cqw;
  right: 6cqw;
  width: 42cqw;
  aspect-ratio: 1;
  margin: 0;
  padding: 0;
  border: var(--line) solid var(--color-ink);
  border-radius: 9cqw;
  background: var(--color-shell-recess);
  box-shadow: inset 1.4cqw 1.4cqw 0 var(--color-shell-shade);
  cursor: grab;
  touch-action: none;
}
.handle:active { cursor: grabbing; }
.handle:focus-visible { outline: 4px solid var(--color-focus); outline-offset: 4px; }
.lamps i {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 2.8cqw;
  aspect-ratio: 1;
  margin: -1.4cqw;
  border-radius: 50%;
  background: var(--color-lamp-off);
  transform: rotate(calc(var(--i) * 45deg - 45deg)) translate(17.4cqw);
}
.lamps i.on {
  background: var(--color-accent);
  box-shadow: 0 0 1.8cqw 0.4cqw var(--color-accent);
}
.dial {
  position: absolute;
  inset: 15%;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--color-accent);
  border: var(--line) solid var(--color-ink);
  box-shadow: 1.2cqw 1.2cqw 0 var(--color-ink), inset -1.6cqw -1.6cqw 0 var(--color-accent-lo);
  transform: rotate(var(--rot, 0deg));
}
.handle.ease .dial { transition: transform var(--dur-short) var(--ease-out); }
.grip {
  position: relative;
  width: 26%;
  height: 90%;
  background: var(--color-accent-hi);
  border: var(--line) solid var(--color-ink);
  border-radius: 3cqw;
  box-shadow: 0.8cqw 0.8cqw 0 var(--color-accent-lo);
}
.grip::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 8%;
  width: 2.6cqw;
  aspect-ratio: 1;
  margin-left: -1.3cqw;
  border-radius: 50%;
  background: var(--color-shell);
}

.turn-hint {
  position: absolute;
  top: -4.4cqw;
  left: 38.6cqw;
  width: 56.8cqw;
  transform-origin: 50% 55.3%;
  pointer-events: none;
  overflow: visible;
  color: var(--color-ink);
  transition: opacity var(--dur-short) var(--ease-out);
  animation: nudge 1.6s var(--ease-in-out) infinite alternate;
}
.machine.turning .turn-hint { opacity: 0; animation: none; }
@keyframes nudge { from { transform: rotate(-12deg); } to { transform: rotate(14deg); } }

.outlet {
  position: absolute;
  top: 12cqw;
  left: 7cqw;
  width: 32cqw;
  height: 30cqw;
  overflow: hidden;
  background: var(--color-hole);
  border: var(--line) solid var(--color-ink);
  border-radius: 6cqw 6cqw 3cqw 3cqw;
  box-shadow: inset 0 3cqw 0 var(--color-ink), 0 0 0 1.6cqw var(--color-shell-recess), 0 0 0 2.4cqw var(--color-ink);
  perspective: 40cqw;
}
.outlet .capsule {
  left: 50%;
  bottom: 1.5cqw;
  width: 15cqw;
  margin-left: -7.5cqw;
}
/* 取り出し口のフタ */
.flap {
  position: absolute;
  inset: 0 0 34%;
  z-index: 1;
  background: var(--color-flap);
  border-bottom: var(--line) solid var(--color-ink);
  transform-origin: 50% 0;
}

/* 裾の広がった台 */
.base {
  position: relative;
  z-index: 0;
  width: 84cqw;
  height: 16cqw;
  margin-top: -1cqw;
  background: var(--color-shell);
  border: var(--line) solid var(--color-ink);
  border-radius: 1.5cqw 1.5cqw 3cqw 3cqw;
  box-shadow: inset 0 3cqw 0 var(--color-shell-shade), inset -3cqw 0 0 var(--color-shell-shade);
  transform: perspective(50cqw) rotateX(24deg);
  transform-origin: 50% 0;
}

/* 小さいカプセル */
.capsule, .big {
  --clear: color-mix(in oklch, var(--cap) 24%, var(--color-shell));
}
.capsule {
  position: absolute;
  aspect-ratio: 1;
  border-radius: 50%;
  border: max(1.5px, 0.6cqw) solid var(--color-ink);
  background: linear-gradient(var(--cap) 0 50%, var(--clear) 50% 100%);
  box-shadow: inset -1.2cqw -1.2cqw 0 var(--color-dot);
}
.pile .capsule { left: 0; top: 0; width: 17%; will-change: transform; }

/* ===== 開封ステージ ===== */
.stage {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  touch-action: none;
  cursor: pointer;
}
.stage[hidden] { display: none; }
.stage-bg {
  position: absolute;
  inset: 0;
  background: var(--color-scrim);
  animation: fade-in var(--dur-long) var(--ease-out) both;
}
.stage[data-void] .stage-bg { background: var(--color-void); }
@keyframes fade-in { from { opacity: 0; } }

.shaker, .cap-wrap {
  display: grid;
  place-items: center;
}
.shaker > *, .cap-wrap > * { grid-area: 1 / 1; }
.shaker { position: relative; width: 100%; height: 100%; }

.cap-wrap {
  position: relative;
  width: var(--S);
  aspect-ratio: 1;
}

.stage { --S: min(62vw, 44dvh, 440px); --light: var(--r-c); --open: 0; --glow: 0; }
.stage[data-light="b"] { --light: var(--r-b); }
.stage[data-light="a"] { --light: var(--r-a); }
.stage[data-light="s"] { --light: var(--r-s); }
.stage[data-light="ss"] { --light: var(--r-ss); }
.stage[data-light="sss"] { --light: var(--r-sss); }
.stage[data-light="secret"] { --light: var(--r-secret); }

.glow, .beams {
  position: absolute;
  pointer-events: none;
  opacity: var(--glow);
  transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out);
}
.glow {
  inset: -25% -80%;
  background: radial-gradient(closest-side, var(--light), transparent);
  transform: scale(calc(0.5 + var(--glow) * 0.7), calc(0.3 + var(--glow) * 0.7));
}
.beams {
  inset: -110%;
  background: repeating-conic-gradient(var(--light) 0 4deg, transparent 4deg 15deg);
  mask: radial-gradient(closest-side, black 25%, transparent);
  -webkit-mask: radial-gradient(closest-side, black 25%, transparent);
  transform: scaleY(calc(0.15 + var(--glow) * 0.5));
}
.stage[data-light="sss"] :is(.glow, .beams, .slit) { animation: rainbow 0.9s linear infinite; }
@keyframes rainbow { to { filter: hue-rotate(360deg); } }

.big {
  position: relative;
  width: 100%;
  height: 100%;
}
.half {
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  border: calc(var(--S) * 0.028) solid var(--color-ink);
  transition: transform var(--dur-micro) var(--ease-out);
}
.half.top {
  top: 0;
  border-bottom-width: calc(var(--S) * 0.02);
  border-radius: 999px 999px 0 0 / 999px 999px 0 0;
  background: var(--cap);
  transform: translateY(calc(var(--open) * var(--S) * -0.09));
}
.half.top::before {
  content: "";
  position: absolute;
  left: 16%;
  top: 22%;
  width: 26%;
  height: 22%;
  border-radius: 50%;
  background: var(--color-shell);
  opacity: 0.75;
  rotate: -35deg;
}
.half.bottom {
  bottom: 0;
  border-top-width: calc(var(--S) * 0.02);
  border-radius: 0 0 999px 999px / 0 0 999px 999px;
  background:
    radial-gradient(var(--color-dot) calc(var(--S) * 0.006), transparent calc(var(--S) * 0.006)) 0 0 / calc(var(--S) * 0.04) calc(var(--S) * 0.04),
    var(--clear);
  transform: translateY(calc(var(--open) * var(--S) * 0.09));
}
.slit {
  position: absolute;
  left: 5%;
  right: 5%;
  top: 40%;
  height: 20%;
  background: linear-gradient(transparent, var(--light) 22%, var(--r-core) 42% 58%, var(--light) 78%, transparent);
  transform: scaleY(var(--open));
  transition: transform var(--dur-micro) var(--ease-out);
}

.mash {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + var(--S) * 0.7);
  margin: 0;
  text-align: center;
  font-family: var(--font-jp);
  font-size: min(12vw, 7dvh, 72px);
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--cap-3);
  -webkit-text-stroke: 0.06em var(--color-ink);
  paint-order: stroke fill;
  text-shadow: 0.07em 0.07em 0 var(--color-ink);
  white-space: nowrap;
  pointer-events: none;
  rotate: -3deg;
}
.mash[hidden] { display: none; }

/* ===== 結果 ===== */
.rays {
  position: absolute;
  width: 170vmax;
  aspect-ratio: 1;
  pointer-events: none;
  opacity: 0;
  background: repeating-conic-gradient(var(--rank) 0 7deg, transparent 7deg 20deg);
  mask: radial-gradient(closest-side, transparent 4%, black 14%, transparent);
  -webkit-mask: radial-gradient(closest-side, transparent 4%, black 14%, transparent);
  transition: opacity var(--dur-long) var(--ease-out);
  animation: spin 14s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.stage[data-rank] .rays { opacity: 0.3; }
.stage[data-rank="c"] .rays { opacity: 0; }
.stage[data-rank="s"] .rays, .stage[data-rank="ss"] .rays { opacity: 0.5; }
.stage[data-rank="sss"] .rays { opacity: 0.6; animation: spin 10s linear infinite, rainbow 1.2s linear infinite; }
.stage[data-rank="secret"] .rays { opacity: 0.45; --rank: var(--r-core); }

.stage[data-rank="c"] { --rank: var(--r-c); }
.stage[data-rank="b"] { --rank: var(--r-b); }
.stage[data-rank="a"] { --rank: var(--r-a); }
.stage[data-rank="s"] { --rank: var(--r-s); }
.stage[data-rank="ss"] { --rank: var(--r-ss); }
.stage[data-rank="sss"] { --rank: var(--r-sss); }
.stage[data-rank="secret"] { --rank: var(--r-secret); }

.rank {
  position: relative;
  margin: 0;
  font-weight: 900;
  font-size: min(64vw, 50dvh);
  line-height: 0.82;
  letter-spacing: -0.005em;
  color: var(--rank);
  -webkit-text-stroke: 0.025em var(--color-ink);
  paint-order: stroke fill;
  text-shadow: 0.05em 0.05em 0 var(--color-ink), 0 0 0.1em var(--halo);
  white-space: nowrap;
  isolation: isolate;
}
/* 文字の後ろで脈打つ光 */
.rank::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  z-index: -1;
  color: var(--halo);
  -webkit-text-stroke: 0;
  text-shadow: none;
  filter: blur(0.06em);
  animation: halo 0.8s var(--ease-in-out) infinite alternate;
}
@keyframes halo { from { opacity: 0.5; transform: scale(1); } to { opacity: 1; transform: scale(1.07); } }
.stage { --halo: var(--rank); }
.stage[data-rank="c"] .rank { text-shadow: 0.05em 0.05em 0 var(--color-ink), 0 0 0.2em var(--halo); }
.stage[data-rank="c"] .rank::before { opacity: 0.3; animation: none; }
.stage[data-rank="sss"] { --halo: var(--r-core); }
.rank[hidden] { display: none; }
.stage[data-rank="ss"] .rank { font-size: min(52vw, 46dvh); }
.stage[data-rank="sss"] .rank { font-size: min(40vw, 42dvh); }
.rank span:nth-child(1) { color: var(--cap-5); }
.rank span:nth-child(2) { color: var(--r-s); }
.rank span:nth-child(3) { color: var(--cap-4); }
.stage[data-rank="secret"] .rank {
  font-family: var(--font-jp);
  font-weight: 400;
  font-size: min(14vw, 12dvh);
  line-height: 1.1;
  color: var(--r-core);
  -webkit-text-stroke: 0;
  text-shadow: 0.06em 0.06em 0 var(--r-secret), 0 0 0.2em var(--r-secret), 0 0 0.5em var(--r-secret);
  animation: glitch 2.4s steps(1) infinite;
}
@keyframes glitch {
  0%, 86%, 100% { transform: none; }
  88% { transform: translate(-3%, 1%) skewX(-12deg); }
  91% { transform: translate(4%, -2%); }
  94% { transform: translate(-1%, 0) skewX(8deg); }
}

.flash {
  position: fixed;
  inset: 0;
  z-index: 12;
  pointer-events: none;
  opacity: 0;
}
#fx {
  position: fixed;
  inset: 0;
  z-index: 11;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .turn-hint, .rays, .rank::before, .stage[data-rank="secret"] .rank { animation: none; }
  .half, .slit, .glow, .beams { transition-duration: 150ms; }
}
