/* Shared modal shell. Geometry from Figma node 2775:2125 (Scratch n Win, 320 wide).
   All numbers are taken from the Figma design context; derivations are in comments. */

.sm-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  overflow: auto;
  padding: 16px 0;
  background: rgba(0, 0, 0, 0.6); /* not from Figma, data-todo="design" */
}

.sm-modal {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  width: 320px;
  margin: auto; /* centers in both axes, still scrollable when taller than the viewport */
  font-family: 'Inter', sans-serif;
  color: #fff;
}
.sm-modal:focus { outline: none; }

/* Header 2775:2132: width 320, aspect 368/127 -> height 320 * 127 / 368 = 110.4348. */
.sm-header {
  position: relative;
  flex-shrink: 0;
  width: 320px;
  /* Explicit height instead of aspect-ratio: 368/127 computed through aspect-ratio snapped to
     110.4219 or 110.4297 depending on the modal's sub-pixel offset. */
  height: 110.4348px;
  /* Visible + above the body: the header art (coin pile) reaches y 116.36 and must not be cut at
     the header's bottom edge (design lead, 2026-10-16). The background, gradient and pattern
     layers carry their own radius / clipping. */
  overflow: visible;
  z-index: 1;
}

/* 2775:2133 Background: top 40, height 87 (bottom 127 is clipped by the header at 110.43). */
.sm-header__bg,
.sm-header__gradient {
  position: absolute;
  left: 0;
  right: 0;
  top: 40px;
  height: 87px;
  /* Figma clips these at the header bottom (110.43); the header no longer clips (see
     .sm-header), so cut them here without squashing the gradient: 40 + 87 - 110.4348 = 16.5652. */
  clip-path: inset(0 0 16.5652px 0);
  border-radius: 24px 24px 0 0;
}
.sm-header__bg { background: #171a24; }

/* 2775:2134 Gradient: SVG data URI copied verbatim from the Figma design context. */
.sm-header__gradient {
  background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 320 87' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><rect x='0' y='0' height='100%' width='100%' fill='url(%23grad)' opacity='1'/><defs><radialGradient id='grad' gradientUnits='userSpaceOnUse' cx='0' cy='0' r='10' gradientTransform='matrix(4.3897e-15 13.904 -24.877 -9.0231e-15 160 -41.061)'><stop stop-color='rgba(11,27,82,1)' offset='0'/><stop stop-color='rgba(11,27,82,0)' offset='1'/></radialGradient></defs></svg>");
}

/* 2775:2135 SVG-Pattern: 320x75 at top 40, top radius 24, clip.
   Figma wraps it in `rotate(180deg)` + `scaleY(-1)`. rotate(180) = scale(-1,-1), so the net
   transform is scale(-1, 1): a HORIZONTAL mirror (a vertical one would move the 24px radii
   to the bottom edge). */
.sm-header__pattern {
  position: absolute;
  left: 0;
  top: 40px;
  width: 320px;
  height: 75px;
  overflow: hidden;
  border-radius: 24px 24px 0 0;
  transform: scaleX(-1);
}
/* 2775:2136: 363.892 x 108, centered horizontally, top 0. shared/assets/header-pattern.png is the
   Figma SVG rasterised at 3x (1092 x 324) by Chromium, its 0.35 opacity baked in; the SVG as an
   <img> rendered differently in iOS Safari (source: design-sources/shared/header-pattern.svg). */
.sm-header__pattern img {
  position: absolute;
  left: 50%;
  top: 0;
  width: 363.892px;
  height: 108px;
  max-width: none;
  transform: translateX(-50%);
}

/* 2775:2141 Vault box: 320 x 110.897, centered at header 50% + 8.28px
   -> top = 110.4348 / 2 + 8.28 - 110.897 / 2 = 8.0489.
   Inside, Figma exports the image as left 95.25%, width -89.66% (negative = mirrored), height
   97.55%, top 0.12%, all inside the same net horizontal mirror as the pattern. Two mirrors
   cancel, so the image renders unmirrored:
     width  = 0.8966 * 320     = 286.912  (286.912 / 108.180 = 2.652 = 2042 / 770, no distortion)
     height = 0.9755 * 110.897 = 108.180
     right edge in mirrored space = 0.9525 * 320 = 304.8 -> left after un-mirroring = 320 - 304.8 = 15.2
     top    = 0.0012 * 110.897 = 0.1331
   Rendered: x 15.2 .. 302.11, y 8.18 .. 116.36 in the header (overflows the header bottom by
   ~6px on purpose, see .sm-header).
   This matches the Figma screenshot (coins span ~x18..302, logo top ~y11 incl. the 21px canvas
   padding * 0.1405 scale). The brief's first guess (width 320) does not match the screenshot. */
.sm-header__art {
  position: absolute;
  left: 0;
  top: 8.0489px;
  width: 320px;
  height: 110.897px;
  pointer-events: none;
}
.sm-header__art img {
  position: absolute;
  left: 15.2px;
  top: 0.1331px;
  width: 286.912px;
  height: 108.18px;
  max-width: none;
}

/* headerArtFit 'contain' (game-agnostic): header art of any aspect ratio, fitted inside the
   header (y 2..110.43) and centred, never clipped or distorted. */
.sm-header__art--contain {
  top: 2px;
  bottom: 0;
  height: auto;
}
.sm-header__art--contain img {
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Text title in place of the header art (game without its own header art yet):
   placeholder, data-todo="design". Centred in the visible header background (y 40..110). */
.sm-header__title {
  position: absolute;
  left: 0;
  right: 0;
  top: 44px;
  margin: 0;
  font: 800 30px/56px 'Inter', sans-serif;
  letter-spacing: 0.04em;
  text-align: center;
  text-transform: uppercase;
  color: #f7d36b;
  text-shadow: 0 2px 0 #7a4a06, 0 0 12px rgba(247, 211, 107, 0.45);
}

/* Generic top-left header slot for game controls (e.g. mute), mirrors the close button. */
.sm-header__actions {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  gap: 8px;
}
.sm-header__action {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: #252730;
  cursor: pointer;
}

/* 2775:2255 plate 28x28 (#252730, r8) at top 0 right 0; 2775:2256 icon 18x18 at top 5 right 5.
   The plate is the button so the hit area is the full 28x28. */
.sm-close {
  position: absolute;
  top: 0;
  right: 0;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: #252730;
  cursor: pointer;
}
.sm-close img {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 18px;
  height: 18px;
}

/* Body 2775:2143: column, gap 8, padding 0 16 16, bottom radius 24. */
.sm-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 320px;
  padding: 0 16px 16px;
  border-radius: 0 0 24px 24px;
  position: relative; /* anchors the countdown */
  background: linear-gradient(to bottom, #171a24 0%, #11131c 62%, #0e1119 100%);
}

/* CTA 2775:2250: 288 x 44, #00A63E (green/600), 2px rgba(255,255,255,.2), r12, padding 8 16. */
.sm-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 288px;
  height: 44px;
  padding: 8px 16px;
  border: 2px solid rgba(255, 255, 255, 0.2);
  border-radius: 12px;
  background: #00a63e;
  color: #fff;
  font: 700 14px/20px 'Inter', sans-serif;
  text-align: center;
  white-space: nowrap;
}
.sm-cta[hidden] { display: none; }
/* Disabled state: no transparency (nothing behind it shows through), a darker solid green with
   muted text. Design lead, 2026-10-16; not in Figma yet: data-todo="design". */
.sm-cta:disabled {
  border-color: rgba(255, 255, 255, 0.1);
  background: #0d5a2c;
  color: rgba(255, 255, 255, 0.55);
  cursor: not-allowed;
}

/* Availability 2775:2258: Inter 400 12/20 #c4c4c4, centered. */
.sm-availability {
  margin: 0;
  font: 400 12px/20px 'Inter', sans-serif;
  color: #c4c4c4;
  text-align: center;
  white-space: nowrap;
}
/* The attempts count is not shown inside the modal (design lead 2026-10-16); with devtools on it
   is mirrored under the modal (.sm-devinfo, shared/ui/modal.js). Error and no-attempts texts on the
   same line stay visible. display: none, so the body's gap leaves no hole. */
.sm-availability[data-field="spin_count"] { display: none; }
/* Prototype-only attempts readout under the modal, outside the card. */
.sm-devinfo {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin: 8px 0 0;
  font: 400 11px/16px 'Inter', sans-serif;
  color: rgba(255, 255, 255, 0.55);
  text-align: center;
  pointer-events: none;
}
.sm-devinfo[hidden],
body[data-devtools="off"] .sm-devinfo { display: none; }
/* Countdown under the availability line: placeholder, data-todo="design". Absolutely placed
   in the body's 16px bottom padding so it never changes the modal height. */
.sm-countdown {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  font: 400 12px/16px 'Inter', sans-serif;
  color: #c4c4c4;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.sm-countdown[hidden] { display: none; }

.sm-message { margin: 0; width: 288px; font: 400 14px/20px 'Inter', sans-serif; color: #c4c4c4; text-align: center; }

/* Shared result sunburst (scratch, wheel, pick, field goal; shared/ui/sunburst.js withSunburst):
   calm white rays (4.5%, 10 deg on / 10 deg off) behind the prize art, radial fade from 30% of the
   radius to the edge, one turn per 60 s, 300 ms fade-in. Placeholder art, data-todo="design".
   Size: --sm-sunburst-size on the wrapper (default 260 px). z-index -1 keeps the rays under the
   title / message / CTA; each game's body or stage isolates so they still paint above the body
   background. Only transform / opacity animate. */
.sm-iconwrap { position: relative; display: flex; align-items: center; justify-content: center; }
.sm-iconwrap > :not(.sm-sunburst) { position: relative; z-index: 1; }
.sm-sunburst {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--sm-sunburst-size, 260px);
  height: var(--sm-sunburst-size, 260px);
  margin: calc(var(--sm-sunburst-size, 260px) / -2) 0 0 calc(var(--sm-sunburst-size, 260px) / -2);
  pointer-events: none;
  z-index: -1;
  background: repeating-conic-gradient(rgba(255, 255, 255, 0.045) 0deg 10deg, transparent 10deg 20deg);
  -webkit-mask-image: radial-gradient(circle closest-side, #000 30%, transparent 100%);
  mask-image: radial-gradient(circle closest-side, #000 30%, transparent 100%);
  animation: sm-sunburst-spin 60s linear infinite, sm-sunburst-in 300ms linear both;
}
@keyframes sm-sunburst-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes sm-sunburst-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .sm-sunburst { animation: none; }
}

/* Seamless header -> body (design lead 2026-10-19: a hard line and a cut-off dot pattern showed at
   the header bottom on phones). The dot pattern used to run 4.6 px past the header (40 + 75 >
   110.43) and ended in a hard edge over the body; the blue gradient was cut mid-tone at the header
   bottom. Both now stop at the header bottom and fade out over their last rows, and the body tucks
   1 px under the header so no sub-pixel seam shows at DPR 2/3. */
.sm-header__pattern {
  height: 70.4348px;
  -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
}
.sm-header__gradient {
  -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent 81%);
  mask-image: linear-gradient(to bottom, #000 40%, transparent 81%);
}
.sm-header + .sm-body { margin-top: -1px; padding-top: 1px; }
