/* ============================================================
   JellyCat Generator — Game Styles
   Pixel-precise match to Figma: fX1oN67McwdF9YUHtUEYxL
   Canvas size: 402 × 874 px
   All tokens via /design-system/tokens.css → tokens.css import.
   ============================================================ */

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

/* Register --game-scale as a typed number so calc() can divide vw by it */
@property --game-scale {
  syntax: '<number>';
  inherits: true;
  initial-value: 1;
}

html, body {
  height: 100vh;
  overflow: hidden;
  background: #faf6eb;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
}

#viewport {
  /* JS sets these to Math.round(402 * --game-scale) × Math.round(874 * --game-scale) */
  width: 402px;
  height: 874px;
  background: #faf6eb;
  overflow: hidden;
  flex-shrink: 0;
  position: relative;
}

#game-frame {
  position: absolute;
  top: 0;
  left: 0;
  width: 402px;
  height: 874px;
  overflow: hidden;
  background: #faf6eb;
  transform: scale(var(--game-scale, 1));
  transform-origin: top left;
}

/* ── Screens ── */
.screen {
  position: absolute;
  inset: 0;
}
.screen.hidden { display: none; }

/* ── 3D machine image ──
   Figma: width=577 height=1332 left=-87 top=-236 inside the 402×874 frame.
── */
.machine-bg {
  position: absolute;
  left: -87px;
  top: -236px;
  width: 577px;
  height: 1332px;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
}

/* Result screen machine stays at the zoomed position (Figma Step 5) */
#screen-result .machine-bg {
  left: -204px;
  top: -377px;
  width: 807px;
  height: auto;
}

/* ── Text above the machine ── */
.game-title {
  position: absolute;
  top: 55px;
  left: 0; right: 0;
  text-align: center;
  font-family: var(--font-heading);
  font-size: var(--text-2xl);              /* 32px */
  font-weight: var(--font-weight-bold);
  line-height: var(--leading-tight);
  color: var(--color-primary-900);         /* #3c273d */
  pointer-events: none;
}

.game-subtitle {
  position: absolute;
  top: 102px;
  left: 0; right: 0;
  text-align: center;
  font-family: var(--font-body);
  font-size: var(--text-lg);              /* 18px */
  font-weight: var(--font-weight-medium);
  line-height: var(--leading-tight);
  color: var(--color-primary-500);        /* #9a729c */
  pointer-events: none;
}

/* ── Reel windows ── */
.reel-window {
  position: absolute;
  overflow: hidden;
  background: #fdfaf4;
}

/* Clip each window to its Figma SVG shape — removes white rectangular corners */
#win-0, #result-win-0 {
  clip-path: path('M57 0H10.3228C7.62992 0 4.03937 3.09837 3.14173 3.98362C2.24409 4.86886 0 38.9508 0 55.3279C0 71.705 0 86.7541 2.69291 108H56.5512C56.5512 108 54.7559 40.7213 57 0Z');
}
#win-1, #result-win-1 {
  clip-path: path('M54.5163 0H0.755295C-1.95539 44.2623 -1.05184 96.4918 0.303522 108H55.4199C55.9127 102.689 56.7751 38.0656 54.5163 0Z');
}
#win-2, #result-win-2 {
  clip-path: path('M0 8C0 3.58 3.58 0 8 0L47 0C49.6929 0 52.1024 2.61476 53 3.5C53.8976 4.38525 57 38.9508 57 55.3279C57 71.705 57 86.7541 54.3071 108H8C3.58 108 0 104.42 0 100Z');
}

.reel-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  z-index: 1;
  /* Render at the zoomed target size (÷ 1.4) then scale down.
     When the machine zooms 1.4×, the scales cancel → text shows at
     its native rendered size instead of a scaled-up bitmap. */
  transform: scale(0.714);
}

/* GPU layer only during animation — prevents early rasterisation at
   the small size which would produce a blurry scaled-up bitmap. */
.reel-content.spinning,
.reel-content.landed {
  will-change: transform, opacity;
}

.reel-emoji {
  font-size: 45px; /* 32px ÷ 0.714 — natural size at zoom target */
  line-height: 1;
  display: block;
}

.reel-label {
  font-family: var(--font-heading);
  font-size: 17px; /* 12px ÷ 0.714 */
  font-weight: 600;
  color: var(--color-primary-900);
  text-align: center;
  line-height: 1;
}

.window-glass {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
  pointer-events: none;
  mix-blend-mode: multiply;
  z-index: 2;
}

/* ── "Draw" button — game layout only; visual styles from .btn.btn-primary.btn-lg ── */
.btn-draw {
  position: absolute;
  left: 81px;
  top: 772px;
  width: 240px;
  height: 42px;
}

/* ── Reel spin animation ── */
@keyframes drumSpin {
  0%   { transform: scale(0.714) translateY(0);     opacity: 1; }
  35%  { transform: scale(0.714) translateY(-120%); opacity: 0; }
  36%  { transform: scale(0.714) translateY(120%);  opacity: 0; }
  100% { transform: scale(0.714) translateY(0);     opacity: 1; }
}
.reel-content.spinning {
  animation: drumSpin 0.55s cubic-bezier(0.4, 0, 0.2, 1) both;
}

