{"id":84,"date":"2026-10-17T23:22:11","date_gmt":"2026-10-17T23:22:11","guid":{"rendered":"https:\/\/apk.produsenpagarbrc.com\/?p=84"},"modified":"2026-10-17T23:22:11","modified_gmt":"2026-10-17T23:22:11","slug":"moonloom-spider","status":"publish","type":"post","link":"https:\/\/play.produsenpagarbrc.com\/?p=84","title":{"rendered":"Moonloom Spider"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Moonloom Spider is a cozy Spider Solitaire game set inside a hidden workshop suspended above the night clouds. In this quiet celestial place, moon rabbits weave glowing card trails into complete lunar patterns while lanterns sway above wooden tables, mochi rests on small trays, and silver clouds drift beyond the workshop windows. Players must arrange cards into descending sequences from King to Ace, complete eight full stacks, and restore order to a magical loom that keeps the night sky stitched together.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The game combines the familiar structure of Spider Solitaire with the warm atmosphere of the Moon Rabbit Workshop. It offers three difficulty modes, responsive controls, smooth drag-and-drop interaction, touch-friendly gameplay, helpful hints, undo support, sound effects, and fullscreen mode. The rules are easy to understand, but completing all eight sequences requires patience, planning, and careful management of every empty column.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/play.produsenpagarbrc.com\/wp-content\/uploads\/2026\/10\/Moonloom-Spider-1024x768.png\" alt=\"\" class=\"wp-image-85\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">The Moonloom Workshop Above the Clouds<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Far above the sleeping world, beyond the highest cloud layer, stands a workshop built from moonwood, violet cloth, silver thread, and lantern glass. This is the Moonloom Workshop, a place where small rabbits work throughout the night to repair the patterns of the sky.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The stars may appear scattered and effortless from below, but the moon rabbits know that every constellation depends on a hidden structure. Silver threads connect one light to another, cloud paths must remain balanced, and the moon\u2019s glow must be carefully distributed across the night. When a thread breaks or a celestial pattern becomes tangled, the workshop\u2019s great loom begins to slow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At the beginning of Moonloom Spider, the workshop has received an enormous pile of unsorted lunar cards. The cards contain four traditional workshop symbols: the Moon Rabbit, the Mochi Cake, the Night Cloud, and the Wooden Mallet. Each suit represents a different part of the moon rabbits\u2019 craft, and every complete King-to-Ace sequence becomes a finished thread that can be placed into one of the eight Mooncraft Trays.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The task sounds simple, but the cards have been scattered across ten tableau columns. Some are visible, while others remain face down beneath tangled layers. The player must uncover the hidden cards, build temporary sequences, and guide each suit into a complete descending path.<\/p>\n\n\n\n<div id=\"moonloom-spider-game\" aria-label=\"Moonloom Spider, a Moon Rabbit Workshop Spider Solitaire game\">\n  <style>\nhtml.mls-page-lock,\nbody.mls-page-lock {\n  overflow: hidden !important;\n  overscroll-behavior: none;\n}\n\n#moonloom-spider-game,\n#moonloom-spider-game * {\n  box-sizing: border-box;\n  -webkit-tap-highlight-color: transparent;\n}\n\n#moonloom-spider-game {\n  --mls-card-w: 68px;\n  --mls-card-h: 94px;\n  --mls-stack-inset: 10px;\n  --mls-stack-top-inset: 6px;\n  --mls-night: #23142f;\n  --mls-plum: #39244d;\n  --mls-violet: #57406e;\n  --mls-lavender: #8b78b8;\n  --mls-cloud: #cfd1ff;\n  --mls-cream: #fff1c9;\n  --mls-paper: #fff8e7;\n  --mls-gold: #f4c542;\n  --mls-wood: #7b5236;\n  --mls-rose: #e58e96;\n  --mls-mochi: #d9a95b;\n  --mls-moss: #7e8c5b;\n  --mls-danger: #d96f6f;\n  --mls-ink: #2f203d;\n  --mls-muted: #6f6380;\n  --mls-border: rgba(244,197,66,.34);\n  --mls-panel: rgba(55,34,75,.90);\n  --mls-shadow: rgba(24,12,36,.34);\n  width: 100%;\n  max-width: 100%;\n  margin: 0 auto;\n  padding: 0;\n  display: block;\n  overflow: visible;\n  isolation: isolate;\n  color: var(--mls-cream);\n  font-family: system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;\n}\n\n#moonloom-spider-game button {\n  appearance: none;\n  -webkit-appearance: none;\n  margin: 0;\n  border: 0;\n  font: inherit;\n}\n\n#moonloom-spider-game button:focus-visible {\n  outline: 3px solid rgba(255,241,201,.90);\n  outline-offset: 3px;\n}\n\n#moonloom-spider-game .mls-shell {\n  position: relative;\n  width: 100%;\n  max-width: 1480px;\n  aspect-ratio: 16 \/ 9;\n  margin: 0 auto;\n  overflow: hidden;\n  isolation: isolate;\n  border: 1px solid rgba(244,197,66,.38);\n  border-radius: clamp(18px,2vw,28px);\n  background:\n    radial-gradient(circle at 78% 9%,rgba(255,241,201,.32),transparent 18%),\n    radial-gradient(circle at 18% 18%,rgba(207,209,255,.13),transparent 24%),\n    linear-gradient(155deg,#23142f 0%,#39244d 42%,#57406e 74%,#271631 100%);\n  box-shadow: 0 24px 64px var(--mls-shadow), inset 0 1px 0 rgba(255,241,201,.10);\n  transform-origin: center;\n}\n\n\/* Moon Rabbit Workshop environment *\/\n#moonloom-spider-game .mls-workshop-bg,\n#moonloom-spider-game .mls-workshop-bg > * {\n  position: absolute;\n  pointer-events: none;\n}\n\n#moonloom-spider-game .mls-workshop-bg {\n  inset: 0;\n  z-index: 0;\n  overflow: hidden;\n  background:\n    radial-gradient(circle at 82% 13%,rgba(255,241,201,.50) 0 4%,rgba(255,241,201,.16) 12%,transparent 22%),\n    radial-gradient(circle at 20% 22%,rgba(207,209,255,.13),transparent 24%),\n    linear-gradient(180deg,#23142f 0%,#39244d 52%,#4f365f 76%,#2b1b35 100%);\n}\n\n#moonloom-spider-game .mls-moon-window {\n  right: 4%;\n  top: 7%;\n  width: 18%;\n  height: 31%;\n  border: clamp(5px,.55vw,9px) solid #6b4d74;\n  border-radius: 50% 50% 22% 22% \/ 42% 42% 18% 18%;\n  background:\n    radial-gradient(circle at 72% 23%,#fff8e7 0 8%,#fff1c9 9% 23%,transparent 24%),\n    radial-gradient(ellipse at 20% 100%,#766691 0 30%,transparent 31%),\n    radial-gradient(ellipse at 68% 100%,#5a4772 0 38%,transparent 39%),\n    linear-gradient(180deg,#24183d 0%,#57406e 70%,#8b78b8 100%);\n  box-shadow: 0 0 0 3px rgba(255,241,201,.16),0 14px 28px rgba(24,12,36,.28),inset 0 0 30px rgba(255,241,201,.16);\n}\n\n#moonloom-spider-game .mls-moon-window::before,\n#moonloom-spider-game .mls-moon-window::after {\n  content: \"\";\n  position: absolute;\n  background: rgba(255,241,201,.14);\n}\n#moonloom-spider-game .mls-moon-window::before { left: 50%; top: 0; bottom: 0; width: 4px; transform: translateX(-50%); }\n#moonloom-spider-game .mls-moon-window::after { left: 0; right: 0; top: 51%; height: 4px; }\n\n#moonloom-spider-game .mls-cloud-bank {\n  left: -6%;\n  right: -6%;\n  top: 29%;\n  height: 28%;\n  opacity: .72;\n  background:\n    radial-gradient(ellipse at 7% 76%,rgba(207,209,255,.22) 0 17%,transparent 18%),\n    radial-gradient(ellipse at 22% 68%,rgba(255,241,201,.12) 0 16%,transparent 17%),\n    radial-gradient(ellipse at 46% 80%,rgba(139,120,184,.22) 0 21%,transparent 22%),\n    radial-gradient(ellipse at 72% 70%,rgba(207,209,255,.18) 0 18%,transparent 19%),\n    radial-gradient(ellipse at 93% 78%,rgba(255,241,201,.10) 0 16%,transparent 17%);\n  filter: blur(1px);\n}\n\n#moonloom-spider-game .mls-star-dust {\n  inset: 0;\n  opacity: .74;\n  background:\n    radial-gradient(circle at 8% 18%,#fff8e7 0 1px,transparent 2px),\n    radial-gradient(circle at 18% 34%,#cfd1ff 0 1.2px,transparent 2.2px),\n    radial-gradient(circle at 34% 13%,#fff1c9 0 1.2px,transparent 2.2px),\n    radial-gradient(circle at 51% 26%,#cfd1ff 0 1px,transparent 2px),\n    radial-gradient(circle at 66% 17%,#fff8e7 0 1.4px,transparent 2.4px),\n    radial-gradient(circle at 83% 37%,#cfd1ff 0 1.2px,transparent 2.2px),\n    radial-gradient(circle at 94% 18%,#fff1c9 0 1px,transparent 2px),\n    radial-gradient(circle at 72% 56%,rgba(255,241,201,.72) 0 1px,transparent 2px),\n    radial-gradient(circle at 24% 61%,rgba(207,209,255,.72) 0 1px,transparent 2px);\n}\n\n#moonloom-spider-game .mls-workbench {\n  left: -3%;\n  right: -3%;\n  top: 47%;\n  bottom: -7%;\n  background:\n    linear-gradient(180deg,rgba(255,241,201,.08),transparent 8%),\n    repeating-linear-gradient(90deg,rgba(37,20,47,.13) 0 2px,transparent 2px 86px),\n    linear-gradient(180deg,#8f6546 0%,#704a34 58%,#4b3026 100%);\n  box-shadow: inset 0 12px 22px rgba(35,20,47,.22);\n}\n\n#moonloom-spider-game .mls-tool-shelf {\n  bottom: 4%;\n  width: clamp(112px,12vw,188px);\n  height: clamp(66px,7vw,108px);\n  border: 2px solid rgba(47,32,61,.58);\n  border-radius: 18px 18px 28px 28px;\n  background:\n    radial-gradient(circle at 20% 42%,#d9a95b 0 9%,transparent 10%),\n    radial-gradient(circle at 45% 36%,#e58e96 0 9%,transparent 10%),\n    radial-gradient(circle at 70% 43%,#8b78b8 0 9%,transparent 10%),\n    repeating-linear-gradient(90deg,#7b5236 0 9px,#9b6d4e 9px 17px,#65422e 17px 25px);\n  box-shadow: 0 18px 28px rgba(24,12,36,.28),inset 0 0 0 3px rgba(255,241,201,.08);\n  opacity: .82;\n}\n#moonloom-spider-game .mls-tool-shelf.left { left: 2.4%; }\n#moonloom-spider-game .mls-tool-shelf.right { right: 2.4%; }\n#moonloom-spider-game .mls-tool-shelf::before {\n  content: \"\";\n  position: absolute;\n  left: 17%;\n  right: 17%;\n  top: -43%;\n  height: 62%;\n  border: clamp(7px,.75vw,12px) solid #7b5236;\n  border-bottom: 0;\n  border-radius: 999px 999px 0 0;\n}\n\n#moonloom-spider-game .mls-lantern {\n  top: 8%;\n  width: clamp(44px,4.4vw,70px);\n  height: clamp(76px,7vw,112px);\n}\n#moonloom-spider-game .mls-lantern.left { left: 28%; }\n#moonloom-spider-game .mls-lantern.right { right: 27%; top: 12%; }\n#moonloom-spider-game .mls-lantern::before {\n  content: \"\";\n  position: absolute;\n  left: 46%;\n  top: -8%;\n  width: 8%;\n  height: 30%;\n  background: #7b5236;\n}\n#moonloom-spider-game .mls-lantern::after {\n  content: \"\";\n  position: absolute;\n  left: 18%;\n  right: 18%;\n  bottom: 0;\n  height: 65%;\n  border: 3px solid #7b5236;\n  border-radius: 12px 12px 18px 18px;\n  background: radial-gradient(circle,#fff8e7 0 16%,#f4c542 36%,rgba(244,197,66,.22) 67%,transparent 68%);\n  box-shadow: 0 0 24px rgba(244,197,66,.34),inset 0 0 0 2px rgba(255,241,201,.18);\n}\n\n\/* HUD *\/\n#moonloom-spider-game .mls-topbar {\n  position: absolute;\n  z-index: 210;\n  top: clamp(10px,1.2vw,18px);\n  left: clamp(10px,1.2vw,18px);\n  right: clamp(10px,1.2vw,18px);\n  display: grid;\n  grid-template-columns: minmax(76px,.45fr) auto minmax(40px,.45fr);\n  align-items: center;\n  gap: clamp(6px,.75vw,11px);\n  pointer-events: none;\n}\n#moonloom-spider-game .mls-topbar > * { pointer-events: auto; }\n#moonloom-spider-game .mls-top-left,\n#moonloom-spider-game .mls-top-right,\n#moonloom-spider-game .mls-stat-row { display: flex; align-items: center; }\n#moonloom-spider-game .mls-top-left { justify-content: flex-start; gap: clamp(5px,.6vw,9px); }\n#moonloom-spider-game .mls-top-right { justify-content: flex-end; position: relative; z-index: 230; }\n#moonloom-spider-game .mls-stat-row { justify-content: center; gap: clamp(5px,.6vw,8px); min-width: 0; }\n\n#moonloom-spider-game .mls-stat-capsule,\n#moonloom-spider-game .mls-icon-button,\n#moonloom-spider-game .mls-workshop-button,\n#moonloom-spider-game .mls-popup-button,\n#moonloom-spider-game .mls-mode-pill {\n  border: 1px solid rgba(244,197,66,.38);\n  color: var(--mls-cream);\n  background: linear-gradient(180deg,rgba(91,63,120,.94),rgba(48,30,64,.94));\n  box-shadow: inset 0 1px 0 rgba(255,241,201,.12),0 8px 18px rgba(24,12,36,.24);\n}\n\n#moonloom-spider-game .mls-stat-capsule {\n  min-width: clamp(50px,6.8vw,92px);\n  height: clamp(30px,3.8vw,46px);\n  padding: clamp(3px,.4vw,6px) clamp(5px,.65vw,10px);\n  border-radius: 999px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  line-height: 1;\n  white-space: nowrap;\n  overflow: hidden;\n}\n#moonloom-spider-game .mls-stat-capsule.mls-stat-wide { min-width: clamp(66px,8.8vw,118px); }\n#moonloom-spider-game .mls-stat-label { margin-bottom: 3px; color: rgba(255,241,201,.63); font-size: clamp(6px,.72vw,10px); font-weight: 850; letter-spacing: .11em; text-transform: uppercase; }\n#moonloom-spider-game .mls-stat-value { color: #fff8e7; font-size: clamp(11px,1.45vw,19px); font-weight: 900; }\n\n#moonloom-spider-game .mls-icon-button,\n#moonloom-spider-game .mls-workshop-button,\n#moonloom-spider-game .mls-popup-button,\n#moonloom-spider-game .mls-mode-pill,\n#moonloom-spider-game .mls-stock-pile { cursor: pointer; touch-action: manipulation; user-select: none; }\n\n#moonloom-spider-game .mls-icon-button {\n  width: clamp(31px,3.3vw,45px);\n  height: clamp(31px,3.3vw,45px);\n  border-radius: clamp(10px,1vw,15px);\n  display: grid;\n  place-items: center;\n  transition: transform .14s ease,border-color .14s ease,box-shadow .14s ease,background .14s ease;\n}\n#moonloom-spider-game .mls-icon-button:hover,\n#moonloom-spider-game .mls-icon-button:focus-visible,\n#moonloom-spider-game .mls-workshop-button:hover,\n#moonloom-spider-game .mls-workshop-button:focus-visible,\n#moonloom-spider-game .mls-popup-button:hover,\n#moonloom-spider-game .mls-popup-button:focus-visible,\n#moonloom-spider-game .mls-mode-pill:hover,\n#moonloom-spider-game .mls-mode-pill:focus-visible {\n  transform: translateY(-2px);\n  border-color: rgba(255,241,201,.75);\n  background: linear-gradient(180deg,#8b78b8,#5a3f78);\n  box-shadow: 0 0 0 3px rgba(244,197,66,.10),0 12px 24px rgba(24,12,36,.28);\n}\n#moonloom-spider-game .mls-icon-button:active,\n#moonloom-spider-game .mls-workshop-button:active,\n#moonloom-spider-game .mls-popup-button:active,\n#moonloom-spider-game .mls-mode-pill:active,\n#moonloom-spider-game .mls-stock-pile:active { transform: translateY(1px) scale(.985); }\n\n#moonloom-spider-game .mls-pause-icon { width: 18px; height: 18px; display: flex; justify-content: center; gap: 5px; }\n#moonloom-spider-game .mls-pause-icon span { width: 5px; height: 18px; border-radius: 4px; background: var(--mls-cream); }\n#moonloom-spider-game .mls-sound-icon { position: relative; width: 28px; height: 23px; display: block; transform: translateX(-1px) scale(.88); }\n#moonloom-spider-game .mls-speaker-box { position: absolute; left: 0; top: 8px; width: 7px; height: 8px; border-radius: 3px 0 0 3px; background: var(--mls-cream); }\n#moonloom-spider-game .mls-speaker-cone { position: absolute; left: 6px; top: 4px; width: 12px; height: 16px; background: var(--mls-cream); clip-path: polygon(0 34%,100% 0,100% 100%,0 66%); }\n#moonloom-spider-game .mls-sound-wave { position: absolute; top: 50%; border: 2px solid var(--mls-cream); border-left: 0; border-top-color: transparent; border-bottom-color: transparent; border-radius: 0 999px 999px 0; transform: translateY(-50%); }\n#moonloom-spider-game .mls-sound-wave-1 { left: 16px; width: 7px; height: 9px; }\n#moonloom-spider-game .mls-sound-wave-2 { left: 19px; width: 10px; height: 15px; opacity: .82; }\n#moonloom-spider-game .mls-sound-wave-3 { left: 22px; width: 13px; height: 21px; opacity: .62; }\n#moonloom-spider-game .mls-mute-slash { position: absolute; left: -2px; top: 10px; width: 30px; height: 3.5px; border-radius: 99px; background: var(--mls-danger); transform: rotate(-42deg); opacity: 0; }\n#moonloom-spider-game .mls-muted .mls-sound-wave { opacity: .08; }\n#moonloom-spider-game .mls-muted .mls-mute-slash { opacity: 1; }\n#moonloom-spider-game .mls-fullscreen-icon { position: relative; width: 23px; height: 23px; display: block; }\n#moonloom-spider-game .mls-fs-corner { position: absolute; width: 9px; height: 9px; border-style: solid; border-color: var(--mls-cream); }\n#moonloom-spider-game .mls-fs-tl { left: 1px; top: 1px; border-width: 3px 0 0 3px; }\n#moonloom-spider-game .mls-fs-tr { right: 1px; top: 1px; border-width: 3px 3px 0 0; }\n#moonloom-spider-game .mls-fs-bl { left: 1px; bottom: 1px; border-width: 0 0 3px 3px; }\n#moonloom-spider-game .mls-fs-br { right: 1px; bottom: 1px; border-width: 0 3px 3px 0; }\n\n\/* Board *\/\n#moonloom-spider-game .mls-play-zone {\n  position: relative;\n  z-index: 5;\n  width: 100%;\n  height: 100%;\n  min-height: 0;\n  padding: clamp(64px,6.4vw,86px) clamp(10px,1.2vw,18px) clamp(54px,5.5vw,72px);\n  display: flex;\n  flex-direction: column;\n}\n\n#moonloom-spider-game .mls-board {\n  position: relative;\n  z-index: 5;\n  flex: 1 1 auto;\n  min-height: 0;\n  overflow: hidden;\n  isolation: isolate;\n  display: flex;\n  flex-direction: column;\n  gap: clamp(6px,.7vw,10px);\n  padding: clamp(8px,.75vw,12px);\n  border: clamp(2px,.22vw,4px) solid rgba(244,197,66,.52);\n  border-radius: clamp(16px,1.8vw,26px);\n  background:\n    linear-gradient(118deg,rgba(255,241,201,.08),transparent 24%),\n    radial-gradient(circle at 11% 10%,rgba(139,120,184,.18),transparent 25%),\n    radial-gradient(circle at 88% 15%,rgba(244,197,66,.11),transparent 27%),\n    linear-gradient(145deg,#4e3562 0%,#39244d 48%,#2a1838 100%);\n  box-shadow: inset 0 0 0 2px rgba(255,241,201,.12),inset 0 0 0 10px rgba(24,12,36,.10),0 22px 48px rgba(24,12,36,.32);\n}\n#moonloom-spider-game .mls-board::before {\n  content: \"\";\n  position: absolute;\n  inset: 8px;\n  border: 1px solid rgba(255,241,201,.18);\n  border-radius: inherit;\n  pointer-events: none;\n}\n#moonloom-spider-game .mls-board::after {\n  content: \"\";\n  position: absolute;\n  right: clamp(12px,1.5vw,24px);\n  bottom: clamp(8px,.9vw,14px);\n  width: clamp(92px,10vw,154px);\n  height: clamp(48px,5vw,76px);\n  opacity: .12;\n  background:\n    radial-gradient(circle at 23% 56%,#fff1c9 0 8%,transparent 9%),\n    radial-gradient(circle at 50% 37%,#e58e96 0 8%,transparent 9%),\n    radial-gradient(circle at 77% 56%,#8b78b8 0 8%,transparent 9%),\n    linear-gradient(135deg,transparent 0 43%,rgba(255,241,201,.55) 44% 47%,transparent 48%);\n  pointer-events: none;\n}\n\n#moonloom-spider-game .mls-board-top {\n  position: relative;\n  z-index: 2;\n  flex: 0 0 auto;\n  min-height: var(--mls-card-h);\n  display: grid;\n  grid-template-columns: repeat(10,minmax(0,1fr));\n  gap: clamp(4px,.42vw,6px);\n  align-items: start;\n  padding: clamp(8px,.72vw,11px) clamp(6px,.62vw,10px) 0;\n}\n\n#moonloom-spider-game .mls-stock-pile {\n  position: relative;\n  grid-column: 1;\n  justify-self: center;\n  width: var(--mls-card-w);\n  height: var(--mls-card-h);\n  min-width: var(--mls-card-w);\n  min-height: var(--mls-card-h);\n  padding: 0;\n  border: 0;\n  background: none;\n  overflow: visible;\n  transition: transform .14s ease,opacity .14s ease,filter .14s ease;\n}\n#moonloom-spider-game .mls-stock-pile:hover,\n#moonloom-spider-game .mls-stock-pile:focus-visible { transform: translateY(-2px); filter: brightness(1.05); outline: none; }\n#moonloom-spider-game .mls-stock-pile.mls-stock-empty .mls-stock-stack { opacity: 0; visibility: hidden; transform: translateY(4px) scale(.94); }\n#moonloom-spider-game .mls-stock-pile.mls-stock-dealing { pointer-events: none; }\n#moonloom-spider-game .mls-stock-pile:disabled { pointer-events: none; cursor: default; }\n#moonloom-spider-game .mls-stock-pile.mls-stock-shake { animation: mlsShake .32s ease; }\n#moonloom-spider-game .mls-stock-stack { position: absolute; inset: 0; width: var(--mls-card-w); height: var(--mls-card-h); transition: opacity .2s ease,transform .2s ease,visibility .2s ease; }\n\n#moonloom-spider-game .mls-stock-card,\n#moonloom-spider-game .mls-completed-card,\n#moonloom-spider-game .mls-card-back {\n  position: absolute;\n  inset: 0;\n  border: 1px solid rgba(244,197,66,.52);\n  border-radius: max(8px,calc(var(--mls-card-w)*.15));\n  background:\n    radial-gradient(circle at 50% 24%,rgba(255,241,201,.18),transparent 30%),\n    repeating-linear-gradient(45deg,rgba(255,241,201,.07) 0 8px,transparent 8px 16px),\n    linear-gradient(145deg,#8b78b8 0%,#57406e 60%,#39244d 100%);\n  box-shadow: inset 0 1px 0 rgba(255,241,201,.18),inset 0 0 0 3px rgba(255,241,201,.08),0 9px 20px rgba(24,12,36,.28);\n}\n#moonloom-spider-game .mls-stock-card::before,\n#moonloom-spider-game .mls-completed-card::before,\n#moonloom-spider-game .mls-card-back::before {\n  content: \"\";\n  position: absolute;\n  inset: 8%;\n  border: 1px dashed rgba(255,241,201,.46);\n  border-radius: max(6px,calc(var(--mls-card-w)*.12));\n}\n#moonloom-spider-game .mls-stock-card::after,\n#moonloom-spider-game .mls-completed-card::after,\n#moonloom-spider-game .mls-card-back::after {\n  content: \"\";\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  width: 34%;\n  aspect-ratio: 1;\n  transform: translate(-50%,-50%);\n  border-radius: 50%;\n  background:\n    radial-gradient(circle at 50% 60%,#fff8e7 0 36%,transparent 37%),\n    radial-gradient(ellipse at 34% 18%,#e58e96 0 18%,transparent 19%),\n    radial-gradient(ellipse at 66% 18%,#e58e96 0 18%,transparent 19%);\n  box-shadow: 0 0 0 2px rgba(244,197,66,.58),0 0 14px rgba(244,197,66,.22);\n}\n#moonloom-spider-game .mls-stock-card:nth-child(1) { transform: translate(0,0); }\n#moonloom-spider-game .mls-stock-card:nth-child(2) { transform: translate(4px,3px); }\n#moonloom-spider-game .mls-stock-card:nth-child(3) { transform: translate(8px,6px); }\n\n#moonloom-spider-game .mls-completed-panel {\n  grid-column: 3 \/ span 8;\n  position: relative;\n  min-width: 0;\n  width: 100%;\n  min-height: calc(var(--mls-card-h) + clamp(14px,1.2vw,18px));\n  padding: clamp(8px,.75vw,12px);\n  overflow: hidden;\n  border: 1px solid rgba(244,197,66,.34);\n  border-radius: clamp(12px,1.3vw,18px);\n  background: linear-gradient(180deg,rgba(91,63,120,.70),rgba(35,20,47,.68));\n  box-shadow: inset 0 0 0 2px rgba(255,241,201,.07),0 10px 24px rgba(24,12,36,.22);\n}\n#moonloom-spider-game .mls-completed-panel::after {\n  content: \"MOONCRAFT TRAYS\";\n  position: absolute;\n  left: 14px;\n  top: 6px;\n  color: rgba(255,241,201,.54);\n  font-size: clamp(7px,.75vw,10px);\n  font-weight: 900;\n  letter-spacing: .16em;\n}\n#moonloom-spider-game .mls-completed-slots {\n  position: relative;\n  z-index: 1;\n  width: 100%;\n  display: grid;\n  grid-template-columns: repeat(8,minmax(0,1fr));\n  align-items: center;\n  justify-items: center;\n}\n#moonloom-spider-game .mls-completed-slot {\n  position: relative;\n  width: var(--mls-card-w);\n  height: var(--mls-card-h);\n  border: 1px dashed rgba(255,241,201,.28);\n  border-radius: max(8px,calc(var(--mls-card-w)*.15));\n  background: linear-gradient(180deg,rgba(255,241,201,.06),rgba(139,120,184,.10));\n}\n#moonloom-spider-game .mls-completed-slot::before {\n  content: \"\";\n  position: absolute;\n  left: 20%;\n  right: 20%;\n  bottom: 18%;\n  height: 34%;\n  border: 2px solid rgba(255,241,201,.18);\n  border-radius: 9px 9px 15px 15px;\n  background: repeating-linear-gradient(90deg,rgba(244,197,66,.10) 0 5px,transparent 5px 10px);\n}\n#moonloom-spider-game .mls-completed-slot.mls-completed-filled {\n  border-style: solid;\n  border-color: rgba(244,197,66,.58);\n  background: linear-gradient(180deg,#fff8e7,#ead9bd);\n  box-shadow: 0 0 18px rgba(244,197,66,.24);\n}\n#moonloom-spider-game .mls-completed-card-stack { position: absolute; left: 50%; top: 50%; width: var(--mls-card-w); height: var(--mls-card-h); transform: translate(-50%,-50%); pointer-events: none; }\n#moonloom-spider-game .mls-completed-card:nth-child(1) { transform: translate(-5px,5px) rotate(-2deg); opacity: .82; }\n#moonloom-spider-game .mls-completed-card:nth-child(2) { transform: translate(-2px,2px) rotate(-1deg); opacity: .92; }\n#moonloom-spider-game .mls-completed-card:nth-child(3) { transform: none; }\n#moonloom-spider-game .mls-completed-slot.mls-completed-new { animation: mlsCompleteSlotGlow .86s ease both; }\n#moonloom-spider-game .mls-completed-slot.mls-completed-new .mls-completed-card-stack { animation: mlsCompleteStackIn .72s cubic-bezier(.18,.88,.26,1.08) both; }\n#moonloom-spider-game .mls-slot-bloom { position: absolute; left: 50%; top: 50%; width: 34%; height: 34%; transform: translate(-50%,-50%); border-radius: 999px; background: rgba(255,248,231,.78); opacity: 0; }\n#moonloom-spider-game .mls-completed-new .mls-slot-bloom { animation: mlsCompleteBloom .74s ease both .08s; }\n\n#moonloom-spider-game .mls-tableau {\n  position: relative;\n  z-index: 2;\n  flex: 1 1 auto;\n  min-height: 0;\n  display: grid;\n  grid-template-columns: repeat(10,minmax(0,1fr));\n  gap: clamp(4px,.42vw,6px);\n  margin-top: clamp(6px,.7vw,10px);\n  padding: 0 clamp(6px,.62vw,10px) clamp(8px,.72vw,11px);\n}\n#moonloom-spider-game .mls-column {\n  position: relative;\n  min-width: 0;\n  min-height: 100%;\n  padding-top: var(--mls-stack-top-inset,6px);\n  overflow: visible;\n  border: 1px solid rgba(255,241,201,.10);\n  border-radius: clamp(9px,1.1vw,17px);\n  background: linear-gradient(180deg,rgba(255,241,201,.025),rgba(139,120,184,.045));\n  box-shadow: inset 0 1px 0 rgba(255,241,201,.04),inset 0 -14px 22px rgba(24,12,36,.05);\n  transition: border-color .14s ease,box-shadow .14s ease,background .14s ease;\n}\n#moonloom-spider-game .mls-column::before {\n  content: \"\";\n  position: absolute;\n  top: var(--mls-stack-top-inset,6px);\n  left: 50%;\n  width: min(calc(var(--mls-card-w)*.96),calc(100% - (var(--mls-stack-inset,10px)*2)));\n  height: calc(var(--mls-card-h)*.35);\n  transform: translateX(-50%);\n  border: 1px dashed rgba(255,241,201,.11);\n  border-radius: clamp(7px,.85vw,13px);\n  pointer-events: none;\n}\n#moonloom-spider-game .mls-column.mls-column-valid,\n#moonloom-spider-game .mls-column.mls-column-hint-target { border-color: rgba(244,197,66,.82); background: linear-gradient(180deg,rgba(244,197,66,.13),rgba(139,120,184,.14)); box-shadow: 0 0 22px rgba(244,197,66,.20); }\n#moonloom-spider-game .mls-column.mls-column-invalid { border-color: rgba(217,111,111,.82); box-shadow: 0 0 18px rgba(217,111,111,.22); }\n\n\/* Cards *\/\n#moonloom-spider-game .mls-card {\n  position: absolute;\n  left: 50%;\n  width: var(--mls-card-w);\n  height: var(--mls-card-h);\n  transform: translateX(-50%);\n  border-radius: max(8px,calc(var(--mls-card-w)*.15));\n  user-select: none;\n  touch-action: none;\n  overflow: hidden;\n  transition: transform .13s ease,box-shadow .13s ease,filter .13s ease,opacity .13s ease;\n}\n#moonloom-spider-game .mls-card-front {\n  cursor: grab;\n  border: 1px solid rgba(74,49,86,.36);\n  color: var(--mls-ink);\n  background:\n    radial-gradient(circle at 50% 0%,rgba(255,255,255,.78),transparent 54%),\n    linear-gradient(155deg,#fffdf0 0%,#fff8df 62%,#e7d4b4 100%);\n  box-shadow: 0 10px 21px rgba(24,12,36,.24),inset 0 0 0 1px rgba(255,255,255,.54);\n}\n#moonloom-spider-game .mls-card-front:active { cursor: grabbing; }\n#moonloom-spider-game .mls-card-front::before { content: \"\"; position: absolute; inset: 5px; border: 1px solid rgba(139,120,184,.20); border-radius: max(6px,calc(var(--mls-card-w)*.12)); pointer-events: none; }\n#moonloom-spider-game .mls-card-front::after { content: \"\"; position: absolute; left: 12px; right: 12px; top: 51%; height: 1px; background: linear-gradient(90deg,transparent,rgba(47,32,61,.10),transparent); }\n#moonloom-spider-game .mls-card-corner { position: absolute; left: 4px; top: 6px; z-index: 3; width: 30px; display: flex; flex-direction: column; align-items: center; gap: 2px; line-height: .88; text-align: center; }\n#moonloom-spider-game .mls-card-corner-bottom { left: auto; top: auto; right: 4px; bottom: 6px; transform: rotate(180deg); opacity: .92; }\n#moonloom-spider-game .mls-card-rank { color: currentColor; font-family: Georgia,\"Times New Roman\",serif; font-size: clamp(15px,calc(var(--mls-card-w)*.26),22px); font-weight: 900; letter-spacing: -.045em; text-shadow: 0 1px 0 rgba(255,255,255,.72); }\n#moonloom-spider-game .mls-suit { position: relative; display: block; color: currentColor; font-size: 0; }\n#moonloom-spider-game .mls-suit-shape { width: 46px; height: 46px; }\n#moonloom-spider-game .mls-suit-shape.small { width: 17px; height: 17px; }\n#moonloom-spider-game .mls-card-watermark { position: absolute; inset: 0; display: grid; place-items: center; opacity: .90; filter: drop-shadow(0 1px 0 rgba(255,255,255,.38)); pointer-events: none; }\n#moonloom-spider-game .mls-card-watermark .mls-suit-shape { width: clamp(36px,calc(var(--mls-card-w)*.56),70px); height: clamp(36px,calc(var(--mls-card-w)*.56),70px); transform: none; }\n#moonloom-spider-game .mls-card-front.mls-card-suit-0,\n#moonloom-spider-game .mls-card-front.mls-card-suit-0 .mls-card-rank,\n#moonloom-spider-game .mls-card-front.mls-card-suit-0 .mls-suit { color: var(--mls-rose); }\n#moonloom-spider-game .mls-card-front.mls-card-suit-1,\n#moonloom-spider-game .mls-card-front.mls-card-suit-1 .mls-card-rank,\n#moonloom-spider-game .mls-card-front.mls-card-suit-1 .mls-suit { color: var(--mls-mochi); }\n#moonloom-spider-game .mls-card-front.mls-card-suit-2,\n#moonloom-spider-game .mls-card-front.mls-card-suit-2 .mls-card-rank,\n#moonloom-spider-game .mls-card-front.mls-card-suit-2 .mls-suit { color: #7d78c7; }\n#moonloom-spider-game .mls-card-front.mls-card-suit-3,\n#moonloom-spider-game .mls-card-front.mls-card-suit-3 .mls-card-rank,\n#moonloom-spider-game .mls-card-front.mls-card-suit-3 .mls-suit { color: var(--mls-wood); }\n\n#moonloom-spider-game .mls-suit-rabbit::before,\n#moonloom-spider-game .mls-suit-rabbit::after,\n#moonloom-spider-game .mls-suit-mochi::before,\n#moonloom-spider-game .mls-suit-mochi::after,\n#moonloom-spider-game .mls-suit-cloud::before,\n#moonloom-spider-game .mls-suit-cloud::after,\n#moonloom-spider-game .mls-suit-mallet::before,\n#moonloom-spider-game .mls-suit-mallet::after {\n  content: \"\";\n  position: absolute;\n  pointer-events: none;\n}\n\n#moonloom-spider-game .mls-suit-rabbit::before {\n  left: 18%;\n  right: 18%;\n  top: 27%;\n  bottom: 9%;\n  border-radius: 50%;\n  background: currentColor;\n  box-shadow: inset -4px -5px 0 rgba(47,32,61,.10),0 1px 0 rgba(255,255,255,.38);\n}\n#moonloom-spider-game .mls-suit-rabbit::after {\n  left: 27%;\n  top: 2%;\n  width: 18%;\n  height: 42%;\n  border-radius: 999px;\n  background: currentColor;\n  box-shadow: 18px 0 0 currentColor;\n  transform: rotate(-4deg);\n}\n#moonloom-spider-game .mls-suit-rabbit.small::after { box-shadow: 7px 0 0 currentColor; }\n\n#moonloom-spider-game .mls-suit-mochi::before {\n  left: 9%;\n  right: 9%;\n  top: 24%;\n  bottom: 10%;\n  border-radius: 50% 50% 44% 44%;\n  background: currentColor;\n  box-shadow: inset 6px 6px 0 rgba(255,248,231,.24),inset -4px -5px 0 rgba(47,32,61,.10);\n}\n#moonloom-spider-game .mls-suit-mochi::after {\n  right: 3%;\n  bottom: 6%;\n  width: 36%;\n  height: 22%;\n  border-radius: 999px 999px 0 999px;\n  background: var(--mls-moss);\n  transform: rotate(-18deg);\n}\n\n#moonloom-spider-game .mls-suit-cloud::before {\n  inset: 18% 4% 14%;\n  background:\n    radial-gradient(circle at 28% 62%,currentColor 0 27%,transparent 28%),\n    radial-gradient(circle at 52% 40%,currentColor 0 34%,transparent 35%),\n    radial-gradient(circle at 76% 63%,currentColor 0 28%,transparent 29%),\n    linear-gradient(currentColor,currentColor) 20% 61% \/ 64% 29% no-repeat;\n}\n#moonloom-spider-game .mls-suit-cloud::after {\n  right: 9%;\n  top: 12%;\n  width: 25%;\n  height: 25%;\n  border-radius: 50%;\n  box-shadow: -7px 0 0 0 rgba(255,248,231,.70);\n}\n\n#moonloom-spider-game .mls-suit-mallet::before {\n  left: 8%;\n  top: 18%;\n  width: 58%;\n  height: 30%;\n  border-radius: 6px;\n  background: currentColor;\n  transform: rotate(-34deg);\n  box-shadow: inset -4px -4px 0 rgba(47,32,61,.12);\n}\n#moonloom-spider-game .mls-suit-mallet::after {\n  left: 48%;\n  top: 38%;\n  width: 18%;\n  height: 54%;\n  border-radius: 999px;\n  background: currentColor;\n  transform: rotate(-34deg);\n  box-shadow: inset -3px -3px 0 rgba(47,32,61,.12);\n}\n\n#moonloom-spider-game .mls-card-selected { filter: brightness(1.04); box-shadow: 0 0 0 3px rgba(244,197,66,.54),0 12px 24px rgba(24,12,36,.26); }\n#moonloom-spider-game .mls-card-hint { filter: brightness(1.05); box-shadow: 0 0 0 3px rgba(207,209,255,.62),0 0 22px rgba(207,209,255,.34); }\n#moonloom-spider-game .mls-card-drag-source { opacity: .14; }\n#moonloom-spider-game .mls-card-flip { animation: mlsCardFlip .22s ease; }\n#moonloom-spider-game .mls-card-deal-in { animation: mlsDealCardIn .46s cubic-bezier(.18,.88,.26,1.12) both; animation-delay: var(--mls-deal-delay,0ms); }\n\n\/* Messages and controls *\/\n#moonloom-spider-game .mls-message-bar {\n  position: absolute;\n  left: 50%;\n  bottom: clamp(50px,5.2vw,68px);\n  z-index: 12;\n  width: max-content;\n  max-width: min(74%,600px);\n  min-height: clamp(22px,2.8vw,34px);\n  padding: clamp(4px,.4vw,7px) clamp(12px,1.2vw,18px);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  overflow: hidden;\n  border: 1px solid rgba(244,197,66,.38);\n  border-radius: 999px;\n  color: var(--mls-cream);\n  background: linear-gradient(180deg,rgba(91,63,120,.96),rgba(48,30,64,.96));\n  box-shadow: 0 8px 20px rgba(24,12,36,.24);\n  font-size: clamp(9px,1vw,14px);\n  font-weight: 720;\n  text-align: center;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  pointer-events: none;\n  opacity: 0;\n  visibility: hidden;\n  transform: translateX(-50%);\n  transition: opacity .2s ease,visibility .2s ease;\n}\n#moonloom-spider-game .mls-message-bar.mls-message-visible { opacity: 1; visibility: visible; }\n#moonloom-spider-game .mls-message-bar.mls-message-pulse { animation: mlsPulse .3s ease; }\n#moonloom-spider-game .mls-bottom-actions { position: absolute; left: 50%; bottom: clamp(11px,1.3vw,19px); z-index: 12; max-width: 97%; display: flex; align-items: center; justify-content: center; gap: clamp(4px,.55vw,8px); transform: translateX(-50%); }\n#moonloom-spider-game .mls-workshop-button { min-height: clamp(28px,3.3vw,42px); padding: 0 clamp(8px,1vw,15px); border-radius: 999px; font-size: clamp(8px,.95vw,13px); font-weight: 850; letter-spacing: .02em; white-space: nowrap; transition: transform .14s ease,border-color .14s ease,box-shadow .14s ease,opacity .14s ease; }\n#moonloom-spider-game .mls-workshop-button:disabled,\n#moonloom-spider-game .mls-popup-button:disabled { opacity: .48; cursor: default; transform: none; }\n\n\/* Popup; fullscreen remains above overlay *\/\n#moonloom-spider-game .mls-popup-overlay {\n  position: absolute;\n  inset: 0;\n  z-index: 150;\n  display: none;\n  align-items: center;\n  justify-content: center;\n  padding: clamp(10px,1.5vw,20px);\n  background: radial-gradient(circle at 52% 42%,rgba(244,197,66,.13),transparent 38%),rgba(24,12,36,.66);\n  backdrop-filter: blur(7px);\n  -webkit-backdrop-filter: blur(7px);\n  overflow: hidden;\n  border-radius: inherit;\n}\n#moonloom-spider-game .mls-popup-overlay.mls-popup-visible { display: flex; }\n#moonloom-spider-game .mls-shell.mls-overlay-ui .mls-topbar { grid-template-columns: 1fr auto; }\n#moonloom-spider-game .mls-shell.mls-overlay-ui .mls-top-left,\n#moonloom-spider-game .mls-shell.mls-overlay-ui .mls-stat-row { display: none; }\n#moonloom-spider-game .mls-shell.mls-overlay-ui .mls-top-right { grid-column: 2; z-index: 230; }\n\n#moonloom-spider-game .mls-popup {\n  position: relative;\n  width: min(86%,430px);\n  max-height: min(88%,430px);\n  padding: clamp(17px,2vw,26px);\n  overflow: hidden;\n  border: 1px solid rgba(244,197,66,.42);\n  border-radius: 26px;\n  background:\n    radial-gradient(circle at 80% 0%,rgba(244,197,66,.20),transparent 35%),\n    linear-gradient(145deg,rgba(255,248,231,.99),rgba(224,211,245,.96));\n  text-align: center;\n  color: var(--mls-ink);\n  box-shadow: inset 0 0 0 4px rgba(255,255,255,.30),0 24px 54px rgba(24,12,36,.36);\n  animation: mlsPopupIn .22s ease both;\n}\n#moonloom-spider-game .mls-popup::before {\n  content: \"\";\n  position: absolute;\n  left: 50%;\n  top: 9px;\n  width: 48px;\n  height: 48px;\n  transform: translateX(-50%);\n  border-radius: 50%;\n  background:\n    radial-gradient(circle at 50% 58%,#fff8e7 0 34%,transparent 35%),\n    radial-gradient(ellipse at 35% 15%,#e58e96 0 16%,transparent 17%),\n    radial-gradient(ellipse at 65% 15%,#e58e96 0 16%,transparent 17%),\n    radial-gradient(circle,#f4c542 0 68%,#8b78b8 69% 100%);\n  filter: drop-shadow(0 5px 8px rgba(47,32,61,.18));\n}\n#moonloom-spider-game .mls-popup-title { margin: 34px 0 0; color: var(--mls-ink); font-size: clamp(20px,3vw,34px); line-height: 1.05; font-weight: 900; letter-spacing: -.03em; }\n#moonloom-spider-game .mls-popup-subtitle { margin: clamp(6px,.8vw,9px) auto 0; color: #6b4d74; font-size: clamp(9px,1vw,13px); line-height: 1.35; font-weight: 850; letter-spacing: .08em; text-transform: uppercase; }\n#moonloom-spider-game .mls-popup-note { margin: clamp(8px,.9vw,11px) auto 0; color: rgba(47,32,61,.76); font-size: clamp(10px,1.05vw,14px); line-height: 1.45; font-weight: 620; }\n#moonloom-spider-game .mls-popup-actions { margin-top: clamp(11px,1.3vw,16px); display: flex; justify-content: center; align-items: center; gap: clamp(5px,.7vw,9px); flex-wrap: wrap; }\n#moonloom-spider-game .mls-popup-button { min-width: clamp(82px,10vw,122px); min-height: clamp(30px,3.2vw,42px); padding: 0 clamp(11px,1.3vw,16px); border-radius: 999px; font-size: clamp(10px,1.05vw,14px); font-weight: 850; letter-spacing: .02em; transition: transform .14s ease,box-shadow .14s ease,border-color .14s ease; }\n#moonloom-spider-game .mls-popup-button.mls-popup-start,\n#moonloom-spider-game .mls-popup-button.mls-popup-cancel,\n#moonloom-spider-game .mls-mode-pill.mls-mode-active { color: #39244d; border-color: rgba(255,255,255,.56); background: linear-gradient(180deg,#fff8df,#f4c542); box-shadow: inset 0 1px 0 rgba(255,255,255,.65),0 9px 20px rgba(47,32,61,.15); }\n#moonloom-spider-game .mls-popup-button.mls-popup-secondary { color: var(--mls-ink); background: linear-gradient(180deg,#fff8e7,#e8d2a7); border-color: rgba(47,32,61,.18); }\n#moonloom-spider-game .mls-mode-row { width: min(100%,306px); margin: clamp(10px,1.1vw,14px) auto 0; display: flex; justify-content: center; gap: clamp(5px,.7vw,9px); }\n#moonloom-spider-game .mls-popup-actions.mls-popup-actions-short { width: auto; margin-left: auto; margin-right: auto; }\n#moonloom-spider-game .mls-popup-button.mls-popup-button-short { min-width: clamp(110px,12vw,150px); width: auto; padding: 0 clamp(18px,2vw,24px); }\n#moonloom-spider-game .mls-mode-pill { min-width: clamp(62px,7vw,92px); min-height: clamp(28px,3vw,38px); padding: 0 clamp(8px,1vw,13px); border-radius: 999px; font-size: clamp(10px,1.02vw,14px); font-weight: 850; }\n#moonloom-spider-game .mls-popup-stats { width: min(100%,292px); margin: clamp(10px,1.2vw,14px) auto 0; display: grid; grid-template-columns: repeat(3,1fr); gap: clamp(4px,.55vw,7px); }\n#moonloom-spider-game .mls-popup-stat { padding: clamp(5px,.7vw,8px); border: 1px solid rgba(47,32,61,.12); border-radius: clamp(10px,1vw,14px); background: rgba(255,255,255,.34); }\n#moonloom-spider-game .mls-popup-stat span { display: block; color: rgba(47,32,61,.56); font-size: clamp(7px,.82vw,10px); font-weight: 850; letter-spacing: .08em; text-transform: uppercase; }\n#moonloom-spider-game .mls-popup-stat strong { display: block; margin-top: 3px; color: var(--mls-ink); font-size: clamp(12px,1.45vw,18px); font-weight: 900; }\n\n#moonloom-spider-game .mls-drag-ghost { position: fixed; left: 0; top: 0; z-index: 999999; width: var(--mls-card-w); height: var(--mls-card-h); display: none; pointer-events: none; will-change: transform; }\n#moonloom-spider-game .mls-drag-ghost.mls-drag-active { display: block; }\n#moonloom-spider-game .mls-drag-ghost .mls-card { left: 0; transform: none; box-shadow: 0 16px 34px rgba(24,12,36,.34); }\n#moonloom-spider-game .mls-win-sparkle { position: absolute; inset: 0; z-index: 182; overflow: hidden; pointer-events: none; }\n#moonloom-spider-game .mls-win-sparkle span { position: absolute; width: 8px; height: 8px; border-radius: 50%; background: var(--mls-paper); box-shadow: 0 0 12px rgba(255,248,231,.92),0 0 22px rgba(244,197,66,.52); animation: mlsSpark 1.15s ease-out forwards; }\n\n\/* Firefox-safe native and fallback fullscreen *\/\n#moonloom-spider-game.mls-browser-fullscreen,\n#moonloom-spider-game.mls-landscape-fullscreen,\n#moonloom-spider-game.mls-fallback-fullscreen {\n  --mls-fs-vw: 100vw;\n  --mls-fs-vh: 100vh;\n  --mls-fs-shell-w: min(100vw,177.777778vh);\n  --mls-fs-shell-h: min(100vh,56.25vw);\n  --mls-fs-center-x: 50vw;\n  --mls-fs-center-y: 50vh;\n  position: fixed;\n  inset: 0;\n  z-index: 2147483647;\n  width: var(--mls-fs-vw);\n  height: var(--mls-fs-vh);\n  max-width: none;\n  min-width: 0;\n  min-height: 0;\n  margin: 0;\n  padding: 0;\n  display: block;\n  overflow: hidden;\n  background: linear-gradient(180deg,#23142f,#39244d 52%,#2a1838 100%);\n}\n#moonloom-spider-game.mls-browser-fullscreen .mls-shell,\n#moonloom-spider-game.mls-landscape-fullscreen .mls-shell,\n#moonloom-spider-game.mls-fallback-fullscreen .mls-shell {\n  position: fixed;\n  left: var(--mls-fs-center-x);\n  top: var(--mls-fs-center-y);\n  width: var(--mls-fs-shell-w);\n  height: var(--mls-fs-shell-h);\n  max-width: none;\n  max-height: none;\n  min-width: 0;\n  min-height: 0;\n  aspect-ratio: 16\/9;\n  margin: 0;\n  transform: translate(-50%,-50%);\n  border-radius: clamp(12px,1.45vmin,24px);\n}\n#moonloom-spider-game:fullscreen::backdrop { background: linear-gradient(180deg,#23142f,#39244d 52%,#2a1838 100%); }\n#moonloom-spider-game:-webkit-full-screen::-webkit-backdrop { background: linear-gradient(180deg,#23142f,#39244d 52%,#2a1838 100%); }\n\n@keyframes mlsShake { 0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}50%{transform:translateX(4px)}75%{transform:translateX(-2px)} }\n@keyframes mlsCardFlip { 0%{transform:translateX(-50%) scaleX(.58);filter:brightness(1.2)}100%{transform:translateX(-50%) scaleX(1);filter:brightness(1)} }\n@keyframes mlsPulse { 0%,100%{transform:translateX(-50%) scale(1)}50%{transform:translateX(-50%) scale(1.02)} }\n@keyframes mlsPopupIn { 0%{opacity:0;transform:translateY(8px) scale(.97)}100%{opacity:1;transform:none} }\n@keyframes mlsSpark { 0%{opacity:0;transform:translate3d(0,0,0) scale(.4)}18%{opacity:1}100%{opacity:0;transform:translate3d(var(--mls-sx),var(--mls-sy),0) scale(1.4)} }\n@keyframes mlsCompleteStackIn { 0%{opacity:0;transform:translate(-50%,calc(-50% + clamp(86px,10vw,142px))) scale(.70) rotate(-5deg)}58%{opacity:1;transform:translate(-50%,calc(-50% - 6px)) scale(1.06) rotate(1.5deg)}100%{opacity:1;transform:translate(-50%,-50%) scale(1)} }\n@keyframes mlsDealCardIn { 0%{opacity:0;transform:translateX(-50%) translateY(calc(-1 * min(122px,var(--mls-card-h)))) scale(.74) rotate(-2deg)}62%{opacity:1;transform:translateX(-50%) translateY(4px) scale(1.035) rotate(.6deg)}100%{opacity:1;transform:translateX(-50%) translateY(0) scale(1)} }\n@keyframes mlsCompleteSlotGlow { 0%{border-color:rgba(244,197,66,.24);box-shadow:none}45%{border-color:rgba(244,197,66,.72);box-shadow:0 0 0 3px rgba(244,197,66,.16),0 0 30px rgba(255,248,231,.46)}100%{border-color:rgba(244,197,66,.58);box-shadow:0 0 18px rgba(244,197,66,.24)} }\n@keyframes mlsCompleteBloom { 0%{opacity:0;transform:translate(-50%,-50%) scale(.25)}42%{opacity:.92;transform:translate(-50%,-50%) scale(1.28);box-shadow:0 -13px 0 -4px rgba(255,248,231,.86),0 13px 0 -4px rgba(139,120,184,.76),13px 0 0 -4px rgba(229,142,150,.72),-13px 0 0 -4px rgba(244,197,66,.72)}100%{opacity:0;transform:translate(-50%,-50%) scale(1.72)} }\n\n@media (max-width:680px),(max-height:420px) {\n  #moonloom-spider-game .mls-topbar { grid-template-columns: 70px 1fr 38px; gap: 4px; }\n  #moonloom-spider-game .mls-stat-row { gap: 4px; }\n  #moonloom-spider-game .mls-stat-capsule { min-width: 42px; padding-left: 4px; padding-right: 4px; }\n  #moonloom-spider-game .mls-stat-capsule.mls-stat-wide { min-width: 58px; }\n  #moonloom-spider-game .mls-bottom-actions { gap: 4px; }\n  #moonloom-spider-game .mls-workshop-button { padding-left: 7px; padding-right: 7px; }\n}\n\n@media (orientation:portrait) and (max-width:680px) {\n  #moonloom-spider-game .mls-topbar { top: 4px; left: 5px; right: 5px; grid-template-columns: 62px 1fr 32px; }\n  #moonloom-spider-game .mls-icon-button { width: 29px; height: 29px; border-radius: 9px; }\n  #moonloom-spider-game .mls-pause-icon { width: 15px; height: 15px; gap: 4px; }\n  #moonloom-spider-game .mls-pause-icon span { width: 4px; height: 15px; }\n  #moonloom-spider-game .mls-sound-icon { transform: translateX(-2px) scale(.72); }\n  #moonloom-spider-game .mls-fullscreen-icon { transform: scale(.76); }\n  #moonloom-spider-game .mls-stat-capsule { min-width: 36px; height: 27px; padding: 2px 3px; }\n  #moonloom-spider-game .mls-stat-capsule.mls-stat-wide { min-width: 48px; }\n  #moonloom-spider-game .mls-stat-label { margin-bottom: 2px; font-size: 5.5px; }\n  #moonloom-spider-game .mls-stat-value { font-size: 9px; }\n  #moonloom-spider-game .mls-play-zone { padding: 36px 4px 31px; }\n}\n\n@media (orientation:landscape) and (max-height:560px) {\n  #moonloom-spider-game { min-height: 0; display: flex; align-items: center; justify-content: center; }\n  #moonloom-spider-game .mls-shell { width: min(100%,calc((100dvh - 6px)*16\/9)); max-height: calc(100dvh - 6px); border-radius: clamp(10px,1.4vmin,18px); }\n  #moonloom-spider-game .mls-play-zone { padding-top: clamp(50px,11vh,66px); padding-bottom: clamp(43px,9vh,56px); }\n  #moonloom-spider-game .mls-topbar { top: 6px; }\n  #moonloom-spider-game .mls-bottom-actions { bottom: 7px; }\n}\n\n@media (prefers-reduced-motion:reduce) {\n  #moonloom-spider-game *,\n  #moonloom-spider-game *::before,\n  #moonloom-spider-game *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }\n}\n  <\/style>\n\n  <div class=\"mls-shell\" aria-label=\"Moonloom Spider Moon Rabbit Workshop Spider Solitaire game\">\n    <div class=\"mls-workshop-bg\" aria-hidden=\"true\">\n      <div class=\"mls-moon-window\"><\/div>\n      <div class=\"mls-cloud-bank\"><\/div>\n      <div class=\"mls-star-dust\"><\/div>\n      <div class=\"mls-workbench\"><\/div>\n      <div class=\"mls-tool-shelf left\"><\/div>\n      <div class=\"mls-tool-shelf right\"><\/div>\n      <div class=\"mls-lantern left\"><\/div>\n      <div class=\"mls-lantern right\"><\/div>\n    <\/div>\n\n    <div class=\"mls-topbar\">\n      <div class=\"mls-top-left\">\n        <button class=\"mls-icon-button\" type=\"button\" data-mls-action=\"pause\" aria-label=\"Pause game\">\n          <span class=\"mls-pause-icon\" aria-hidden=\"true\"><span><\/span><span><\/span><\/span>\n        <\/button>\n        <button class=\"mls-icon-button\" type=\"button\" data-mls-action=\"sound\" aria-label=\"Toggle sound\">\n          <span class=\"mls-sound-icon\" aria-hidden=\"true\">\n            <span class=\"mls-speaker-box\"><\/span>\n            <span class=\"mls-speaker-cone\"><\/span>\n            <span class=\"mls-sound-wave mls-sound-wave-1\"><\/span>\n            <span class=\"mls-sound-wave mls-sound-wave-2\"><\/span>\n            <span class=\"mls-sound-wave mls-sound-wave-3\"><\/span>\n            <span class=\"mls-mute-slash\"><\/span>\n          <\/span>\n        <\/button>\n      <\/div>\n\n      <div class=\"mls-stat-row\" aria-live=\"polite\">\n        <div class=\"mls-stat-capsule\"><span class=\"mls-stat-label\">Score<\/span><span class=\"mls-stat-value\" id=\"mls-score-value\">500<\/span><\/div>\n        <div class=\"mls-stat-capsule\"><span class=\"mls-stat-label\">Moves<\/span><span class=\"mls-stat-value\" id=\"mls-moves-value\">0<\/span><\/div>\n        <div class=\"mls-stat-capsule mls-stat-wide\"><span class=\"mls-stat-label\">Completed<\/span><span class=\"mls-stat-value\" id=\"mls-completed-value\">0\/8<\/span><\/div>\n        <div class=\"mls-stat-capsule\"><span class=\"mls-stat-label\">Deals<\/span><span class=\"mls-stat-value\" id=\"mls-deals-value\">5<\/span><\/div>\n      <\/div>\n\n      <div class=\"mls-top-right\">\n        <button class=\"mls-icon-button\" type=\"button\" data-mls-action=\"fullscreen\" aria-label=\"Toggle fullscreen\">\n          <span class=\"mls-fullscreen-icon\" aria-hidden=\"true\">\n            <span class=\"mls-fs-corner mls-fs-tl\"><\/span><span class=\"mls-fs-corner mls-fs-tr\"><\/span>\n            <span class=\"mls-fs-corner mls-fs-bl\"><\/span><span class=\"mls-fs-corner mls-fs-br\"><\/span>\n          <\/span>\n        <\/button>\n      <\/div>\n    <\/div>\n\n    <div class=\"mls-play-zone\">\n      <div class=\"mls-board\">\n        <div class=\"mls-board-top\">\n          <button class=\"mls-stock-pile\" type=\"button\" data-mls-action=\"stock\" aria-label=\"Deal one card to every tableau column\">\n            <span class=\"mls-stock-stack\" aria-hidden=\"true\">\n              <span class=\"mls-stock-card\"><\/span><span class=\"mls-stock-card\"><\/span><span class=\"mls-stock-card\"><\/span>\n            <\/span>\n          <\/button>\n          <div class=\"mls-completed-panel\"><div class=\"mls-completed-slots\" id=\"mls-completed-slots\"><\/div><\/div>\n        <\/div>\n        <div class=\"mls-tableau\" id=\"mls-tableau\"><\/div>\n      <\/div>\n\n      <div class=\"mls-message-bar\" id=\"mls-message-bar\">Build same-suit moonlit trails from King down to Ace.<\/div>\n\n      <div class=\"mls-bottom-actions\">\n        <button class=\"mls-workshop-button\" type=\"button\" data-mls-action=\"new-game\">New Game<\/button>\n        <button class=\"mls-workshop-button\" type=\"button\" data-mls-action=\"restart\">Restart<\/button>\n        <button class=\"mls-workshop-button\" type=\"button\" data-mls-action=\"stock\">Deal Cards<\/button>\n        <button class=\"mls-workshop-button\" type=\"button\" data-mls-action=\"undo\">Undo<\/button>\n        <button class=\"mls-workshop-button\" type=\"button\" data-mls-action=\"hint\">Moon Hint<\/button>\n      <\/div>\n    <\/div>\n\n    <div class=\"mls-popup-overlay mls-popup-visible\" id=\"mls-popup-overlay\"><div class=\"mls-popup\" id=\"mls-popup\"><\/div><\/div>\n    <div class=\"mls-drag-ghost\" id=\"mls-drag-ghost\"><\/div>\n    <div class=\"mls-win-sparkle\" id=\"mls-win-sparkle\" aria-hidden=\"true\"><\/div>\n  <\/div>\n\n  <script>\n(function () {\n      \"use strict\";\n      function mlsInitialize() {\n      const mlsRoot = document.getElementById(\"moonloom-spider-game\");\n      if (!mlsRoot || mlsRoot.dataset.mlsReady === \"true\" || mlsRoot.dataset.mlsReady === \"booting\") return;\n      mlsRoot.dataset.mlsReady = \"booting\";\n      const mlsShell = mlsRoot.querySelector(\".mls-shell\");\n      const mlsTableau = mlsRoot.querySelector(\"#mls-tableau\");\n      const mlsStacksSlots = mlsRoot.querySelector(\"#mls-completed-slots\");\n      const mlsPopupOverlay = mlsRoot.querySelector(\"#mls-popup-overlay\");\n      const mlsPopup = mlsRoot.querySelector(\"#mls-popup\");\n      const mlsMessageBar = mlsRoot.querySelector(\"#mls-message-bar\");\n      const mlsPointsValue = mlsRoot.querySelector(\"#mls-score-value\");\n      const mlsStepsValue = mlsRoot.querySelector(\"#mls-moves-value\");\n      const mlsStacksValue = mlsRoot.querySelector(\"#mls-completed-value\");\n      const mlsDrawsValue = mlsRoot.querySelector(\"#mls-deals-value\");\n      const mlsStockPile = mlsRoot.querySelector(\".mls-stock-pile\");\n      const mlsSoundButton = mlsRoot.querySelector('[data-mls-action=\"sound\"]');\n      const mlsDragGhost = mlsRoot.querySelector(\"#mls-drag-ghost\");\n      const mlsWinSparkle = mlsRoot.querySelector(\"#mls-win-sparkle\");\n      const MLS_COLUMN_COUNT = 10;\n      const MLS_COMPLETED_TARGET = 8;\n      const MLS_INITIAL_SCORE = 500;\n      const MLS_HISTORY_LIMIT = 20;\n      const MLS_MUTE_KEY = \"moonloom_spider_muted_v1\";\n      const mlsModeMap = Object.freeze({ easy: 1, normal: 2, expert: 4 });\n      const mlsRankLabel = Object.freeze({ 1: \"A\", 11: \"J\", 12: \"Q\", 13: \"K\" });\n      const mlsState = {\n        mode: \"easy\",\n        tempMode: \"easy\",\n        started: false,\n        popup: \"start\",\n        popupSource: \"initial\",\n        gameOver: false,\n        score: MLS_INITIAL_SCORE,\n        moves: 0,\n        completed: 0,\n        columns: Array.from({ length: MLS_COLUMN_COUNT }, function () { return []; }),\n        stock: [],\n        initialDeck: null,\n        history: [],\n        selection: null,\n        hint: null,\n        muted: mlsSafeStorageGet(MLS_MUTE_KEY) === \"1\",\n        dealing: false,\n        recentFlipIds: new Set(),\n        recentDealIds: new Set(),\n        recentStacksSlots: new Set()\n      };\n      const mlsLayout = { cardW: 68, cardH: 94, offset: 24, stackInset: 10, stackTopInset: 6 };\n      let mlsAudioCtx = null;\n      let mlsMessageTimer = 0;\n      let mlsMessagePulseTimer = 0;\n      let mlsResizeTimer = 0;\n      let mlsHintTimer = 0;\n      let mlsDealAnimationTimer = 0;\n      let mlsCompleteAnimationTimer = 0;\n      let mlsDragCandidate = null;\n      let mlsDragFrame = 0;\n      let mlsLastPointer = { x: 0, y: 0 };\n      let mlsFallbackFullscreen = false;\n      function mlsSafeStorageGet(key) {\n        try { return localStorage.getItem(key); } catch (error) { return null; }\n      }\n      function mlsSafeStorageSet(key, value) {\n        try { localStorage.setItem(key, value); } catch (error) {}\n      }\n      function mlsRankName(rank) {\n        return mlsRankLabel[rank] || String(rank);\n      }\n      function mlsCloneCard(card) {\n        return { id: card.id, rank: card.rank, suit: card.suit, faceUp: !!card.faceUp };\n      }\n      function mlsCloneDeck(deck) {\n        return deck.map(mlsCloneCard);\n      }\n      function mlsSnapshot() {\n        return {\n          mode: mlsState.mode,\n          score: mlsState.score,\n          moves: mlsState.moves,\n          completed: mlsState.completed,\n          gameOver: mlsState.gameOver,\n          columns: mlsState.columns.map(function (col) { return col.map(mlsCloneCard); }),\n          stock: mlsState.stock.map(mlsCloneCard)\n        };\n      }\n      function mlsRestoreSnapshot(snapshot) {\n        mlsState.mode = snapshot.mode;\n        mlsState.score = snapshot.score;\n        mlsState.moves = snapshot.moves;\n        mlsState.completed = snapshot.completed;\n        mlsState.gameOver = snapshot.gameOver;\n        mlsState.columns = snapshot.columns.map(function (col) { return col.map(mlsCloneCard); });\n        mlsState.stock = snapshot.stock.map(mlsCloneCard);\n        mlsState.selection = null;\n        mlsState.hint = null;\n        mlsState.popup = null;\n        mlsState.dealing = false;\n        mlsState.recentFlipIds.clear();\n        mlsState.recentDealIds.clear();\n        mlsState.recentStacksSlots.clear();\n        clearTimeout(mlsHintTimer);\n        clearTimeout(mlsDealAnimationTimer);\n        clearTimeout(mlsCompleteAnimationTimer);\n        mlsRenderAll();\n      }\n      function mlsPushHistory() {\n        mlsState.history.push(mlsSnapshot());\n        if (mlsState.history.length > MLS_HISTORY_LIMIT) mlsState.history.shift();\n      }\n      function mlsBuildDeck(mode) {\n        const suitCount = mlsModeMap[mode] || 1;\n        const copiesPerSuit = 8 \/ suitCount;\n        const deck = [];\n        let idCount = 0;\n        for (let suit = 0; suit < suitCount; suit++) {\n          for (let copy = 0; copy < copiesPerSuit; copy++) {\n            for (let rank = 1; rank <= 13; rank++) {\n              deck.push({\n                id: \"mls-card-\" + mode + \"-\" + suit + \"-\" + copy + \"-\" + rank + \"-\" + idCount++,\n                rank: rank,\n                suit: suit,\n                faceUp: false\n              });\n            }\n          }\n        }\n        return deck;\n      }\n      function mlsShuffle(deck) {\n        const shuffled = mlsCloneDeck(deck);\n        for (let i = shuffled.length - 1; i > 0; i--) {\n          const j = Math.floor(Math.random() * (i + 1));\n          const temp = shuffled[i];\n          shuffled[i] = shuffled[j];\n          shuffled[j] = temp;\n        }\n        return shuffled;\n      }\n      function mlsStartGame(mode, deckOverride) {\n        const deck = deckOverride ? mlsCloneDeck(deckOverride) : mlsShuffle(mlsBuildDeck(mode));\n        if (!deckOverride) {\n          mlsState.initialDeck = mlsCloneDeck(deck);\n        }\n        mlsState.mode = mode;\n        mlsState.tempMode = mode;\n        mlsState.started = true;\n        mlsState.popup = null;\n        mlsState.popupSource = \"game\";\n        mlsState.gameOver = false;\n        mlsState.score = MLS_INITIAL_SCORE;\n        mlsState.moves = 0;\n        mlsState.completed = 0;\n        mlsState.history = [];\n        mlsState.selection = null;\n        mlsState.hint = null;\n        mlsState.dealing = false;\n        mlsState.recentFlipIds.clear();\n        mlsState.recentDealIds.clear();\n        mlsState.recentStacksSlots.clear();\n        clearTimeout(mlsHintTimer);\n        clearTimeout(mlsDealAnimationTimer);\n        clearTimeout(mlsCompleteAnimationTimer);\n        mlsState.columns = Array.from({ length: MLS_COLUMN_COUNT }, function () { return []; });\n        for (let col = 0; col < 10; col++) {\n          const count = col < 4 ? 6 : 5;\n          for (let i = 0; i < count; i++) {\n            const card = mlsCloneCard(deck.shift());\n            card.faceUp = i === count - 1;\n            mlsState.columns[col].push(card);\n          }\n        }\n        mlsState.stock = deck.map(function (card) {\n          const next = mlsCloneCard(card);\n          next.faceUp = false;\n          return next;\n        });\n        mlsShowMessage(\"Build same-suit moonlit trails from King down to Ace.\");\n        mlsPlaySound(\"start\");\n        mlsRenderAll();\n      }\n      function mlsRestartGame() {\n        if (!mlsState.initialDeck) {\n          mlsShowStartPopup(\"initial\");\n          return;\n        }\n        mlsStartGame(mlsState.mode, mlsState.initialDeck);\n        mlsShowMessage(\"The original moonlit tableau has been restored.\");\n      }\n      function mlsIsInteractive() {\n        return mlsState.started ? (!mlsState.popup ? (!mlsState.gameOver ? !mlsState.dealing : false) : false) : false;\n      }\n      function mlsCanMoveRun(colIndex, cardIndex) {\n        const col = mlsState.columns[colIndex];\n        const card = col ? col[cardIndex] : col;\n        if (!card || !card.faceUp) return false;\n        for (let i = cardIndex; i < col.length - 1; i++) {\n          const upper = col[i];\n          const lower = col[i + 1];\n          if (!upper.faceUp || !lower.faceUp) return false;\n          if (upper.suit !== lower.suit) return false;\n          if (upper.rank !== lower.rank + 1) return false;\n        }\n        return true;\n      }\n      function mlsCanPlace(card, destColIndex) {\n        const destCol = mlsState.columns[destColIndex];\n        if (!destCol) return false;\n        if (destCol.length === 0) return true;\n        const top = destCol[destCol.length - 1];\n        return top.faceUp ? top.rank === card.rank + 1 : false;\n      }\n      function mlsAutoFlip(colIndex) {\n        const col = mlsState.columns[colIndex];\n        if (!col || col.length === 0) return;\n        const top = col[col.length - 1];\n        if (!top.faceUp) {\n          top.faceUp = true;\n          mlsState.recentFlipIds.add(top.id);\n          mlsPlaySound(\"flip\");\n        }\n      }\n      function mlsAutoComplete() {\n        let completedNow = 0;\n        let found = true;\n        while (found) {\n          found = false;\n          for (let colIndex = 0; colIndex < 10; colIndex++) {\n            const col = mlsState.columns[colIndex];\n            if (col.length < 13) continue;\n            const start = col.length - 13;\n            const seq = col.slice(start);\n            const suit = seq[0].suit;\n            let valid = true;\n            for (let i = 0; i < 13; i++) {\n              if (!seq[i].faceUp || seq[i].suit !== suit || seq[i].rank !== 13 - i) {\n                valid = false;\n                break;\n              }\n            }\n            if (valid) {\n              const completedSlotIndex = mlsState.completed;\n              col.splice(start, 13);\n              mlsState.completed += 1;\n              mlsState.recentStacksSlots.add(completedSlotIndex);\n              mlsState.score += 100;\n              completedNow += 1;\n              found = true;\n              mlsAutoFlip(colIndex);\n              break;\n            }\n          }\n        }\n        if (completedNow > 0) {\n          clearTimeout(mlsCompleteAnimationTimer);\n          mlsCompleteAnimationTimer = setTimeout(function () {\n            mlsState.recentStacksSlots.clear();\n          }, 1050);\n          mlsShowMessage(\"A complete King-to-Ace trail has reached a glowing Mooncraft Tray.\");\n          mlsPlaySound(\"complete\");\n        }\n        return completedNow;\n      }\n      function mlsTryMove(srcCol, cardIndex, destCol) {\n        if (!mlsIsInteractive()) return false;\n        if (srcCol === destCol || destCol === null || destCol === undefined) return false;\n        if (!mlsCanMoveRun(srcCol, cardIndex)) return false;\n        const movingCard = mlsState.columns[srcCol][cardIndex];\n        if (!mlsCanPlace(movingCard, destCol)) return false;\n        mlsPushHistory();\n        const group = mlsState.columns[srcCol].splice(cardIndex);\n        mlsState.columns[destCol].push.apply(mlsState.columns[destCol], group);\n        mlsAutoFlip(srcCol);\n        mlsState.moves += 1;\n        mlsState.score = Math.max(0, mlsState.score - 1);\n        mlsState.selection = null;\n        mlsState.hint = null;\n        mlsPlaySound(\"move\");\n        mlsAutoComplete();\n        mlsRenderAll();\n        mlsCheckEndState();\n        return true;\n      }\n      function mlsDealStock() {\n        if (!mlsIsInteractive() || mlsState.dealing) return;\n        if (mlsState.stock.length < 10) {\n          mlsShowMessage(\"The final mooncell reserve has already been dealt.\");\n          mlsPlaySound(\"error\");\n          return;\n        }\n        for (let i = 0; i < 10; i++) {\n          if (mlsState.columns[i].length === 0) {\n            mlsShowMessage(\"Fill every empty tableau column before dealing again.\");\n            mlsStockPile.classList.remove(\"mls-stock-shake\");\n            void mlsStockPile.offsetWidth;\n            mlsStockPile.classList.add(\"mls-stock-shake\");\n            mlsPlaySound(\"error\");\n            return;\n          }\n        }\n        mlsState.dealing = true;\n        mlsRenderStock();\n        mlsPushHistory();\n        const dealtIds = [];\n        for (let i = 0; i < 10; i++) {\n          const card = mlsCloneCard(mlsState.stock.shift());\n          card.faceUp = true;\n          mlsState.columns[i].push(card);\n          dealtIds.push(card.id);\n        }\n        mlsState.recentDealIds = new Set(dealtIds);\n        clearTimeout(mlsDealAnimationTimer);\n        mlsState.moves += 1;\n        mlsState.score = Math.max(0, mlsState.score - 1);\n        mlsState.selection = null;\n        mlsState.hint = null;\n        mlsShowMessage(\"The mooncell reserve places one card in every tableau column.\");\n        mlsPlaySound(\"deal\");\n        mlsAutoComplete();\n        mlsRenderAll();\n        mlsState.recentDealIds.clear();\n        mlsDealAnimationTimer = setTimeout(function () {\n          mlsState.dealing = false;\n          mlsRenderStock();\n        }, 620);\n        mlsCheckEndState();\n      }\n      function mlsHasAnyMove() {\n        for (let src = 0; src < 10; src++) {\n          const col = mlsState.columns[src];\n          for (let index = 0; index < col.length; index++) {\n            if (!mlsCanMoveRun(src, index)) continue;\n            const card = col[index];\n            for (let dest = 0; dest < 10; dest++) {\n              if (dest === src) continue;\n              if (mlsCanPlace(card, dest)) return true;\n            }\n          }\n        }\n        return false;\n      }\n      function mlsCheckEndState() {\n        if (mlsState.completed >= MLS_COMPLETED_TARGET) {\n          mlsState.gameOver = true;\n            mlsState.score += 200;\n          mlsRenderAll();\n          mlsShowWinPopup();\n          mlsSparkleBurst();\n          mlsPlaySound(\"win\");\n          return;\n        }\n        if (mlsState.stock.length === 0 ? !mlsHasAnyMove() : false) {\n          mlsState.gameOver = true;\n          mlsRenderAll();\n          mlsShowNoStepsPopup();\n        }\n      }\n      function mlsUndo() {\n        if (!mlsState.started || mlsState.history.length === 0) {\n          mlsShowMessage(\"There is no moonlit move available to undo.\");\n          mlsPlaySound(\"error\");\n          return;\n        }\n        const snapshot = mlsState.history.pop();\n        mlsRestoreSnapshot(snapshot);\n        mlsShowMessage(\"The previous moonlit move has been restored.\");\n        mlsPlaySound(\"undo\");\n      }\n      function mlsFindHint() {\n        for (let pass = 0; pass < 2; pass++) {\n          for (let src = 0; src < 10; src++) {\n            const col = mlsState.columns[src];\n            for (let index = col.length - 1; index >= 0; index--) {\n              if (!mlsCanMoveRun(src, index)) continue;\n              const card = col[index];\n              for (let dest = 0; dest < 10; dest++) {\n                if (dest === src) continue;\n                const destEmpty = mlsState.columns[dest].length === 0;\n                if (pass === 0 ? destEmpty : false) continue;\n                if (pass === 1 ? !destEmpty : false) continue;\n                if (mlsCanPlace(card, dest)) {\n                  return { src: src, index: index, dest: dest };\n                }\n              }\n            }\n          }\n        }\n        return null;\n      }\n      function mlsHint() {\n        if (!mlsIsInteractive()) return;\n        const hint = mlsFindHint();\n        if (!hint) {\n          mlsState.hint = null;\n          mlsShowMessage(\"No useful moonlit move is available right now.\");\n          mlsPlaySound(\"error\");\n          mlsRenderAll();\n          return;\n        }\n        mlsState.hint = hint;\n        mlsShowMessage(\"Two moon-gold glows are highlighting a useful move.\");\n        mlsPlaySound(\"hint\");\n        mlsRenderAll();\n        clearTimeout(mlsHintTimer);\n        mlsHintTimer = setTimeout(function () {\n          mlsState.hint = null;\n          mlsRenderAll();\n        }, 1600);\n      }\n      function mlsSelectRun(col, index) {\n        if (!mlsCanMoveRun(col, index)) {\n          mlsShowMessage(\"Those cards cannot follow that moonlit trail.\");\n          mlsPlaySound(\"error\");\n          return;\n        }\n        const current = mlsState.selection;\n        if (current ? (current.col === col ? current.index === index : false) : false) {\n          mlsState.selection = null;\n        } else {\n          mlsState.selection = { col: col, index: index };\n          mlsPlaySound(\"click\");\n        }\n        mlsState.hint = null;\n        mlsRenderAll();\n      }\n      function mlsHandleCardTap(col, index) {\n        if (!mlsIsInteractive()) return;\n        const selected = mlsState.selection;\n        if (selected ? selected.col !== col : false) {\n          if (mlsTryMove(selected.col, selected.index, col)) return;\n          if (mlsCanMoveRun(col, index)) {\n            mlsSelectRun(col, index);\n          } else {\n            mlsShowMessage(\"Those cards cannot follow that moonlit trail.\");\n            mlsPlaySound(\"error\");\n          }\n          return;\n        }\n        mlsSelectRun(col, index);\n      }\n      function mlsHandleColumnTap(col) {\n        if (!mlsIsInteractive() || !mlsState.selection) return;\n        const selected = mlsState.selection;\n        if (!mlsTryMove(selected.col, selected.index, col)) {\n          mlsShowMessage(\"Those cards cannot follow that moonlit trail.\");\n          mlsPlaySound(\"error\");\n        }\n      }\n      function mlsSyncViewportMode() {\n        const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement;\n        const viewport = window.visualViewport;\n        const viewportWidth = Math.max(1, viewport ? (viewport.width ? viewport.width : window.innerWidth) : window.innerWidth);\n        const viewportHeight = Math.max(1, viewport ? (viewport.height ? viewport.height : window.innerHeight) : window.innerHeight);\n        const viewportOffsetLeft = viewport ? (Number.isFinite(viewport.offsetLeft) ? viewport.offsetLeft : 0) : 0;\n        const viewportOffsetTop = viewport ? (Number.isFinite(viewport.offsetTop) ? viewport.offsetTop : 0) : 0;\n        const shellWidth = Math.min(viewportWidth, viewportHeight * (16 \/ 9));\n        const shellHeight = Math.min(viewportHeight, viewportWidth * (9 \/ 16));\n        const centerX = viewportOffsetLeft + (viewportWidth \/ 2);\n        const centerY = viewportOffsetTop + (viewportHeight \/ 2);\n        const isStandaloneFullscreen = window.matchMedia ? window.matchMedia(\"(display-mode: fullscreen)\").matches : false;\n        const nativeFullscreen = fullscreenElement === mlsRoot || fullscreenElement === mlsShell;\n        const browserFullscreen = !fullscreenElement ? !!isStandaloneFullscreen : false;\n        const fullscreenLike = nativeFullscreen || browserFullscreen || mlsFallbackFullscreen;\n\n        mlsRoot.style.setProperty(\"--mls-fs-vw\", viewportWidth + \"px\");\n        mlsRoot.style.setProperty(\"--mls-fs-vh\", viewportHeight + \"px\");\n        mlsRoot.style.setProperty(\"--mls-fs-shell-w\", shellWidth + \"px\");\n        mlsRoot.style.setProperty(\"--mls-fs-shell-h\", shellHeight + \"px\");\n        mlsRoot.style.setProperty(\"--mls-fs-center-x\", centerX + \"px\");\n        mlsRoot.style.setProperty(\"--mls-fs-center-y\", centerY + \"px\");\n        mlsRoot.classList.toggle(\"mls-browser-fullscreen\", !!browserFullscreen);\n        mlsRoot.classList.toggle(\"mls-landscape-fullscreen\", !!fullscreenLike);\n        mlsRoot.classList.toggle(\"mls-fallback-fullscreen\", !!mlsFallbackFullscreen);\n      }\n      function mlsRenderAll() {\n        mlsSyncViewportMode();\n        mlsUpdateLayout();\n        mlsRenderStats();\n        mlsRenderStacks();\n        mlsRenderStock();\n        mlsRenderTableau();\n        mlsRenderPopup();\n        mlsUpdateSoundButton();\n      }\n      function mlsRenderStats() {\n        const visibleDraws = mlsState.started ? Math.floor(mlsState.stock.length \/ 10) : 5;\n        mlsPointsValue.textContent = String(mlsState.score);\n        mlsStepsValue.textContent = String(mlsState.moves);\n        mlsStacksValue.textContent = mlsState.completed + \"\/\" + MLS_COMPLETED_TARGET;\n        mlsDrawsValue.textContent = String(visibleDraws);\n      }\n      function mlsRenderStacks() {\n        let html = \"\";\n        for (let i = 0; i < MLS_COMPLETED_TARGET; i++) {\n          const filled = i < mlsState.completed;\n          const isNew = mlsState.recentStacksSlots.has(i);\n          html += '<span class=\"mls-completed-slot' +\n            (filled ? \" mls-completed-filled\" : \"\") +\n            (isNew ? \" mls-completed-new\" : \"\") +\n            '\">';\n          if (filled) {\n            html += '<span class=\"mls-completed-card-stack\" aria-hidden=\"true\">' +\n              '<span class=\"mls-completed-card\"><\/span>' +\n              '<span class=\"mls-completed-card\"><\/span>' +\n              '<span class=\"mls-completed-card\"><\/span>' +\n              '<\/span>';\n          }\n          html += '<span class=\"mls-slot-bloom\"><\/span><\/span>';\n        }\n        mlsStacksSlots.innerHTML = html;\n      }\n      function mlsSuitThemeClass(suit) {\n        return [\"mls-suit-rabbit\", \"mls-suit-mochi\", \"mls-suit-cloud\", \"mls-suit-mallet\"][suit] || \"mls-suit-rabbit\";\n      }\n      function mlsBuildSuitMarkup(suit, small) {\n        return '<span class=\"mls-suit mls-suit-shape ' + mlsSuitThemeClass(suit) + (small ? ' small' : '') + '\"><\/span>';\n      }\n      function mlsRenderStock() {\n        const deals = mlsState.started ? Math.floor(mlsState.stock.length \/ 10) : 5;\n        const stockDisabled = mlsState.started ? (deals <= 0 || mlsState.dealing) : false;\n        mlsStockPile.classList.toggle(\"mls-stock-empty\", mlsState.started ? deals <= 0 : false);\n        mlsStockPile.classList.toggle(\"mls-stock-dealing\", !!mlsState.dealing);\n        mlsStockPile.disabled = stockDisabled;\n        mlsStockPile.setAttribute(\"aria-disabled\", stockDisabled ? \"true\" : \"false\");\n      }\n      function mlsBuildCardInner(card) {\n        if (!card.faceUp) return \"\";\n        const rank = mlsRankName(card.rank);\n        const suitSmall = mlsBuildSuitMarkup(card.suit, true);\n        const suitCenter = mlsBuildSuitMarkup(card.suit, false);\n        return (\n          '<div class=\"mls-card-corner\">' +\n            '<span class=\"mls-card-rank\">' + rank + '<\/span>' +\n            suitSmall +\n          '<\/div>' +\n          '<div class=\"mls-card-watermark\">' + suitCenter + '<\/div>' +\n          '<div class=\"mls-card-corner mls-card-corner-bottom\">' +\n            '<span class=\"mls-card-rank\">' + rank + '<\/span>' +\n            suitSmall +\n          '<\/div>'\n        );\n      }\n      function mlsRenderTableau() {\n        const selected = mlsState.selection;\n        const hint = mlsState.hint;\n        let html = \"\";\n        for (let col = 0; col < 10; col++) {\n          const targetHint = hint ? hint.dest === col : false;\n          html += '<div class=\"mls-column' + (targetHint ? \" mls-column-hint-target\" : \"\") + '\" data-mls-col=\"' + col + '\">';\n          const column = mlsState.columns[col];\n          for (let index = 0; index < column.length; index++) {\n            const card = column[index];\n            const isSelected = selected ? (selected.col === col ? index >= selected.index : false) : false;\n            const isHint = hint ? (hint.src === col ? index >= hint.index : false) : false;\n            const isFlip = mlsState.recentFlipIds.has(card.id);\n            const isDeal = mlsState.recentDealIds.has(card.id);\n            const faceClass = card.faceUp ? \"mls-card-front\" : \"mls-card-back\";\n            const dealDelay = isDeal ? \"; --mls-deal-delay:\" + (col * 34) + \"ms\" : \"\";\n            html +=\n              '<div class=\"mls-card ' + faceClass +\n              (card.faceUp ? ' mls-card-suit-' + card.suit : '') +\n              (isSelected ? \" mls-card-selected\" : \"\") +\n              (isHint ? \" mls-card-hint\" : \"\") +\n              (isFlip ? \" mls-card-flip\" : \"\") +\n              (isDeal ? \" mls-card-deal-in\" : \"\") +\n              '\" data-mls-card-id=\"' + card.id +\n              '\" data-mls-col=\"' + col +\n              '\" data-mls-index=\"' + index +\n              '\" style=\"top:' + (mlsLayout.stackTopInset + (index * mlsLayout.offset)) + 'px; z-index:' + (index + 2) + dealDelay + ';\" role=\"button\" aria-label=\"' +\n              (card.faceUp ? mlsRankName(card.rank) + \" card\" : \"Face down card\") +\n              '\">' + mlsBuildCardInner(card) + '<\/div>';\n          }\n          html += \"<\/div>\";\n        }\n        mlsTableau.innerHTML = html;\n        if (mlsState.recentFlipIds.size) {\n          setTimeout(function () {\n            mlsState.recentFlipIds.clear();\n          }, 260);\n        }\n      }\n      function mlsShowMessage(text) {\n        clearTimeout(mlsMessageTimer);\n        clearTimeout(mlsMessagePulseTimer);\n        mlsMessageBar.textContent = text;\n        mlsMessageBar.classList.remove(\"mls-message-pulse\");\n        mlsMessageBar.classList.add(\"mls-message-visible\");\n        void mlsMessageBar.offsetWidth;\n        mlsMessageBar.classList.add(\"mls-message-pulse\");\n        mlsMessagePulseTimer = setTimeout(function () {\n          mlsMessageBar.classList.remove(\"mls-message-pulse\");\n        }, 360);\n        mlsMessageTimer = setTimeout(function () {\n          mlsMessageBar.classList.remove(\"mls-message-visible\");\n        }, 2200);\n      }\n      function mlsShowStartPopup(source) {\n        mlsState.popup = \"start\";\n        mlsState.popupSource = source || \"game\";\n        mlsState.tempMode = mlsState.mode || \"easy\";\n        mlsRenderPopup();\n      }\n      function mlsShowPausePopup() {\n        if (!mlsState.started || mlsState.popup || mlsState.gameOver) return;\n        mlsState.popup = \"pause\";\n        mlsState.popupSource = \"game\";\n        mlsRenderPopup();\n        mlsPlaySound(\"click\");\n      }\n      function mlsShowWinPopup() {\n        mlsState.popup = \"win\";\n        mlsState.popupSource = \"win\";\n        mlsRenderPopup();\n      }\n      function mlsShowNoStepsPopup() {\n        mlsState.popup = \"nomoves\";\n        mlsState.popupSource = \"nomoves\";\n        mlsRenderPopup();\n        mlsPlaySound(\"error\");\n      }\n      function mlsHidePopup() {\n        mlsState.popup = null;\n        mlsRenderPopup();\n      }\n      function mlsRenderPopup() {\n        if (!mlsState.popup) {\n          mlsPopupOverlay.classList.remove(\"mls-popup-visible\");\n          mlsShell.classList.remove(\"mls-overlay-ui\");\n          mlsPopup.innerHTML = \"\";\n          return;\n        }\n        mlsPopupOverlay.classList.add(\"mls-popup-visible\");\n        mlsShell.classList.add(\"mls-overlay-ui\");\n        if (mlsState.popup === \"start\") {\n          const showCancel = mlsState.popupSource !== \"initial\";\n          const mode = mlsState.tempMode || \"easy\";\n          mlsPopup.innerHTML =\n            '<h2 class=\"mls-popup-title\">Moonloom Spider<\/h2>' +\n            '<p class=\"mls-popup-subtitle\">Moon Rabbit Workshop Spider Solitaire<\/p>' +\n            '<p class=\"mls-popup-note\">Build descending same-suit moonlit trails from King to Ace and guide all eight completed sequences into the Mooncraft Trays.<\/p>' +\n            '<div class=\"mls-popup-actions mls-popup-actions-short\">' +\n              '<button class=\"mls-popup-button mls-popup-start mls-popup-button-short\" type=\"button\" data-mls-action=\"start-selected\">Open the Moonlit Table<\/button>' +\n            '<\/div>' +\n            '<div class=\"mls-mode-row\">' +\n              mlsModeButton(\"easy\", \"Easy\", mode) +\n              mlsModeButton(\"normal\", \"Normal\", mode) +\n              mlsModeButton(\"expert\", \"Expert\", mode) +\n            '<\/div>' +\n            (showCancel\n              ? '<div class=\"mls-popup-actions mls-popup-actions-short\"><button class=\"mls-popup-button mls-popup-cancel mls-popup-button-short\" type=\"button\" data-mls-action=\"cancel-start\">Cancel<\/button><\/div>'\n              : \"\");\n          return;\n        }\n        if (mlsState.popup === \"pause\") {\n          mlsPopup.innerHTML =\n            '<h2 class=\"mls-popup-title\">The Workshop Rests<\/h2>' +\n            '<p class=\"mls-popup-note\">Your tableau remains safe while the Moon Rabbit Workshop rests beneath the drifting clouds.<\/p>' +\n            '<div class=\"mls-popup-actions\">' +\n              '<button class=\"mls-popup-button\" type=\"button\" data-mls-action=\"resume\">Resume Game<\/button>' +\n              '<button class=\"mls-popup-button mls-popup-secondary\" type=\"button\" data-mls-action=\"new-game\">New Game<\/button>' +\n            '<\/div>';\n          return;\n        }\n        if (mlsState.popup === \"win\") {\n          mlsPopup.innerHTML =\n            '<h2 class=\"mls-popup-title\">Every Mooncraft Tray Is Complete<\/h2>' +\n            '<p class=\"mls-popup-note\">All eight King-to-Ace trails now rest inside the glowing Mooncraft Trays.<\/p>' +\n            mlsPopupStats() +\n            '<div class=\"mls-popup-actions\">' +\n              '<button class=\"mls-popup-button\" type=\"button\" data-mls-action=\"new-game-from-win\">New Game<\/button>' +\n              '<button class=\"mls-popup-button mls-popup-secondary\" type=\"button\" data-mls-action=\"restart\">Restart<\/button>' +\n            '<\/div>';\n          return;\n        }\n        if (mlsState.popup === \"nomoves\") {\n          mlsPopup.innerHTML =\n            '<h2 class=\"mls-popup-title\">No More Moonlit Moves<\/h2>' +\n            '<p class=\"mls-popup-note\">No legal move remains among the tableau columns.<\/p>' +\n            '<div class=\"mls-popup-actions\">' +\n              '<button class=\"mls-popup-button\" type=\"button\" data-mls-action=\"new-game-from-nomoves\">New Game<\/button>' +\n              '<button class=\"mls-popup-button mls-popup-secondary\" type=\"button\" data-mls-action=\"restart\">Restart<\/button>' +\n            '<\/div>';\n        }\n      }\n      function mlsModeButton(mode, label, activeMode) {\n        return '<button class=\"mls-mode-pill' + (mode === activeMode ? \" mls-mode-active\" : \"\") + '\" type=\"button\" data-mls-action=\"set-mode\" data-mls-mode=\"' + mode + '\">' + label + '<\/button>';\n      }\n      function mlsPopupStats() {\n        return (\n          '<div class=\"mls-popup-stats\">' +\n            '<div class=\"mls-popup-stat\"><span>Score<\/span><strong>' + mlsState.score + '<\/strong><\/div>' +\n            '<div class=\"mls-popup-stat\"><span>Moves<\/span><strong>' + mlsState.moves + '<\/strong><\/div>' +\n            '<div class=\"mls-popup-stat\"><span>Completed<\/span><strong>' + mlsState.completed + '\/8<\/strong><\/div>' +\n          '<\/div>'\n        );\n      }\n      function mlsUpdateLayout() {\n        const rect = mlsTableau.getBoundingClientRect();\n        if (!rect.width || !rect.height) return;\n        const maxLen = Math.max(6, mlsState.columns.reduce(function (max, col) {\n          return Math.max(max, col.length);\n        }, 0));\n        const sidePadding = Math.max(12, Math.min(20, rect.width * 0.013));\n        const gapEstimate = Math.max(4, Math.min(9, rect.width * 0.0054));\n        const usableWidth = Math.max(280, rect.width - sidePadding * 2);\n        const columnWidth = (usableWidth - gapEstimate * 9) \/ 10;\n        const cardW = Math.floor(Math.max(28, Math.min(146, columnWidth * 0.96)));\n        const cardH = Math.floor(cardW * 1.38);\n        const stackInset = Math.max(8, Math.min(14, Math.round((columnWidth - cardW) \/ 2)));\n        const stackTopInset = Math.max(4, Math.min(8, Math.round(stackInset * 0.62)));\n        let offset = Math.floor(cardW * 0.22);\n        if (maxLen > 1) {\n          offset = Math.floor(Math.min(offset, (rect.height - stackTopInset - cardH - 6) \/ (maxLen - 1)));\n        }\n        offset = Math.max(6, Math.min(offset, Math.floor(cardW * 0.27)));\n        mlsLayout.cardW = cardW;\n        mlsLayout.cardH = cardH;\n        mlsLayout.offset = offset;\n        mlsLayout.stackInset = stackInset;\n        mlsLayout.stackTopInset = stackTopInset;\n        mlsRoot.style.setProperty(\"--mls-card-w\", cardW + \"px\");\n        mlsRoot.style.setProperty(\"--mls-card-h\", cardH + \"px\");\n        mlsRoot.style.setProperty(\"--mls-stack-inset\", stackInset + \"px\");\n        mlsRoot.style.setProperty(\"--mls-stack-top-inset\", stackTopInset + \"px\");\n      }\n      function mlsQueueResize() {\n        clearTimeout(mlsResizeTimer);\n        mlsResizeTimer = setTimeout(function () {\n          mlsRenderAll();\n        }, 80);\n      }\n      function mlsGetColumnFromPoint(x, y) {\n        const element = document.elementFromPoint(x, y);\n        if (!element) return null;\n        const colEl = element.closest(\"#moonloom-spider-game .mls-column\");\n        if (!colEl) return null;\n        return Number(colEl.dataset.mlsCol);\n      }\n      function mlsClearDragClasses() {\n        mlsRoot.querySelectorAll(\".mls-column-valid, .mls-column-invalid\").forEach(function (el) {\n          el.classList.remove(\"mls-column-valid\", \"mls-column-invalid\");\n        });\n        mlsRoot.querySelectorAll(\".mls-card-drag-source\").forEach(function (el) {\n          el.classList.remove(\"mls-card-drag-source\");\n        });\n      }\n      function mlsStartDrag(pointerEvent) {\n        const candidate = mlsDragCandidate;\n        if (!candidate) return;\n        const group = mlsState.columns[candidate.src].slice(candidate.index);\n        const cardRect = candidate.cardEl.getBoundingClientRect();\n        candidate.dragging = true;\n        candidate.grabX = candidate.startX - cardRect.left;\n        candidate.grabY = candidate.startY - cardRect.top;\n        let html = \"\";\n        for (let i = 0; i < group.length; i++) {\n          const card = group[i];\n          html +=\n            '<div class=\"mls-card mls-card-front mls-card-suit-' + card.suit + '\" style=\"top:' + (i * mlsLayout.offset) + 'px; z-index:' + (i + 2) + ';\">' +\n            mlsBuildCardInner(card) +\n            '<\/div>';\n        }\n        mlsDragGhost.innerHTML = html;\n        mlsDragGhost.style.height = (mlsLayout.cardH + (group.length - 1) * mlsLayout.offset) + \"px\";\n        mlsDragGhost.classList.add(\"mls-drag-active\");\n        group.forEach(function (card) {\n          const original = mlsRoot.querySelector('[data-mls-card-id=\"' + card.id + '\"]');\n          if (original) original.classList.add(\"mls-card-drag-source\");\n        });\n        mlsUpdateDragGhost(pointerEvent.clientX, pointerEvent.clientY);\n      }\n      function mlsUpdateDragGhost(x, y) {\n        if (!mlsDragCandidate || !mlsDragCandidate.dragging) return;\n        mlsLastPointer.x = x;\n        mlsLastPointer.y = y;\n        if (mlsDragFrame) return;\n        mlsDragFrame = requestAnimationFrame(function () {\n          mlsDragFrame = 0;\n          const candidate = mlsDragCandidate;\n          if (!candidate || !candidate.dragging) return;\n          const left = mlsLastPointer.x - candidate.grabX;\n          const top = mlsLastPointer.y - candidate.grabY;\n          mlsDragGhost.style.transform = \"translate3d(\" + left + \"px,\" + top + \"px,0)\";\n          mlsClearDragColumnState();\n          const target = mlsGetColumnFromPoint(mlsLastPointer.x, mlsLastPointer.y);\n          if (target === null || target === candidate.src) return;\n          const colEl = mlsRoot.querySelector('.mls-column[data-mls-col=\"' + target + '\"]');\n          if (!colEl) return;\n          const movingCard = mlsState.columns[candidate.src][candidate.index];\n          colEl.classList.add(mlsCanPlace(movingCard, target) ? \"mls-column-valid\" : \"mls-column-invalid\");\n        });\n      }\n      function mlsClearDragColumnState() {\n        mlsRoot.querySelectorAll(\".mls-column-valid, .mls-column-invalid\").forEach(function (el) {\n          el.classList.remove(\"mls-column-valid\", \"mls-column-invalid\");\n        });\n      }\n      function mlsEndDrag() {\n        mlsDragGhost.classList.remove(\"mls-drag-active\");\n        mlsDragGhost.innerHTML = \"\";\n        mlsDragGhost.style.transform = \"\";\n        mlsClearDragClasses();\n        mlsDragCandidate = null;\n      }\n      function mlsOnPointerDown(event) {\n        const cardEl = event.target.closest(\"#moonloom-spider-game .mls-card\");\n        if (!cardEl || !mlsIsInteractive()) return;\n        if (!cardEl.classList.contains(\"mls-card-front\")) return;\n        if (event.button !== undefined ? event.button !== 0 : false) return;\n        const src = Number(cardEl.dataset.mlsCol);\n        const index = Number(cardEl.dataset.mlsIndex);\n        if (!mlsCanMoveRun(src, index)) {\n          mlsShowMessage(\"Those cards cannot follow that moonlit trail.\");\n          mlsPlaySound(\"error\");\n          return;\n        }\n        event.preventDefault();\n        mlsDragCandidate = {\n          pointerId: event.pointerId,\n          src: src,\n          index: index,\n          cardEl: cardEl,\n          startX: event.clientX,\n          startY: event.clientY,\n          dragging: false,\n          grabX: 0,\n          grabY: 0\n        };\n        document.addEventListener(\"pointermove\", mlsOnPointerMove, { passive: false });\n        document.addEventListener(\"pointerup\", mlsOnPointerUp, { passive: false });\n        document.addEventListener(\"pointercancel\", mlsOnPointerCancel, { passive: false });\n      }\n      function mlsOnPointerMove(event) {\n        if (!mlsDragCandidate || event.pointerId !== mlsDragCandidate.pointerId) return;\n        const dx = event.clientX - mlsDragCandidate.startX;\n        const dy = event.clientY - mlsDragCandidate.startY;\n        if (!mlsDragCandidate.dragging ? Math.hypot(dx, dy) > 7 : false) {\n          mlsStartDrag(event);\n        }\n        if (mlsDragCandidate.dragging) {\n          event.preventDefault();\n          mlsUpdateDragGhost(event.clientX, event.clientY);\n        }\n      }\n      function mlsOnPointerUp(event) {\n        if (!mlsDragCandidate || event.pointerId !== mlsDragCandidate.pointerId) return;\n        event.preventDefault();\n        const candidate = mlsDragCandidate;\n        if (candidate.dragging) {\n          const target = mlsGetColumnFromPoint(event.clientX, event.clientY);\n          if (target === null || !mlsTryMove(candidate.src, candidate.index, target)) {\n            mlsShowMessage(\"Those cards cannot follow that moonlit trail.\");\n            mlsPlaySound(\"error\");\n          }\n        } else {\n          mlsHandleCardTap(candidate.src, candidate.index);\n        }\n        mlsRemovePointerListeners();\n        mlsEndDrag();\n      }\n      function mlsOnPointerCancel() {\n        mlsRemovePointerListeners();\n        mlsEndDrag();\n      }\n      function mlsRemovePointerListeners() {\n        document.removeEventListener(\"pointermove\", mlsOnPointerMove);\n        document.removeEventListener(\"pointerup\", mlsOnPointerUp);\n        document.removeEventListener(\"pointercancel\", mlsOnPointerCancel);\n      }\n      function mlsHandleClick(event) {\n        const actionEl = event.target.closest(\"#moonloom-spider-game [data-mls-action]\");\n        if (actionEl) {\n          const action = actionEl.dataset.mlsAction;\n          mlsHandleAction(action, actionEl);\n          return;\n        }\n        const cardEl = event.target.closest(\"#moonloom-spider-game .mls-card\");\n        if (cardEl) return;\n        const colEl = event.target.closest(\"#moonloom-spider-game .mls-column\");\n        if (colEl) {\n          mlsHandleColumnTap(Number(colEl.dataset.mlsCol));\n        }\n      }\n      function mlsHandleAction(action, element) {\n        mlsEnsureAudio();\n        if (action === \"pause\") {\n          mlsShowPausePopup();\n          return;\n        }\n        if (action === \"sound\") {\n          mlsState.muted = !mlsState.muted;\n          mlsSafeStorageSet(MLS_MUTE_KEY, mlsState.muted ? \"1\" : \"0\");\n          mlsUpdateSoundButton();\n          mlsPlaySound(\"click\");\n          return;\n        }\n        if (action === \"fullscreen\") {\n          mlsToggleFullscreen();\n          return;\n        }\n        if (action === \"stock\") {\n          mlsDealStock();\n          return;\n        }\n        if (action === \"new-game\") {\n          mlsShowStartPopup(mlsState.started ? \"game\" : \"initial\");\n          mlsPlaySound(\"click\");\n          return;\n        }\n        if (action === \"new-game-from-win\") {\n          mlsShowStartPopup(\"win\");\n          mlsPlaySound(\"click\");\n          return;\n        }\n        if (action === \"new-game-from-nomoves\") {\n          mlsShowStartPopup(\"nomoves\");\n          mlsPlaySound(\"click\");\n          return;\n        }\n        if (action === \"restart\") {\n          mlsRestartGame();\n          return;\n        }\n        if (action === \"undo\") {\n          mlsUndo();\n          return;\n        }\n        if (action === \"hint\") {\n          mlsHint();\n          return;\n        }\n        if (action === \"resume\") {\n          mlsHidePopup();\n          mlsShowMessage(\"Build same-suit moonlit trails from King down to Ace.\");\n          mlsPlaySound(\"click\");\n          return;\n        }\n        if (action === \"set-mode\") {\n          mlsState.tempMode = element.dataset.mlsMode || \"easy\";\n          mlsRenderPopup();\n          mlsPlaySound(\"click\");\n          return;\n        }\n        if (action === \"start-selected\") {\n          mlsStartGame(mlsState.tempMode || \"easy\");\n          return;\n        }\n        if (action === \"cancel-start\") {\n          mlsCancelStartPopup();\n        }\n      }\n      function mlsCancelStartPopup() {\n        const source = mlsState.popupSource;\n        if (source === \"win\") {\n          mlsShowWinPopup();\n          return;\n        }\n        if (source === \"nomoves\") {\n          mlsShowNoStepsPopup();\n          return;\n        }\n        if (source === \"game\") {\n          mlsHidePopup();\n          mlsShowMessage(\"Build same-suit moonlit trails from King down to Ace.\");\n        }\n      }\n      function mlsUpdateSoundButton() {\n        mlsSoundButton.classList.toggle(\"mls-muted\", mlsState.muted);\n        mlsSoundButton.setAttribute(\"aria-label\", mlsState.muted ? \"Unmute sound\" : \"Mute sound\");\n      }\n      function mlsEnsureAudio() {\n        if (mlsState.muted) return null;\n        try {\n          if (!mlsAudioCtx) {\n            const AudioContextClass = window.AudioContext || window.webkitAudioContext;\n            if (!AudioContextClass) return null;\n            mlsAudioCtx = new AudioContextClass();\n          }\n          if (mlsAudioCtx.state === \"suspended\") {\n            mlsAudioCtx.resume();\n          }\n          return mlsAudioCtx;\n        } catch (error) {\n          return null;\n        }\n      }\n      function mlsPlaySound(type) {\n        if (mlsState.muted) return;\n        const ctx = mlsEnsureAudio();\n        if (!ctx) return;\n        const now = ctx.currentTime;\n        const patterns = {\n          click: [[560.00, 0.00, 0.08, 0.022]],\n          start: [[420.00, 0.00, 0.16, 0.030], [560.00, 0.07, 0.18, 0.027], [720.00, 0.14, 0.22, 0.024]],\n          move: [[360.00, 0.00, 0.12, 0.024]],\n          flip: [[640.00, 0.00, 0.09, 0.022]],\n          deal: [[300.00, 0.00, 0.12, 0.022], [420.00, 0.05, 0.13, 0.020]],\n          complete: [[560.00, 0.00, 0.20, 0.030], [740.00, 0.08, 0.22, 0.027], [940.00, 0.16, 0.26, 0.024]],\n          hint: [[760.00, 0.00, 0.16, 0.022], [980.00, 0.07, 0.18, 0.019]],\n          undo: [[460.00, 0.00, 0.12, 0.022], [350.00, 0.06, 0.14, 0.019]],\n          error: [[210.00, 0.00, 0.16, 0.025], [170.00, 0.07, 0.18, 0.018]],\n          win: [[440.00, 0.00, 0.24, 0.030], [600.00, 0.08, 0.26, 0.028], [780.00, 0.16, 0.28, 0.026], [1020.00, 0.25, 0.34, 0.023]]\n        };\n        const notes = patterns[type] || patterns.click;\n        notes.forEach(function (note) {\n          const frequency = note[0];\n          const delay = note[1];\n          const duration = note[2];\n          const volume = note[3];\n          const startAt = now + delay;\n          const endAt = startAt + duration;\n          const filter = ctx.createBiquadFilter();\n          const gain = ctx.createGain();\n          const fundamental = ctx.createOscillator();\n          const harmonic = ctx.createOscillator();\n          filter.type = \"lowpass\";\n          filter.frequency.setValueAtTime(type === \"error\" ? 980 : 2300, startAt);\n          filter.Q.setValueAtTime(0.55, startAt);\n          fundamental.type = type === \"error\" ? \"triangle\" : \"sine\";\n          harmonic.type = \"triangle\";\n          fundamental.frequency.setValueAtTime(frequency, startAt);\n          harmonic.frequency.setValueAtTime(frequency * 2.01, startAt);\n          const harmonicGain = ctx.createGain();\n          harmonicGain.gain.setValueAtTime(volume * 0.17, startAt);\n          harmonicGain.gain.exponentialRampToValueAtTime(0.0001, startAt + duration * 0.62);\n          gain.gain.setValueAtTime(0.0001, startAt);\n          gain.gain.exponentialRampToValueAtTime(volume, startAt + 0.008);\n          gain.gain.exponentialRampToValueAtTime(Math.max(0.0002, volume * 0.22), startAt + duration * 0.34);\n          gain.gain.exponentialRampToValueAtTime(0.0001, endAt);\n          fundamental.connect(gain);\n          harmonic.connect(harmonicGain);\n          harmonicGain.connect(filter);\n          gain.connect(filter);\n          filter.connect(ctx.destination);\n          fundamental.start(startAt);\n          harmonic.start(startAt);\n          fundamental.stop(endAt + 0.025);\n          harmonic.stop(endAt + 0.025);\n        });\n      }\n      function mlsSetPageLock(active) {\n        document.documentElement.classList.toggle(\"mls-page-lock\", !!active);\n        if (document.body) document.body.classList.toggle(\"mls-page-lock\", !!active);\n      }\n      function mlsEnterFallbackFullscreen() {\n        mlsFallbackFullscreen = true;\n        mlsSetPageLock(true);\n        mlsSyncViewportMode();\n        mlsQueueResize();\n      }\n      function mlsExitFallbackFullscreen() {\n        mlsFallbackFullscreen = false;\n        mlsSetPageLock(false);\n        mlsSyncViewportMode();\n        mlsQueueResize();\n      }\n      function mlsToggleFullscreen() {\n        const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement;\n        const fullscreenTarget = mlsRoot;\n        if (fullscreenElement) {\n          const exit = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen;\n          if (exit) {\n            try {\n              const result = exit.call(document);\n              if (result ? typeof result.finally === \"function\" : false) result.finally(mlsQueueResize);\n            } catch (error) {\n              mlsShowMessage(\"Fullscreen could not be closed.\");\n            }\n          }\n          mlsPlaySound(\"click\");\n          return;\n        }\n        if (mlsFallbackFullscreen) {\n          mlsExitFallbackFullscreen();\n          mlsPlaySound(\"click\");\n          return;\n        }\n        const request = fullscreenTarget.requestFullscreen || fullscreenTarget.webkitRequestFullscreen || fullscreenTarget.mozRequestFullScreen || fullscreenTarget.msRequestFullscreen;\n        if (!request) {\n          mlsEnterFallbackFullscreen();\n          mlsPlaySound(\"click\");\n          return;\n        }\n        try {\n          const result = request.call(fullscreenTarget);\n          if (result ? typeof result.then === \"function\" : false) {\n            result.then(mlsQueueResize).catch(function () {\n              mlsEnterFallbackFullscreen();\n            });\n          } else {\n            mlsQueueResize();\n          }\n        } catch (error) {\n          mlsEnterFallbackFullscreen();\n        }\n        mlsPlaySound(\"click\");\n      }\n      function mlsSparkleBurst() {\n        mlsWinSparkle.innerHTML = \"\";\n        for (let i = 0; i < 36; i++) {\n          const spark = document.createElement(\"span\");\n          const x = 35 + Math.random() * 30;\n          const y = 32 + Math.random() * 28;\n          const sx = (Math.random() - 0.5) * 260;\n          const sy = (Math.random() - 0.7) * 220;\n          spark.style.left = x + \"%\";\n          spark.style.top = y + \"%\";\n          spark.style.setProperty(\"--mls-sx\", sx + \"px\");\n          spark.style.setProperty(\"--mls-sy\", sy + \"px\");\n          spark.style.animationDelay = (Math.random() * 0.18) + \"s\";\n          mlsWinSparkle.appendChild(spark);\n        }\n        setTimeout(function () {\n          mlsWinSparkle.innerHTML = \"\";\n        }, 1500);\n      }\n      mlsRoot.addEventListener(\"pointerdown\", mlsOnPointerDown);\n      mlsRoot.addEventListener(\"click\", mlsHandleClick);\n      window.addEventListener(\"resize\", mlsQueueResize);\n      if (window.ResizeObserver) {\n        const mlsResizeObserver = new ResizeObserver(mlsQueueResize);\n        mlsResizeObserver.observe(mlsRoot);\n        mlsResizeObserver.observe(mlsShell);\n      }\n      window.addEventListener(\"orientationchange\", mlsQueueResize);\n      if (window.visualViewport) {\n        window.visualViewport.addEventListener(\"resize\", mlsQueueResize);\n      }\n      function mlsHandleFullscreenChange() {\n        const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement;\n        if (fullscreenElement) {\n          mlsFallbackFullscreen = false;\n          mlsSetPageLock(false);\n        }\n        mlsSyncViewportMode();\n        mlsQueueResize();\n      }\n      document.addEventListener(\"fullscreenchange\", mlsHandleFullscreenChange);\n      document.addEventListener(\"webkitfullscreenchange\", mlsHandleFullscreenChange);\n      document.addEventListener(\"mozfullscreenchange\", mlsHandleFullscreenChange);\n      document.addEventListener(\"keydown\", function (event) {\n        if (event.key === \"Escape\" ? mlsFallbackFullscreen : false) mlsExitFallbackFullscreen();\n      });\n      mlsUpdateSoundButton();\n      mlsRenderAll();\n      mlsShowStartPopup(\"initial\");\n      mlsRoot.dataset.mlsReady = \"true\";\n      }\n      if (document.readyState === \"loading\") {\n        document.addEventListener(\"DOMContentLoaded\", mlsInitialize, { once: true });\n      } else {\n        mlsInitialize();\n      }\n    })();\n  <\/script>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">How to Play Moonloom Spider<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The main objective is to create eight complete card sequences. Each sequence must begin with a King and continue downward through Queen, Jack, Ten, and every lower rank until it reaches Ace. For a sequence to be completed and removed from the tableau, all thirteen cards must belong to the same suit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cards can be placed on another card if the destination card is exactly one rank higher. For example, a Nine may be placed on a Ten, and a Queen may be placed on a King. In Spider Solitaire, cards of different suits may be arranged temporarily, but only same-suit descending sequences can be moved together as a group.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When a face-down card becomes uncovered, it automatically turns face up. Revealing hidden cards is one of the most important parts of the game because it creates new opportunities and may expose cards needed to complete a long sequence.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Any valid movable card or same-suit sequence may be placed into an empty tableau column. Empty columns are extremely valuable because they provide extra space for reorganizing difficult arrangements. However, players should avoid filling them carelessly, as they may be needed later for a more important move.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Three Difficulty Modes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Moonloom Spider includes three difficulty levels designed for different types of players.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Easy mode uses one suit. All cards share the same workshop symbol, making it easier to build and move long descending sequences. This mode is ideal for new players, relaxing sessions, or anyone who wants to learn the structure of Spider Solitaire without managing multiple suits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Normal mode uses two suits. Players must pay closer attention to suit order because mixed sequences cannot be moved together. This creates a balanced challenge that rewards planning without becoming overwhelming.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Expert mode uses all four suits: Moon Rabbit, Mochi Cake, Night Cloud, and Wooden Mallet. This is the most demanding version of the game. Every move matters, empty columns become especially important, and poorly arranged suits can block one another for a long time. Expert mode is intended for players who enjoy deep strategy and careful long-term planning.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Meaning of the Four Mooncraft Suits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Moon Rabbit suit represents patience, observation, and quiet determination. These cards reflect the apprentices who work through the night, carefully repairing small mistakes before they grow into larger problems.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Mochi Cake suit represents comfort and renewal. The moon rabbits prepare mochi during long shifts, believing that warm food helps restore both energy and courage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Night Cloud suit represents change and uncertainty. Clouds constantly move through the workshop\u2019s paths, hiding stars, revealing new routes, and reminding the rabbits that no arrangement remains permanent.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Wooden Mallet suit represents craftsmanship. The mallet is used to shape mochi, repair workshop frames, and secure the silver threads of the moonloom. It symbolizes careful action rather than force.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These symbols give each deck a visual identity while helping players distinguish the suits clearly during gameplay.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the Stock Pile<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The stock pile contains the remaining cards that were not dealt into the initial tableau. Pressing the Deal Cards button or tapping the stock pile places one new face-up card on every tableau column.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">New deals can create opportunities, but they can also cover useful cards and make existing sequences harder to organize. Because of this, players should examine the board carefully before dealing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The game does not allow a new deal while any tableau column is empty. This rule prevents players from gaining too much temporary space and keeps the challenge consistent with traditional Spider Solitaire.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are five stock deals available at the beginning of a standard game. Once all stock cards have been used, the player must solve the remaining tableau using the available moves.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mooncraft Trays and Completed Sequences<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At the top of the board are eight Mooncraft Trays. Each tray represents one repaired section of the celestial loom.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When a complete same-suit sequence from King to Ace is formed, it is automatically removed from the tableau and placed into the next available tray. The player receives a score bonus, the column beneath the completed sequence becomes available, and any newly exposed face-down card is turned over.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Completing a sequence can dramatically change the board. It may create an empty column, uncover a critical card, or free a group that was previously trapped. Because of this, building one complete sequence is often more valuable than making several smaller moves.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The game is won when all eight trays are filled.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Score, Moves, and Progress<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Moonloom Spider begins with a base score. Each normal move slightly reduces the score, while completing a full sequence adds a significant bonus. This system encourages efficient play without forcing players to rush.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The HUD displays the current score, total number of moves, completed sequences, and remaining stock deals. These values help players understand their progress and evaluate different strategies.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A lower move count usually indicates a more efficient solution, but the most important goal remains completing all eight sequences. Sometimes an extra move is necessary to create an empty column or uncover a hidden card.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Undo and Moon Hint<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Undo button restores the board to its previous state. It can reverse normal card moves and stock deals, making it useful when an action creates an unexpected problem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Undo is not only a correction tool. It can also be used for learning. Players can experiment with a move, observe the result, and return to the earlier arrangement if the path is not useful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Moon Hint feature highlights a legal move when the player is unsure what to do next. It is designed as gentle guidance rather than an automatic solution. A hint may reveal a useful step, but it does not guarantee that the suggested move is part of the best long-term strategy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Players should continue examining the board and considering future consequences before following every hint.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Strategy for Building Strong Sequences<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A strong strategy begins with uncovering face-down cards. Hidden cards limit the number of available choices, so opening them should usually be a priority.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Players should also try to build same-suit sequences whenever possible. Mixed-suit descending stacks may look organized, but they cannot be moved together. A long same-suit run is much more flexible and can be transferred as a complete group.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Empty columns should be protected and used carefully. They can temporarily hold a King, a long sequence, or a card that blocks access to something important. Filling an empty column with a weak move may remove one of the player\u2019s most valuable tools.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before dealing new cards, players should complete as many useful moves as possible. Stock cards are placed on every column, so they may cover cards that were ready to move or interrupt nearly complete sequences.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Planning several moves ahead is often more important than making the most obvious move immediately.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Responsive Controls for Desktop and Mobile<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Moonloom Spider is designed for modern desktop and mobile browsers. Players can select cards by tapping or clicking, or move sequences using drag-and-drop controls.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Valid target columns receive a visual highlight during dragging, while invalid destinations are clearly marked. This feedback makes the game easier to understand and helps prevent accidental moves.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The interface adapts to different screen sizes, including desktop monitors, tablets, and smartphones. Card dimensions and stack spacing are calculated dynamically so the tableau remains visible without unnecessary scrolling.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fullscreen mode enlarges the game while preserving its sixteen-by-nine layout. The game remains centered even when the browser cannot lock the screen orientation, and the fullscreen control stays available when popup menus are open.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Quiet Challenge Beneath the Moon<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Moonloom Spider is not a game about speed. It is a game about gradually turning disorder into structure. Each face-down card is an unknown piece of the night. Each empty column is an opportunity. Each completed sequence brings the workshop closer to restoring the celestial loom.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The soft violet background, creamy moonlight, wooden details, glowing trays, and gentle sound effects create a calm atmosphere, but the strategic challenge remains deep. Easy mode offers a relaxing introduction, while Expert mode can demand careful concentration and many attempts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Every game tells a slightly different story because every shuffled tableau creates new obstacles and possibilities. Sometimes the path opens quickly. Sometimes one hidden card blocks an entire suit. Sometimes a difficult board can be saved by a single empty column and one carefully planned move.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Arrange the lunar cards, uncover the hidden symbols, complete all eight King-to-Ace sequences, and help the moon rabbits repair the great loom before the night begins to fade.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Moonloom Spider is a cozy Spider Solitaire game set inside a hidden workshop suspended above the night clouds. In this quiet celestial place, moon rabbits weave glowing card trails into complete lunar patterns while lanterns sway above wooden tables, mochi rests on small trays, and silver clouds drift beyond the workshop windows. Players must arrange &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-84","post","type-post","status-publish","format-standard","hentry","category-card"],"_links":{"self":[{"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=\/wp\/v2\/posts\/84","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=84"}],"version-history":[{"count":0,"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=\/wp\/v2\/posts\/84\/revisions"}],"wp:attachment":[{"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=84"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=84"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/play.produsenpagarbrc.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=84"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}