/* ── Landing bounce ── */
@keyframes landBounce {
  0%   { transform: scale(0.714) translateY(0); }
  30%  { transform: scale(0.771) translateY(-6px); }
  60%  { transform: scale(0.693) translateY(2px); }
  80%  { transform: scale(0.728) translateY(-2px); }
  100% { transform: scale(0.714) translateY(0); }
}
.reel-content.landed {
  animation: landBounce 0.35s ease both;
}

/* ── Result screen ── */
.result-frost {
  position: absolute;
  inset: 0;
  background: rgba(255, 161, 161, 0);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  z-index: 10;
  animation: frostIn var(--transition-slow) ease both;
}

/* Gradient layer — fades from mauve to white across lower half of screen */
.result-frost-2 {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent 0%, rgba(221, 143, 177, 0.4) 61%, rgba(255, 255, 255, 0.7) 83%);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  z-index: 11;
  animation: frostIn var(--transition-slow) ease both;
}

/* Body stays cream — the in-frame frost/backdrop elements (clipped to container height)
   handle all coloring, so no overflow above or below the game frame. */
body.result-active,
body.nomatch-active {
  background: #faf6eb;
}

@keyframes frostIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes cardSlideIn {
  0%   { opacity: 0; transform: translateY(-40px) scale(0.95); }
  55%  { opacity: 1; transform: translateY(14px) scale(1.03); }
  72%  { transform: translateY(-8px) scale(0.98); }
  86%  { transform: translateY(5px) scale(1.01); }
  94%  { transform: translateY(-3px); }
  100% { transform: translateY(0) scale(1); }
}

/* ── Card visual wrap — amber V2 card with doll and deco elements ── */
.result-card-wrap {
  position: absolute;
  left: 42px;
  top: 135px;
  z-index: 12;
  animation: cardSlideIn 0.7s 0.05s ease both;
}

/* Action buttons — absolutely positioned near bottom of frame */
.result-btn-buy {
  position: absolute;
  left: 76px;
  top: 688px;
  width: 240px;
  justify-content: center;
  z-index: 13;
  box-shadow: 0px 4px 15px rgba(94, 58, 95, 0.5);
}
.result-btn-play-again {
  position: absolute;
  left: 76px;
  top: 754px;
  width: 240px;
  justify-content: center;
  z-index: 13;
}

/* ── Machine group — wraps machine-bg + reel windows so they scale together ──
   Pivot at 51.1% 13.3% maps to viewport (205.5, 116.5), which is the exact
   center derived from Figma Step 2: machine moves -87→-204, -236→-377 at 1.4×. ── */
#machine-group {
  position: absolute;
  inset: 0;
  transform-origin: 51.1% 13.3%;
  transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

#machine-group.zoomed {
  transform: scale(1.4);
}

/* ── No-match overlay ── */
.no-match-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;
}
.no-match-overlay.hidden { display: none; }

.no-match-backdrop {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(54, 54, 54, 0.9);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  animation: frostIn var(--transition-slow) ease both;
}

.no-match-ticket-wrap {
  position: absolute;
  left: 50%;
  top: calc(50% - 35px);
  z-index: 2;
  transform: translate(-50%, -50%) rotate(11.51deg);
  width: 431px;
  height: 559px;
  animation: ticketPop 0.5s 0.15s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.no-match-ticket {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

@keyframes ticketPop {
  from { opacity: 0; transform: translate(-50%, -50%) rotate(11.51deg) scale(0.75); }
  to   { opacity: 1; transform: translate(-50%, -50%) rotate(11.51deg) scale(1); }
}

/* Play again button — Figma: left:76 top:754 w:240 */
.no-match-play-btn {
  position: absolute;
  left: 76px;
  top: 754px;
  width: 240px;
  height: 42px;
  z-index: 3;
}

/* During machine zoom: sides bleed into viewport, top/bottom clipped at frame edge */
body.machine-zoomed #viewport {
  overflow: visible;
}
body.machine-zoomed #game-frame {
  overflow: visible;
  clip-path: inset(0px -9999px); /* clips top/bottom, allows left/right overflow */
}

/* No-match overlay: extend dark blur to full viewport width, clip top/bottom */
body.nomatch-active #viewport {
  overflow: visible;
  background: transparent;
}
body.nomatch-active #game-frame {
  overflow: visible;
  clip-path: inset(0px -9999px);
  background: transparent;
}
body.nomatch-active .no-match-backdrop {
  left: calc(-1 * (100vw / var(--game-scale) - 402px) / 2);
  right: calc(-1 * (100vw / var(--game-scale) - 402px) / 2);
}

/* On result screen: clip vertically at frame edges, allow frost to bleed left/right.
   Transparent backgrounds let the body gradient show through uniformly under the blur. */
body.result-active #viewport {
  overflow: visible;
  background: transparent;
}
body.result-active #game-frame {
  overflow: visible;
  clip-path: inset(0px -9999px);
  background: transparent;
}

/* Extend frost layers to full viewport width.
   Inside a scaled frame, viewport px ÷ game-scale = frame coordinate px. */
body.result-active .result-frost,
body.result-active .result-frost-2 {
  left: calc(-1 * (100vw / var(--game-scale) - 402px) / 2);
  right: calc(-1 * (100vw / var(--game-scale) - 402px) / 2);
}
