Skateboarding astronaut catOne-line
DeepSeek V4.1 Flash 1017
by DeepSeekReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 2 min 12 s
- Cost
- $0.053
- Output tokens
- 44,073
- Spent thinking
- 35,648 tokens
- Speed
- 335.9 tok/s
- Console errors
- 0
- First token after
- 424 ms
- First visible text after
- 1 min 56 s
- Prompt tokens
- 374
- Code size
- 20.7 KB
- Finish reason
- stop
- Served by
- Together
- Model id
deepseek/deepseek-v4.1-flash-1017- Reasoning sent
{"effort":"max"}- Max output
- 64,000 tokens
- Generated
- Nov 11, 2026
What it was asked
The prompt
“draw me an SVG of an astronaut cat skateboarding on the moon”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task. Output rules: - Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block. - Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task. - Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw. - The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. - Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction. - Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session. - Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing. - The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message. - The code must run with zero errors in the console of the latest Chrome.
Code run-1.svg · 426 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Astronaut Cat — Moon Skate</title>
<style>
html,body{height:100%}
body{margin:0;overflow:hidden;background:#04050d;display:flex;align-items:center;justify-content:center}
svg#scene{width:100%;height:100%;display:block}
@keyframes twinkle{0%,100%{opacity:.15}50%{opacity:1}}
@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@keyframes sway{0%,100%{transform:rotate(-1.3deg)}50%{transform:rotate(1.3deg)}}
@keyframes tailSway{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(9deg)}}
@keyframes earTwitch{0%,86%,100%{transform:rotate(0)}90%{transform:rotate(-10deg)}94%{transform:rotate(5deg)}}
@keyframes puff{0%{transform:translate(0,0) scale(.3);opacity:0}14%{opacity:.8}100%{transform:translate(-170px,26px) scale(1.55);opacity:0}}
@keyframes pulse{0%,100%{opacity:.3}50%{opacity:.9}}
.spin{transform-box:fill-box;transform-origin:center;animation:spin 1.4s linear infinite}
#cat{transform-box:fill-box;transform-origin:58% 95%;animation:sway 4.6s ease-in-out infinite}
#tail{transform-box:fill-box;transform-origin:92% 80%;animation:tailSway 3.2s ease-in-out infinite}
#earL{transform-box:fill-box;transform-origin:60% 100%;animation:earTwitch 5.6s ease-in-out infinite}
.puff{opacity:0;transform-box:fill-box;transform-origin:center;animation:puff 2.4s ease-out infinite}
.p1{animation-delay:0s}.p2{animation-delay:.5s}.p3{animation-delay:1s}.p4{animation-delay:1.5s}.p5{animation-delay:1.9s}
.glowpulse{animation:pulse 2.6s ease-in-out infinite}
</style>
</head>
<body>
<svg id="scene" viewBox="0 0 1000 700" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="An astronaut cat skateboarding across the moon">
<defs>
<radialGradient id="skyG" cx="50%" cy="50%" r="72%">
<stop offset="0" stop-color="#1a2350"/>
<stop offset="40%" stop-color="#0c1130"/>
<stop offset="100%" stop-color="#05060f"/>
</radialGradient>
<linearGradient id="moonG" x1="0" y1="470" x2="0" y2="790" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8faff"/>
<stop offset="28%" stop-color="#d7ddec"/>
<stop offset="66%" stop-color="#a9b0c7"/>
<stop offset="100%" stop-color="#7f879f"/>
</linearGradient>
<radialGradient id="earthG" cx="34%" cy="28%" r="82%">
<stop offset="0" stop-color="#9ceaff"/>
<stop offset="42%" stop-color="#2f86d8"/>
<stop offset="100%" stop-color="#0a2554"/>
</radialGradient>
<radialGradient id="earthGlowG">
<stop offset="0" stop-color="#5fc8ff" stop-opacity=".55"/>
<stop offset="55%" stop-color="#2b7fd0" stop-opacity=".16"/>
<stop offset="100%" stop-color="#2b7fd0" stop-opacity="0"/>
</radialGradient>
<linearGradient id="helmetG" x1="0.2" y1="0" x2="0.6" y2="1">
<stop offset="0" stop-color="#eaffff" stop-opacity=".6"/>
<stop offset="52%" stop-color="#9fe0ff" stop-opacity=".1"/>
<stop offset="100%" stop-color="#2f6fa8" stop-opacity=".3"/>
</linearGradient>
<linearGradient id="suitG" x1="0.1" y1="0" x2="0.8" y2="1">
<stop offset="0" stop-color="#ffffff"/>
<stop offset="55%" stop-color="#e9eef8"/>
<stop offset="100%" stop-color="#bfc9de"/>
</linearGradient>
<linearGradient id="furG" x1="0" y1="0" x2="0.2" y2="1">
<stop offset="0" stop-color="#ffcd8f"/>
<stop offset="100%" stop-color="#ee9345"/>
</linearGradient>
<radialGradient id="eyeG" cx="40%" cy="30%" r="78%">
<stop offset="0" stop-color="#d2ffdf"/>
<stop offset="55%" stop-color="#4fc98a"/>
<stop offset="100%" stop-color="#125c3b"/>
</radialGradient>
<linearGradient id="deckG" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#3f4d79"/>
<stop offset="52%" stop-color="#1d2542"/>
<stop offset="100%" stop-color="#0f1426"/>
</linearGradient>
<linearGradient id="ringG" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ffdcab"/>
<stop offset="100%" stop-color="#c78d5a"/>
</linearGradient>
<linearGradient id="streakG" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#ffffff" stop-opacity="0"/>
<stop offset="100%" stop-color="#e6f7ff" stop-opacity=".95"/>
</linearGradient>
<radialGradient id="catGlowG">
<stop offset="0" stop-color="#8fdcff" stop-opacity=".18"/>
<stop offset="60%" stop-color="#5aa6ff" stop-opacity=".07"/>
<stop offset="100%" stop-color="#5aa6ff" stop-opacity="0"/>
</radialGradient>
<radialGradient id="vigG" cx="50%" cy="47%" r="72%">
<stop offset="52%" stop-color="#05060f" stop-opacity="0"/>
<stop offset="100%" stop-color="#05060f" stop-opacity=".92"/>
</radialGradient>
<filter id="blurSoft" x="-45%" y="-45%" width="190%" height="190%">
<feGaussianBlur stdDeviation="7"/>
</filter>
<filter id="blurBig" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="20"/>
</filter>
<clipPath id="moonClip"><circle cx="500" cy="1420" r="940"/></clipPath>
<g id="crater">
<ellipse rx="40" ry="13" fill="#7c8496" opacity=".22"/>
<ellipse cy="-2" rx="34" ry="9" fill="#ffffff" opacity=".38"/>
<ellipse cy="1" rx="26" ry="6" fill="#8d95a4" opacity=".25"/>
</g>
<g id="pawPrint">
<ellipse cy="0" rx="9" ry="7.5" fill="#7c8499"/>
<circle cx="-7.5" cy="-8.5" r="3.2" fill="#7c8499"/>
<circle cx="-2.5" cy="-11" r="3.2" fill="#7c8499"/>
<circle cx="2.5" cy="-11" r="3.2" fill="#7c8499"/>
<circle cx="7.5" cy="-8.5" r="3.2" fill="#7c8499"/>
</g>
</defs>
<!-- ===== SKY ===== -->
<rect x="0" y="0" width="1000" height="700" fill="url(#skyG)"/>
<g filter="url(#blurBig)" opacity=".55">
<ellipse cx="200" cy="150" rx="210" ry="130" fill="#3b2f80"/>
<ellipse cx="850" cy="470" rx="170" ry="100" fill="#1d5a7d"/>
<ellipse cx="620" cy="90" rx="160" ry="90" fill="#4a2b63"/>
</g>
<g id="stars"></g>
<g fill="#ffffff">
<path d="M 300 84 l 3 10 10 3 -10 3 -3 10 -3 -10 -10 -3 10 -3 z" opacity=".9"/>
<path d="M 702 200 l 2.5 8 8 2.5 -8 2.5 -2.5 8 -2.5 -8 -8 -2.5 8 -2.5 z" opacity=".7"/>
<path d="M 862 296 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".55"/>
<path d="M 118 336 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".55"/>
<path d="M 430 60 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".5"/>
</g>
<!-- ===== RINGED PLANET ===== -->
<g>
<ellipse cx="150" cy="120" rx="46" ry="13" transform="rotate(-18 150 120)" fill="none" stroke="url(#ringG)" stroke-width="5" opacity=".7"/>
<circle cx="150" cy="120" r="24" fill="url(#ringG)"/>
<circle cx="151" cy="121" r="24" fill="#b8763f" opacity=".35"/>
<circle cx="142" cy="112" r="7" fill="#a9683a" opacity=".55"/>
<circle cx="158" cy="130" r="5" fill="#a9683a" opacity=".45"/>
<path d="M 104 120 A 46 13 0 0 1 196 120" transform="rotate(-18 150 120)" fill="none" stroke="url(#ringG)" stroke-width="5" opacity=".95"/>
</g>
<!-- ===== EARTH ===== -->
<g>
<circle cx="830" cy="150" r="118" fill="url(#earthGlowG)" class="glowpulse"/>
<circle cx="830" cy="150" r="46" fill="url(#earthG)"/>
<g opacity=".8">
<path d="M 806 128 q 16 -10 28 2 q 8 8 -2 16 q -12 8 -22 -2 q -8 -8 -4 -16 z" fill="#4fbf7a"/>
<path d="M 848 160 q 14 -4 18 8 q 2 10 -10 12 q -12 0 -12 -10 q 0 -8 4 -10 z" fill="#4fbf7a"/>
<ellipse cx="822" cy="176" rx="16" ry="6" fill="#4fbf7a" opacity=".6"/>
</g>
<path d="M 812 120 q 26 -14 48 6" stroke="#ffffff" stroke-width="4" fill="none" opacity=".5" stroke-linecap="round"/>
<path d="M 800 168 q 22 12 46 2" stroke="#ffffff" stroke-width="3" fill="none" opacity=".38" stroke-linecap="round"/>
<circle cx="830" cy="150" r="46" fill="none" stroke="#b9e8ff" stroke-width="2" opacity=".55"/>
</g>
<circle cx="286" cy="286" r="9" fill="#cfd8ea" opacity=".45"/>
<circle cx="283" cy="283" r="3" fill="#9aa6bd" opacity=".5"/>
<!-- ===== SHOOTING STAR ===== -->
<g opacity=".85">
<path d="M 686 92 L 790 50" stroke="url(#streakG)" stroke-width="3" stroke-linecap="round"/>
<circle cx="790" cy="50" r="2.6" fill="#ffffff"/>
</g>
<!-- ===== MOON ===== -->
<g>
<circle cx="500" cy="1420" r="940" fill="url(#moonG)"/>
<g clip-path="url(#moonClip)">
<use href="#crater" transform="translate(190,660) scale(1.7,1.5)"/>
<use href="#crater" transform="translate(322,566) scale(.85,.8)"/>
<use href="#crater" transform="translate(690,558) scale(.75,.7)"/>
<use href="#crater" transform="translate(792,642) scale(1.5,1.3)"/>
<use href="#crater" transform="translate(470,694) scale(1.2,1.1)"/>
<use href="#crater" transform="translate(92,616) scale(1,.9)"/>
<use href="#crater" transform="translate(884,702) scale(1.4,1.2)"/>
<use href="#crater" transform="translate(602,678) scale(.6,.55)"/>
<use href="#crater" transform="translate(384,644) scale(.45,.4)"/>
<use href="#crater" transform="translate(246,536) scale(.5,.45)"/>
<use href="#crater" transform="translate(742,520) scale(.4,.35)"/>
<use href="#crater" transform="translate(560,606) scale(.35,.3)"/>
<g opacity=".32">
<use href="#pawPrint" transform="translate(118,676) scale(1.3)"/>
<use href="#pawPrint" transform="translate(196,642) scale(1.1)"/>
<use href="#pawPrint" transform="translate(258,616) scale(.95)"/>
<use href="#pawPrint" transform="translate(310,598) scale(.8)"/>
<use href="#pawPrint" transform="translate(352,586) scale(.7)"/>
</g>
<g fill="#8b93a9" opacity=".5">
<path d="M 236 692 l 14 -10 16 6 4 14 -18 8 -16 -6 z"/>
<path d="M 708 670 l 10 -8 12 4 3 10 -13 6 -12 -4 z"/>
<path d="M 88 642 l 8 -6 9 3 2 8 -10 5 -9 -3 z"/>
</g>
</g>
<circle cx="500" cy="1420" r="940" fill="none" stroke="#cfe4ff" stroke-width="14" opacity=".45" filter="url(#blurSoft)"/>
<circle cx="500" cy="1420" r="940" fill="none" stroke="#ffffff" stroke-width="2" opacity=".5"/>
</g>
<!-- speed streaks -->
<g stroke="#a9efff" stroke-linecap="round" opacity=".32">
<path d="M 236 588 h 72" stroke-width="4"/>
<path d="M 186 612 h 118" stroke-width="3"/>
<path d="M 262 634 h 62" stroke-width="3"/>
<path d="M 150 662 h 70" stroke-width="2.5" opacity=".6"/>
</g>
<ellipse cx="520" cy="430" rx="330" ry="300" fill="url(#catGlowG)"/>
<!-- ===== RIDER ===== -->
<g id="rider">
<!-- shadow -->
<ellipse cx="500" cy="636" rx="180" ry="18" fill="#5b6480" opacity=".35" filter="url(#blurSoft)"/>
<ellipse cx="500" cy="632" rx="118" ry="10" fill="#3f4864" opacity=".3" filter="url(#blurSoft)"/>
<!-- dust puffs -->
<g fill="#eaf4ff">
<circle class="puff p1" cx="402" cy="618" r="10"/>
<circle class="puff p2" cx="382" cy="626" r="7"/>
<circle class="puff p3" cx="394" cy="630" r="12"/>
<circle class="puff p4" cx="374" cy="612" r="6"/>
<circle class="puff p5" cx="388" cy="610" r="5"/>
</g>
<!-- board -->
<g id="board">
<rect x="408" y="592" width="26" height="16" rx="5" fill="#8b98b6"/>
<rect x="566" y="592" width="26" height="16" rx="5" fill="#8b98b8"/>
<g>
<circle cx="421" cy="612" r="19" fill="#1c2338" stroke="#0b0f1c" stroke-width="3"/>
<circle cx="421" cy="612" r="12" fill="#39476b"/>
<circle class="spin" cx="421" cy="612" r="11" fill="none" stroke="#6be1ff" stroke-width="2.5" stroke-dasharray="5 7" opacity=".85"/>
<circle cx="421" cy="612" r="4.5" fill="#6be1ff"/>
</g>
<g>
<circle cx="579" cy="612" r="19" fill="#1c2338" stroke="#0b0f1c" stroke-width="3"/>
<circle cx="579" cy="612" r="12" fill="#39476b"/>
<circle class="spin" cx="579" cy="612" r="11" fill="none" stroke="#6be1ff" stroke-width="2.5" stroke-dasharray="5 7" opacity=".85"/>
<circle cx="579" cy="612" r="4.5" fill="#6be1ff"/>
</g>
<rect x="352" y="576" width="296" height="22" rx="11" fill="url(#deckG)" stroke="#0a0e1c" stroke-width="3"/>
<rect x="360" y="580" width="280" height="7" rx="3.5" fill="#6be1ff" opacity=".45"/>
<rect x="462" y="590" width="60" height="4" rx="2" fill="#6be1ff" opacity=".45"/>
<path d="M 600 578 l 2.5 7 7 2.5 -7 2.5 -2.5 7 -2.5 -7 -7 -2.5 7 -2.5 z" fill="#ffd166"/>
</g>
<!-- cat -->
<g id="cat">
<!-- tail -->
<g id="tail">
<path d="M 468 546 C 420 572 368 552 360 510 C 354 484 366 464 388 464"
fill="none" stroke="url(#furG)" stroke-width="19" stroke-linecap="round"/>
<circle cx="388" cy="464" r="9.5" fill="#ffe9cf"/>
<path d="M 404 496 q 14 -6 22 2" stroke="#dd8a44" stroke-width="3" fill="none" opacity=".55" stroke-linecap="round"/>
<path d="M 372 476 q 12 -6 20 0" stroke="#dd8a44" stroke-width="3" fill="none" opacity=".45" stroke-linecap="round"/>
</g>
<!-- backpack -->
<g id="backpack">
<rect x="396" y="466" width="90" height="104" rx="24" fill="#c9d5e9" stroke="#9dabc6" stroke-width="3"/>
<rect x="410" y="480" width="62" height="30" rx="10" fill="#eaf1fb" stroke="#a8b6cf" stroke-width="2"/>
<circle cx="426" cy="527" r="6" fill="#6be1ff"/>
<circle cx="446" cy="527" r="6" fill="#6be1ff" opacity=".6"/>
<rect x="408" y="544" width="66" height="12" rx="6" fill="#aebbd4"/>
</g>
<!-- back arm -->
<path d="M 470 500 C 446 512 428 530 422 548" fill="none" stroke="#dde6f5" stroke-width="24" stroke-linecap="round"/>
<ellipse cx="418" cy="552" rx="15" ry="13" transform="rotate(-20 418 552)" fill="#f2f7ff" stroke="#c2cde2" stroke-width="3"/>
<ellipse cx="416" cy="554" rx="6.5" ry="5.5" fill="#f7b0b8" opacity=".9"/>
<!-- legs -->
<path d="M 496 544 C 472 552 454 558 444 566" fill="none" stroke="#dde6f5" stroke-width="30" stroke-linecap="round"/>
<path d="M 546 542 C 568 550 580 556 590 562" fill="none" stroke="#eef3fc" stroke-width="30" stroke-linecap="round"/>
<!-- boots -->
<ellipse cx="440" cy="568" rx="23" ry="11.5" fill="#d5e0f0" stroke="#a9b8d2" stroke-width="2.5"/>
<path d="M 420 574 h 40" stroke="#8fa0be" stroke-width="4" stroke-linecap="round"/>
<ellipse cx="592" cy="564" rx="23" ry="11.5" fill="#e6edf9" stroke="#b3c1d8" stroke-width="2.5"/>
<path d="M 572 570 h 40" stroke="#9aa9c4" stroke-width="4" stroke-linecap="round"/>
<!-- torso -->
<path d="M 474 468 C 452 486 448 522 462 550 C 492 566 552 566 578 550 C 592 520 588 486 566 468 Z"
fill="url(#suitG)" stroke="#b7c4dc" stroke-width="3"/>
<!-- suit details -->
<rect x="492" y="492" width="58" height="42" rx="11" fill="#dce7f7" stroke="#a7b6d1" stroke-width="2.5"/>
<rect x="500" y="500" width="42" height="15" rx="4" fill="#4fd8f7"/>
<rect x="503" y="504" width="10" height="3" rx="1.5" fill="#0b3a52" opacity=".5"/>
<rect x="516" y="504" width="16" height="3" rx="1.5" fill="#0b3a52" opacity=".4"/>
<rect x="503" y="509" width="22" height="3" rx="1.5" fill="#0b3a52" opacity=".35"/>
<circle cx="503" cy="524" r="4.5" fill="#7ef2a8"/>
<circle cx="518" cy="524" r="4.5" fill="#ffd166"/>
<circle cx="533" cy="524" r="4.5" fill="#ff8a8a"/>
<rect x="466" y="534" width="106" height="14" rx="7" fill="#c8d4e9" stroke="#a4b3ce" stroke-width="2.5"/>
<circle cx="566" cy="482" r="10" fill="#ffd166" stroke="#d9a93f" stroke-width="2"/>
<path d="M 566 477 l 1.8 4.4 4.7 .5 -3.5 3.2 1 4.7 -4 -2.5 -4 2.5 1 -4.7 -3.5 -3.2 4.7 -.5 z" fill="#a97a1f" opacity=".8"/>
<path d="M 470 476 C 462 490 460 504 462 518" stroke="#6be1ff" stroke-width="5" fill="none" stroke-linecap="round" opacity=".8"/>
<!-- neck + collar -->
<rect x="498" y="438" width="44" height="44" rx="20" fill="#e3eaf6"/>
<ellipse cx="520" cy="472" rx="54" ry="17" fill="#cfdaec" stroke="#a3b1cc" stroke-width="3"/>
<ellipse cx="520" cy="470" rx="44" ry="11" fill="#b9c7de" opacity=".55"/>
<!-- ears -->
<g id="earL">
<path d="M 486 374 L 470 326 L 524 352 Z" fill="url(#furG)" stroke="#dc8440" stroke-width="2" stroke-linejoin="round"/>
<path d="M 490 366 L 479 334 L 512 352 Z" fill="#ffb7ae" opacity=".85"/>
</g>
<path d="M 554 374 L 570 326 L 516 352 Z" fill="url(#furG)" stroke="#dc8440" stroke-width="2" stroke-linejoin="round"/>
<path d="M 550 366 L 561 334 L 528 352 Z" fill="#ffb7ae" opacity=".85"/>
<!-- head -->
<ellipse cx="520" cy="404" rx="55" ry="49" fill="url(#furG)"/>
<g stroke="#dd8a44" stroke-width="4" stroke-linecap="round" opacity=".5">
<path d="M 496 366 l -6 -14"/>
<path d="M 520 360 l 0 -14"/>
<path d="M 544 366 l 6 -14"/>
</g>
<ellipse cx="482" cy="424" rx="8" ry="5" fill="#ff9aa5" opacity=".4"/>
<ellipse cx="558" cy="424" rx="8" ry="5" fill="#ff9aa5" opacity=".4"/>
<!-- eyes -->
<ellipse cx="499" cy="398" rx="15" ry="16.5" fill="url(#eyeG)"/>
<ellipse cx="543" cy="398" rx="15" ry="16.5" fill="url(#eyeG)"/>
<ellipse cx="499" cy="399" rx="4.5" ry="13" fill="#101a1c"/>
<ellipse cx="543" cy="399" rx="4.5" ry="13" fill="#101a1c"/>
<circle cx="494" cy="392" r="4.5" fill="#ffffff" opacity=".95"/>
<circle cx="538" cy="392" r="4.5" fill="#ffffff" opacity=".95"/>
<circle cx="503" cy="404" r="2.2" fill="#ffffff" opacity=".7"/>
<circle cx="547" cy="404" r="2.2" fill="#ffffff" opacity=".7"/>
<!-- muzzle -->
<ellipse cx="510" cy="430" rx="16" ry="12" fill="#ffe9cf"/>
<ellipse cx="532" cy="430" rx="16" ry="12" fill="#ffe9cf"/>
<path d="M 514 414 L 526 414 Q 527 419 520 423 Q 513 419 514 414 Z" fill="#f28d9b"/>
<path d="M 520 423 v 5 M 520 428 q -7 6 -13 1 M 520 428 q 7 6 13 1" stroke="#a9713f" stroke-width="2.4" fill="none" stroke-linecap="round"/>
<!-- whiskers -->
<g stroke="#ffffff" stroke-width="2.2" stroke-linecap="round" opacity=".85">
<path d="M 498 426 L 462 418"/>
<path d="M 496 432 L 458 432"/>
<path d="M 498 438 L 464 446"/>
<path d="M 542 426 L 578 418"/>
<path d="M 544 432 L 582 432"/>
<path d="M 542 438 L 576 446"/>
</g>
<!-- helmet -->
<circle cx="520" cy="396" r="80" fill="url(#helmetG)" stroke="#e2f6ff" stroke-width="4"/>
<circle cx="520" cy="396" r="80" fill="none" stroke="#8fc8ea" stroke-width="8" opacity=".16"/>
<path d="M 451 364 A 76 76 0 0 1 500 323" fill="none" stroke="#ffffff" stroke-width="9" stroke-linecap="round" opacity=".8"/>
<path d="M 464 448 A 76 76 0 0 1 444 404" fill="none" stroke="#ffffff" stroke-width="5" stroke-linecap="round" opacity=".3"/>
<!-- antenna -->
<line x1="568" y1="338" x2="596" y2="300" stroke="#cfd9ea" stroke-width="4" stroke-linecap="round"/>
<circle cx="598" cy="297" r="13" fill="#6be1ff" opacity=".28" class="glowpulse"/>
<circle cx="598" cy="297" r="6.5" fill="#6be1ff"/>
<!-- front arm -->
<path d="M 564 492 C 592 486 616 468 630 446" fill="none" stroke="#eef3fc" stroke-width="26" stroke-linecap="round"/>
<path d="M 572 500 C 596 494 616 478 628 458" fill="none" stroke="#cfdaea" stroke-width="3.5" stroke-linecap="round" opacity=".45"/>
<ellipse cx="632" cy="441" rx="18" ry="17" fill="#f8fbff" stroke="#c2cde2" stroke-width="3"/>
<ellipse cx="632" cy="445" rx="9" ry="7" fill="#f7b0b8" opacity=".95"/>
<circle cx="622" cy="432" r="3.6" fill="#f7b0b8" opacity=".95"/>
<circle cx="632" cy="429" r="3.6" fill="#f7b0b8" opacity=".95"/>
<circle cx="642" cy="432" r="3.6" fill="#f7b0b8" opacity=".95"/>
</g>
</g>
<!-- vignette -->
<rect x="0" y="0" width="1000" height="700" fill="url(#vigG)" pointer-events="none"/>
<!-- label -->
<g fill="#7d8aa8" opacity=".75" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="14" letter-spacing="3">
<text x="58" y="58">LUNAR SK8 · 1/6 g</text>
</g>
</svg>
<script>
(function () {
var g = document.getElementById('stars');
if (!g) return;
var NS = 'http://www.w3.org/2000/svg';
var seed = 123456789;
function rnd() {
seed = (s => (s * 16807) % 2147483647)(seed);
return seed / 2147483647;
}
var frag = document.createDocumentFragment();
for (var i = 0; i < 130; i++) {
var c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
c.setAttribute('cx', (rnd() * 1000).toFixed(1));
c.setAttribute('cy', (rnd() * 620).toFixed(1));
c.setAttribute('r', (0.5 + rnd() * 1.6).toFixed(2));
c.setAttribute('fill', rnd() > 0.86 ? '#c6e8ff' : '#ffffff');
c.setAttribute('fill-opacity', (0.3 + rnd() * 0.7).toFixed(2));
c.style.animation = 'twinkle ' + (2.4 + rnd() * 4).toFixed(1) + 's ease-in-out ' + (rnd() * 5).toFixed(1) + 's infinite';
frag.appendChild(c);
}
g.appendChild(frag);
})();
</script>
</body>
</html>Reasoning trace (35,648 tokens)
We need to create an SVG of an astronaut cat skateboarding on the moon. Let's make a nice detailed inline SVG with animation. Since it's an SVG task, we should reply with ```svg ... ``` maybe, but the file rendered in iframe. Hmm, the task says "draw me an SVG". Best approach: produce an HTML file containing the SVG so it renders in the iframe, since it will be rendered automatically in a sandboxed iframe. Actually the rules say reply with one fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). The task asks for an SVG. But if we output raw SVG, it will render in the iframe as an image/svg document. That could work fine — animations with SMIL or CSS inside SVG work in Chrome.
Safer: output a full HTML page that displays the SVG centered with a starry background, plus subtle CSS animations. The comparison is with other models given same task; likely they'd produce HTML with inline SVG. Either works. But an SVG file rendered at top-level in iframe: Chrome renders standalone SVG documents fine, and it scales to viewport. But responsive adaptation down to 375px is easier in HTML. Let's do HTML with an inline SVG that scales.
Design an astronaut cat skateboarding on the moon:
- Space background: dark gradient, stars, distant Earth, maybe Saturn.
- Moon surface: cratered, curved horizon.
- Astronaut cat: cat head with helmet (glass bubble), ears inside helmet, whiskers, cat eyes, spacesuit body, tail poking out, arms, legs on skateboard.
- Skateboard with wheels, slight motion.
- Animations: floating dust, twinkling stars, bobbing cat, spinning wheels, tail sway, thruster glints.
Let's carefully lay out coordinates in a 1000x700 viewBox.
Layout:
- Sky from y=0 to y≈520 (moon horizon curve).
- Moon surface big circle centered at (500, 1400) radius 900? That gives horizon at y=500. Let's do circle cx=500 cy=1450 r=960 → top at y=490. Fine.
- Skateboard near y=560 maybe on the surface... Moon surface at x=500 is y=490. Hmm, we want the cat skateboarding above the surface with some shadow. Let's place skateboard around y=520-560, with surface horizon at 490 and surface visible below. Actually if the moon circle top is 490, the surface in the middle of screen is at 490 going down. The skateboard should be on the surface near y ~ 560? Consider the visible surface region: the circle's top arc — at center x=500 the top is 490; the whole lower area is moon. So place skateboard with wheels touching around y=600, which is inside the moon's surface (foreground). Good, gives depth.
Let me build in viewBox 0 0 1000 700.
Elements:
1. defs: gradients for sky, moon surface, helmet glass, board deck, wheel, glow filters, star.
2. Background rect with radial gradient dark navy → deep purple.
3. Stars: generate via JS? Better static for reliability but JS can generate a nice starfield. JS is fine. But screenshot at 3s, so fine. Still, static is safest and simpler to control. I'll write ~60 stars manually? That's a lot. Use JS to generate stars with random positions and twinkle animation delays. That's compact and reliable. But rule: zero errors. Straightforward.
Actually, I'd rather do a hybrid: a handful of hand-placed stars plus a JS-generated field. Let's just use JS to create stars in a <g id="stars">.
4. Distant Earth: small blue circle with green continents at top-right, with a subtle glow. Maybe a crescent? Keep simple.
5. Moon: big ellipse/circle with craters, subtle gradient, rim light.
6. Cat astronaut:
- Position around x=500, y=380.
- Helmet: circle r=78 centered (500,330) with glass gradient and white rim, highlight arc.
- Cat head inside: rounded shape w/ ears, muzzle, eyes (big cat eyes with slit pupils), whiskers, nose.
- Body: spacesuit torso below helmet, backpack.
- Arms: one arm out for balance, other down.
- Legs bent onto skateboard.
- Tail: curving out from behind, with a paw-tip.
- Skateboard: deck under feet, two wheels with trucks.
7. Motion: speed lines, small dust particles behind wheels, glow.
8. Text? Maybe not needed. A small caption could be nice but not necessary. Might add subtle "MEOW" but skip.
Animation via CSS:
- float (translateY) on the whole rider group
- wheel spin (rotate) on wheel spokes
- tail sway (rotate)
- stars twinkle (opacity)
- Earth glow pulse.
Careful: CSS animations inside inline SVG in HTML work great.
Let's write the shapes carefully.
Coordinate plan (viewBox 0 0 1000 700):
Moon: `<circle cx="500" cy="1420" r="940" />` → top at y=480, and at x=0: dx=500 → y = 1420 - sqrt(940²-500²) = 1420 - sqrt(883600-250000)=1420-sqrt(633600)=1420-796=624. So at edges the surface is lower (624). Hmm that means the horizon curve dips at edges? No — a circle top arc: at center the top is highest (480) and at edges lower (624). That is the correct look of a lunar horizon curving away: near horizon at center, falls off at sides. Good. But then the bottom-left/right corners of viewBox: at y=700, the circle spans x where (y-1420)² + (x-500)² = 940² → (700-1420)² = 518400; 883600-518400=365200; sqrt=604. So at y=700 the moon spans x from -104 to 1104. So bottom corners covered.
The horizon: at x=0..40, y ≈ 624. Good, leaves sky at corners top area. Fine.
Skateboard at bottom around y≈600? The surface at x=500 is 480, so y=600 is 120px below the horizon at center — that's "closer to viewer", fine. But visually, the wheels will be on y=600 while the horizon is at 480, so the cat appears standing in front of a large empty moon area below. Fine. Maybe put the board at y=610 for space.
Rider total height: skateboard deck y=600, cat feet on deck, body up to head top at ~y=300. Helmet circle center (500, 350) r=80 → top 270. That's a big figure, good.
Let me design:
Skateboard:
- Deck: a rounded path from x=360 to x=650 at y=600, with slight kicktails up.
Deck path: M 355 592 Q 350 578 372 576 L 628 576 Q 650 578 645 592 L 645 598 L 355 598 Z — that's a simple deck. Maybe simpler: rounded rect x=350 y=574 width=300 height=18 rx=9, with slight rotation. Add a lighter top edge.
- Wheels: circles at (415, 612) and (585, 612), r=16, with inner hub circle and spokes.
- Trucks: small rects connecting deck to wheels.
Let me place deck at y=570..590, wheels centers at y=606 r=16 → bottom 622. Moon ground contact at 622.
Rider:
- Legs: from hips (~y=520) down to feet on deck at y=572.
- Torso: rounded rect / path from y=430 to 545, width ~110. Spacesuit white with gray shading.
- Backpack: behind torso, rounded rect x=380..? Hmm rider faces right? Let's have the cat facing right (moving right), body slightly turned.
Let me establish: cat faces right. Helmet centered at (520, 400), radius 78. Torso from x=450 to x=560, y=470 to 560. Hip at (505,555). Legs: front leg goes forward-right to foot at (585, 570), back leg goes back-left to foot at (430, 570). Both feet on deck (deck y 570..).
Hmm, having the deck at y=570 and the feet there is fine but then the torso is above.
Skateboard: deck top surface y=568. Feet at ~y=562 (paws rounded). Wheels centers y=600.
Let's redo vertical stack:
- wheels: cy=612, r=18 → bottom 630. Hmm, need ground contact around y=630. Moon surface at x=500 is 480, so it's fine — the cat is in the foreground.
Actually let's make the scene: horizon at 480, cat's wheels at ~620. The shadow ellipse under the board around y=632.
Deck: y=578 to 594, x=340..660 (width 320). Wheels cy=612 r=17.
Feet on deck at y=578.
Torso: y=470..565. Helmet: center (520, 395) r=78 → top 317, bottom 473. Overlaps torso top a bit — good.
Total figure top ~317, comfortable.
Arms:
- Front arm (right side of image): from shoulder (565, 500) to hand at (640, 450) — raised waving pose, or out for balance.
- Back arm (left): from shoulder (460, 500) to hand at (395, 530).
Tail: from hip back-left, curving up: from (455, 555) curve to (380, 540) to (350, 480) with a rounded tip. Tail striped? It's a cat tail; maybe with a subtle stripe.
Cat head inside helmet:
- Ears: triangles near top of helmet interior, at (480,330) and (555, 332), slightly rounded. But helmet r=78 centered (520,395) — top of helmet is 317; ears at y=330 inside the glass. Good.
- Head: ellipse cx=520 cy=400 rx=52 ry=46, fur light gray/white? Let's make the cat a light gray tabby with white muzzle, or an orange tabby (nice contrast against white suit and blue space). Orange cat with cream muzzle. Space suit white/light gray with cyan accents. Helmet glass with a light blue tint and highlight.
Cat face:
- Head shape: rounded with cheeks. ellipse rx=54 ry=48, cx=520 cy=402.
- Ears: path triangles: left ear from (478, 372) to (470, 330) to (510, 358) — need inside head. Since head center y=402, top of head y=354. Ears should extend up to ~y=340. But helmet top is 317, so ears at 340 fit. Left ear: points (482,362), (468,325), (512,352). Hmm, ear tips could poke slightly. Let's define left ear polygon: M 486 366 L 472 322 L 520 352 Z. Right ear: M 554 366 L 568 322 L 520 352 Z. But head ellipse top is at 354 at cx=520. Ears at x 472-520 are outside head's ellipse (at x=490, head y top = 402 - 48*sqrt(1-(30/54)²) = 402 - 48*0.83 = 362). So ear base at 366 near head. OK.
Actually simpler: draw ear triangles behind the head, with inner ear pink triangles.
- Eyes: big oval eyes at (500, 398) and (542, 398), rx=13 ry=15, dark green/black with white glints and slit pupils. Cat eyes look great.
- Muzzle: two small circles/ellipse at (512, 424) and (530, 424) in cream, plus nose triangle at (521, 416) pink, and mouth curve.
- Whiskers: 3 lines each side.
- Maybe a little smile.
Helmet: circle with glass gradient (semi-transparent light blue) on top of head, with rim stroke, plus highlight arc. Also a helmet collar/ring at bottom of helmet: ellipse at y=470.
Spacesuit details: chest control panel with buttons, stripes on arms, boots.
Colors:
- Sky: #05060f → #101a3a → purple.
- Moon: #d9dbe6 → #9aa0b5 with darker craters; strong moonlight.
- Cat fur: #f3a35c orange, cream muzzle #ffe8cc, dark stripes #d97f3a.
- Suit: #f3f6fb white with #c9d3e6 shading, cyan accents #57e0ff.
- Helmet glass: #a9e6ff at low opacity with white rim.
Animations:
- `#rider` gentle bob: translateY 0 → -8 → 0 over 3s, plus slight rotate.
- wheels rotate.
- tail sway.
- stars twinkle via JS-generated with random delays.
- speed dust particles moving left with fade — CSS animation on circles.
- Earth glow pulse.
Careful with CSS transform on SVG groups: use `transform-box: fill-box; transform-origin: center` or set explicit transform-origin in user units with `transform-origin: 415px 612px`? For SVG elements in HTML, CSS transform-origin percentages resolve against the element's bounding box if transform-box is fill-box. I'll use `transform-box: fill-box; transform-origin: center;` for wheels, and for tail use `transform-box: fill-box; transform-origin: 100% 100%;` roughly at base. Hmm tail base at right-bottom of its bbox. Let's design tail going left from hip: bbox from x=350..462, y=470..560. Base of tail at (462,555) which is bottom-right. So transform-origin: 100% 100% works with fill-box. Good.
Bob animation on #rider: `transform: translateY(-10px)` — with SVG and CSS, transforms on SVG elements work (Chrome supports CSS transforms on SVG elements). Use `transform-box: fill-box` not needed for translate.
Let's also add a slight rotation: `transform: translateY(-9px) rotate(-1deg)` with transform-origin center. It's fine.
Rider bob may cause feet to leave the board. Instead bob the whole group (rider + board) together so wheels lift off the moon? That looks like floating, not good. Alternative: bob only the cat (body+head+arms+tail) but feet stay? Feet would separate.
Simplest: no vertical bob of the whole thing, instead subtle scale/rotation, or bob the board + cat together by 3px — small enough to be fine because of the shadow staying. Actually the shadow stays and the board lifts 3px — looks like a mini hop, kind of cute. Or avoid bob entirely and animate dust + wheels + tail + ears twitch. That's enough motion. Let's do: whole rider group tiny bob of 4px with a soft shadow that scales — looks like hovering slightly. Hmm.
I'll just animate: wheels spinning, tail swaying, ear twitch, stars twinkle, dust puffs moving, Earth glow, helmet glint sweep, and a subtle body sway using rotate around the board contact point (like balancing): rotate ±1.2deg around (500, 630)? If rotating around the wheel contact, the board tilts too — like a skater balancing. That's cute but the wheels would tilt off the ground slightly, negligible at 1 degree with the pivot at ground.
Better: rotate only the cat (not the board) ±1.5deg around the hips. Feet would move slightly on the board, fine.
Let's keep it moderate: `#cat` group gets `animation: sway 4s ease-in-out infinite;` with `transform: rotate(1.2deg)` and `transform-origin: 500px 570px;` (in user units, need transform-box: view-box for that to make sense). With `transform-box: view-box`, transform-origin coordinates are in the SVG user coordinate system relative to the viewBox origin. Chrome supports `transform-box: view-box`. Good.
Actually simpler & safe: wrap cat in <g id="cat"> and use `style="transform-box: view-box; transform-origin: 520px 565px;"`.
Hmm, `transform-box: view-box` is supported in Chrome. Yes.
Let's write it.
Sky: rect 0 0 1000 700 fill url(#sky).
Sky gradient: linearGradient x1=0 y1=0 x2=0.4 y2=1: stops #05040f, #0b1030, #1b1240, #2a1747? Let's do radial from around cat: brighter behind cat.
Add a soft glow behind the cat: radial gradient circle centered (520, 420) r 320 with cyan/white 8% opacity → nice.
Stars: JS-generated, 90 stars, sizes 0.6-2.4, opacity, twinkle animation with random delay/duration. Also a few larger 4-point sparkle stars.
Earth: at (830, 150), radius 46: blue gradient, green blobs, white swirl clouds, dark night side via a clipped darker overlay? Simpler: circle with linear gradient from #2f7fd0 to #0d3d78, plus green shapes with opacity, plus a soft glow ring via filter or outer circle with low opacity. Add a crescent highlight.
Maybe also a small distant moon/planet with rings? Keep it: Earth top-right, a tiny red planet top-left, shooting star.
Moon surface:
- circle cx=500 cy=1420 r=940 fill url(#moonGrad) — gradient from top #eef1f8 to bottom #a7adc4? Since the circle is huge, use a linear gradient over y 480..700. Let's use linearGradient with userSpaceOnUse y1=480 y2=760: #f2f5fb → #b9c0d4 → #8e95ad.
- Craters: ellipses with darker fill and inner shadow, positioned in the visible band y 490..680, sizes 20-90, flattened ellipses (ry ~ 0.35 rx). Place at various x, avoid the skateboard area? They can be around.
- Add a rim highlight along the horizon: a path/stroke arc with white opacity 0.5 and a glow filter. Or a second circle with stroke.
- Terminator shading at edges maybe.
Crater look: ellipse fill #b6bccf with stroke lighter on bottom edge? Classic: fill darker ellipse (#b7bdd0), plus a lighter arc at the bottom-right inner. Let's do each crater as a <g> with ellipse fill #b0b7cc opacity .55 and an inner highlight path.
Simplify: define a `<g id="crater">` with ellipse rx=40 ry=14 fill="#9aa1b8" opacity=".5" and a smaller ellipse offset up fill="#c8cde0" opacity=".35"... use <use> with transform scale/translate. Using <use> with transform works.
Let's do:
```
<g id="crater">
<ellipse cx="0" cy="0" rx="40" ry="14" fill="#7f87a1" opacity="0.35"/>
<ellipse cx="0" cy="-3" rx="34" ry="9" fill="#e8ecf7" opacity="0.45"/>
<ellipse cx="0" cy="-1" rx="30" ry="7" fill="#98a0b8" opacity="0.4"/>
</g>
```
Then `<use href="#crater" x=".." y=".." transform="scale(...)"/>`. Careful: using both x/y and scale can be confusing. Use `transform="translate(x,y) scale(s, s*0.8)"` with `<use href="#crater"/>`.
Hmm the `<use>` element and scale: `transform="translate(180,600) scale(1.4,1)"` fine.
Shadow under board: ellipse cx=500 cy=634 rx=170 ry=16 fill #5a6078 opacity .35 with blur filter, plus a smaller darker.
Dust: small circles near the wheels that animate left and fade.
Let's write the cat carefully.
Coordinates:
- Helmet: cx=520, cy=395, r=80. Top 315, bottom 475.
- Collar ring: ellipse cx=520 cy=470 rx=62 ry=14, fill #cfd8ea, stroke #aab6cd. Draw after torso, before helmet? The collar should be at the base of the helmet, drawn over the torso top and over the bottom of the helmet. Order: torso, collar, head+ears, helmet glass (transparent over head), helmet rim.
Wait — helmet glass over head means glass is semi-transparent, so we can see the head through it. Good: draw head first, then glass circle with fill rgba(...) opacity 0.25 and highlight. The rim stroke is opaque white-blue.
- Head: cx=520 cy=400.
- Ears behind head: left ear path M 484 372 L 466 320 L 522 350 Z (fur), inner ear M 484 366 L 475 331 L 508 350 Z (pink #f0a3a3).
- Right ear: M 556 372 L 574 320 L 518 350 Z; inner: M 556 366 L 565 331 L 532 350 Z.
Hmm ears at 320-372 while helmet top is 315 — ears just inside. Good.
- Head shape: ellipse cx=520 cy=402 rx=54 ry=48 fill #f6a95e. Add cheek fluff?? Let's use a path for a slightly catlike head: rounded with pointed cheek fur. Simpler: ellipse plus two small circles for cheeks. Keep ellipse, add stripes.
- Stripes on forehead: three short strokes.
- Eyes: at (499, 396) and (543, 396), each: ellipse rx=14 ry=16 fill #1c2a1f? Cat eyes green: outer almond shape fill #2b7d4f? Let's do: eye shape ellipse rx=14.5 ry=16 fill="#2e8b57"? Hmm, with slit pupil.
- Eye white/sclera: ellipse fill "#f7f2d8"? Cat eyes usually full iris. Let's do iris: ellipse rx=14 ry=15.5 fill url(#eyeGrad) (#8ef0b0 → #2ea66b), then pupil: ellipse rx=4 ry=13 fill #101820, then glint circles white r=4 at upper-left, r=2 at lower-right.
- Muzzle: two overlapping ellipses cx=509/531 cy=428 rx=15 ry=11 fill #ffe9cf.
- Nose: path triangle around (520, 417): M 514 414 L 526 414 L 520 422 Z fill #ef8f9b.
- Mouth: path M 520 422 q 0 6 -7 7 M 520 422 q 0 6 7 7 stroke #b07a4a.
- Whiskers: lines from (500,424) to (462,418), (500,430) to (458,430), (500,436) to (466,442); mirrored.
- Maybe blush.
- Torso: path rounded: from shoulders at (470,470) to (570,470), down to hips at (555,565) & (485,565). Use a rounded rect-ish path:
`M 466 478 Q 452 520 470 556 Q 520 572 570 556 Q 588 520 574 478 Z` fill white gradient.
Add chest panel: rounded rect x=500 y=496 w=48 h=34 rx=8 fill #dbe6f5 stroke. Screen fill #47d6f7 with tiny bars.
Add belt: rect at y=548.
Suit accents: cyan stripes on shoulders.
- Backpack: behind torso, to the left: rounded rect x=402 y=480 w=70 h=90 rx=18 fill #d7dfee stroke #a9b5cc, with small nozzle.
Hmm the backpack on the left side. Since the cat faces right, backpack behind (left). It'd be partially hidden by torso; draw before torso.
- Arms:
- Back arm (left): from (470,495) curving down-left to hand at (420,545). Draw as a thick stroked path with round cap: stroke #e6ecf7 width 26, then a paw circle at the end.
- Front arm (right): from (575,495) to hand at (640,455) — raised for balance, paw up. Thick stroked path stroke #f2f6fd width 26 plus cuff stripe cyan near the wrist and paw (mitten) circle fill #f6a95e? Paws inside gloves — astronaut gloves should be white with a cat paw shape. Let's do gloves as light gray rounded shapes with pink paw pads! Cute: on the raised hand, show paw pad circles.
- Legs:
- Back leg: from hip (490,556) to foot (435,570) — a bent leg: thick stroke path M 490 552 Q 455 552 440 566, stroke width 30, white.
- Front leg: from hip (550,556) to foot (585,568): M 552 550 Q 578 552 588 564.
- Boots: rounded rects/ellipses at feet: ellipse cx=436 cy=568 rx=22 ry=11 fill #dbe4f2 stroke, and cx=588 cy=566.
Hmm feet on deck at y=578 (deck top). Let's set deck top y=580, boots bottom at 578.
Let's finalize deck: rounded rect x=330 y=578 w=340 h=20 rx=10 fill url(#deckGrad) (#2b3550 → #101728). Top edge highlight: rect x=336 y=580 w=328 h=5 rx=3 fill #57e0ff opacity .5? Maybe neon cyan grip tape edge for a sci-fi feel. Plus a star sticker.
Wheels: cx 410 & 590, cy=612, r=18. tire fill #1a2233, hub #57e0ff, spokes lines.
Trucks: rect from deck bottom (598) to wheel center: small path fill #9aa6be.
Board shadow ellipse cx=500 cy=634 rx=190 ry=18 fill #4a4f66 opacity .4 filter blur.
Hmm wheels bottom at 630, shadow at 634. Good.
Now the horizon at y=480 — the cat is in front of the moon, so the board is at 578-630 and the moon surface extends behind it. Good.
Rider position vs horizon: cat head top 315, well above horizon in space. Good.
Add a subtle motion trail behind the board: cyan streaks at left around (250-350, 590-620).
Dust particles kicked up behind the wheels — small circles moving left.
Let's add a "MEOW" speech? No. Maybe small floating text "MEOW" in a comic bubble? Skip; keep it illustrative.
Add caption at bottom? Not needed.
Responsiveness: SVG with width 100%, height auto, viewBox preserveAspectRatio. Container centered on dark background. For 375px wide, the SVG scales down; details get small but silhouette remains readable. Maybe use `max-height: 100vh`. Set html,body height 100%, display grid place-items center, background #05060f. SVG width: min(100%, 1100px), height auto, max-height 100vh. With aspect 1000x700, at 1280 wide → the container max-width 1100 → height 770 > 800? 1100*0.7 = 770 fits in 800. Good. But if we use `max-height:100vh` with width auto, it will letterbox. Let's just do `width: 100%; height: 100%;` with preserveAspectRatio="xMidYMid meet" on a full-viewport SVG. That's simplest and scales gracefully: the SVG fills the viewport and letterboxes with the page background. But then the background inside SVG won't cover the letterbox area — the body background is also dark, so it's seamless. Use a slightly different body background? Set body bg to #05060f matching the SVG's sky top color. With meet, there will be bars on the sides at 375px (portrait) with aspect 1.43 vs 1.87 → bars top/bottom actually. At 375x800, the SVG at width 375 → height 262, centered vertically, big empty area top/bottom. Hmm, "adapt gracefully" — with the dark space background it just looks like the scene floats in space. Acceptable but could improve: use preserveAspectRatio="xMidYMid slice" to fill? That would crop. Maybe better: for narrow screens, scale to width and center vertically with the space background continuing. Let's make the body background a radial gradient similar to the scene so it blends.
Alternative: SVG width 100%, height 100%, preserveAspectRatio="xMidYMid slice" so it fills the viewport and crops the sides on narrow screens. Cropping sides of a wide scene at portrait would cut the moon/e earth. With slice at 375x800: scale = max(375/1000, 800/700) = 1.143 → visible width = 375/1.143 = 328 of 1000 → heavy crop, only the center 328 units visible. That would actually still show the cat and board (center) nicely, cropping out Earth and distant planets. Hmm, that's actually decent: a zoomed-in cat. But the moon's horizon and background stars still fill. The cat spans x 330-660 (330 wide) — with 328 visible we'd barely crop the tail/board edges. Risky but okay-ish.
I think 'meet' is safer and standard. Let's use `preserveAspectRatio="xMidYMid meet"` with the SVG sized to 100%x100%, and the page background as a matching dark radial gradient. On narrow screens the whole scene shrinks and remains fully visible. That is graceful.
To make portrait nicer, I could set a media query for the SVG height, but the viewBox scaling handles it.
Let's go with:
```css
html,body{margin:0;height:100%;background:#05060f;overflow:hidden;}
body{display:grid;place-items:center;}
svg{width:100%;height:100%;display:block;}
```
And a background gradient on body to blend: `background: radial-gradient(ellipse at 50% 45%, #141a3a 0%, #080a1a 55%, #04050d 100%);` The SVG's own sky is opaque anyway, so the body bg only matters for letterbox areas. If the SVG sky has similar radial, the transition might be visible at edges. With a rect covering the whole viewBox that's opaque, there will be a hard edge at the SVG boundary. Hmm. To avoid the seam, use "meet" plus body background matching the average edge color. The SVG rect edges would be #070a18-ish. Let's make body background #07091a and the SVG sky gradient dark at the edges: radial gradient centered near the cat, with edges at #07091a. Then the seam is nearly invisible.
Actually, a cleaner approach: make the SVG `preserveAspectRatio="xMidYMid slice"` and `width:100%;height:100%` so no letterbox at all. And design the scene with content mostly in the central safe area (roughly x 250-750 vertical center). But then Earth at top-right would get cropped on portrait. That's okay — it's background.
Portrait: scale = max(375/1000, 800/700)=1.143, visible x range = 500 ± 164 → 336..664. The cat's arms reach x=640 (front paw), tail tip 350, board 330..670, shadow 310..690. So we'd crop the board ends slightly and the raised paw. Hmm, borderline.
Compromise: use `preserveAspectRatio="xMidYMid meet"` — no crop, all visible. I'll go with meet and a matching dark bg. That's the most reliable "graceful" adaptation.
Let me also add subtle vignette via CSS? Not needed.
Now let's write the code.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Astronaut Cat on the Moon</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#06070f;}
body{display:flex;align-items:center;justify-content:center;
background:radial-gradient(ellipse 80% 60% at 50% 50%, #0b0f26 0%, #06070f 70%);}
svg{width:100%;height:100%;display:block;max-width:1400px;}
/* animations */
@keyframes twinkle{0%,100%{opacity:.25}50%{opacity:1}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes sway{0%,100%{transform:rotate(-1.4deg)}50%{transform:rotate(1.4deg)}}
@keyframes tailsway{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(8deg)}}
@keyframes ear{0%,86%,100%{transform:rotate(0)}90%{transform:rotate(-8deg)}94%{transform:rotate(4deg)}}
@keyframes puffs{0%{transform:translate(0,0) scale(.6);opacity:0}
20%{opacity:.9}
100%{transform:translate(-190px,26px) scale(1.6);opacity:0}}
@keyframes glow{0%,100%{opacity:.55}50%{opacity:1}}
@keyframes gleam{0%,100%{opacity:0;transform:translateX(-30px)}40%{opacity:.9}60%{opacity:.9;transform:translateX(30px)}}
...
</style>
```
For the wheels: `#wheel1, #wheel2 { transform-box: fill-box; transform-origin: 50% 50%; animation: spin 1.6s linear infinite; }` But the wheel group includes the tire; spinning the whole wheel including the tire is fine if the tire is radially symmetric — hub and spokes spin visually. Better, spin only a `g.spin` inside each wheel containing spokes.
Careful with `transform-box: fill-box` on a `<g>`: works in Chrome.
Let me write the star generation JS:
```js
const g = document.getElementById('stars');
const NS='http://www.w3.org/2000/svg';
let seed=7;
function rnd(){seed=(seed*1103515245+12345)%2147483648;return seed/2147483648;}
let html='';
for(let i=0;i<110;i++){
const x=Math.round(rnd()*1000), y=Math.round(rnd()*640);
const r=(0.4+rnd()*1.5).toFixed(2);
const o=(0.25+rnd()*0.7).toFixed(2);
const d=(2+rnd()*4).toFixed(1), delay=(rnd()*5).toFixed(1);
html+=`<circle cx="${x}" cy="${y}" r="${r}" fill="#fff" opacity="${o}" style="animation:twinkle ${d}s ease-in-out ${delay}s infinite"/>`;
}
g.innerHTML=html;
```
Careful: stars behind the moon would be visible? The moon circle is drawn after stars, so it covers them. Good.
Also add a few bigger "sparkle" stars statically, drawn as 4-point star paths — put them in a separate group after? They'd be under the moon too if placed in the sky region. Fine.
Now the detailed SVG.
```svg
<svg viewBox="0 0 1000 700" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="sky" cx="50%" cy="52%" r="72%">
<stop offset="0" stop-color="#1b2350"/>
<stop offset="45%" stop-color="#0c1030"/>
<stop offset="100%" stop-color="#05060f"/>
</radialGradient>
<linearGradient id="moonG" x1="0" y1="470" x2="0" y2="760" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f4f6fc"/>
<stop offset="35%" stop-color="#cfd5e6"/>
<stop offset="100%" stop-color="#8d93ab"/>
</linearGradient>
<radialGradient id="earthG" cx="35%" cy="30%" r="80%">
<stop offset="0" stop-color="#63c6ff"/>
<stop offset="55%" stop-color="#2b76cf"/>
<stop offset="100%" stop-color="#0d2f63"/>
</radialGradient>
<linearGradient id="helmetG" x1="0" y1="0" x2="0.4" y2="1">
<stop offset="0" stop-color="#d7f4ff" stop-opacity="0.55"/>
<stop offset="45%" stop-color="#7fd4ff" stop-opacity="0.12"/>
<stop offset="100%" stop-color="#2a6fb0" stop-opacity="0.22"/>
</linearGradient>
<linearGradient id="suitG" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ffffff"/>
<stop offset="60%" stop-color="#e7edf8"/>
<stop offset="100%" stop-color="#c3cde0"/>
</linearGradient>
<linearGradient id="deckG" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#3a4670"/>
<stop offset="55%" stop-color="#1c2440"/>
<stop offset="100%" stop-color="#11162a"/>
</linearGradient>
<linearGradient id="furG" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#ffc37a"/>
<stop offset="100%" stop-color="#ef9448"/>
</linearGradient>
<radialGradient id="glowG">
<stop offset="0" stop-color="#8fe6ff" stop-opacity="0.5"/>
<stop offset="100%" stop-color="#8fe6ff" stop-opacity="0"/>
</radialGradient>
<filter id="blur6" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="6"/>
</filter>
<filter id="blur14" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="14"/>
</filter>
<filter id="soft" ...>
...
</defs>
```
Careful with filter regions on small objects; specify generous x/y/width/height.
Now the scene:
```svg
<rect width="1000" height="700" fill="url(#sky)"/>
<g id="stars"></g>
<!-- nebula glows -->
<ellipse cx="180" cy="180" rx="220" ry="150" fill="#3a2b7a" opacity=".18" filter="url(#blur14)"/>
<ellipse cx="820" cy="430" rx="180" ry="120" fill="#1e5a8a" opacity=".15" filter="url(#blur14)"/>
```
Planets:
- Earth at (830,145) r=44 with glow behind: circle r=62 fill url(#glowG)? Use a radial gradient glow with blue.
- A small ringed planet at (140, 120) r=22 with an ellipse ring rotated.
- Distant small moon at (250, 260) r=10.
Shooting star: a line with gradient, animated? Static fine, or slight move. Keep static: `<path d="M 700 70 L 790 30" stroke="url(#streak)" stroke-width="2.5" stroke-linecap="round"/>` with a gradient fading.
Moon:
```svg
<circle cx="500" cy="1420" r="940" fill="url(#moonG)"/>
```
Then craters clipped by the moon circle? Craters placed within y 490..700 are inside the circle nearly everywhere, but near the far left/right at y=500 it might be outside. At y=500, the circle spans x where (500-1420)²=846400; 883600-846400=37200; sqrt=193 → x from 307 to 693. So at y=500, only x 307..693 is moon. Placing craters at x<300, y<620 would be off the moon. I'll use a clipPath of the moon circle for the crater group. Good idea: `<clipPath id="moonClip"><circle cx="500" cy="1420" r="940"/></clipPath>` and group craters with clip-path.
Craters placement (visible region):
- (200, 640) scale 1.6
- (330, 560) scale 0.8 → at y=560, circle spans sqrt(883600 - 739600)=sqrt(144000)=379 → x from 121 to 879. So x=330 fine.
- (650, 545) scale 0.7
- (760, 620) scale 1.2
- (480, 690) scale 1.1 (bottom center, partly cut)
- (120, 690) scale 1.0
- (880, 690) scale 1.3
- (600, 660) scale .6
Also small ones.
Careful not to overlap the skateboard shadow. Fine.
Add a bright rim along the horizon: `<circle cx="500" cy="1420" r="940" fill="none" stroke="#ffffff" stroke-opacity=".55" stroke-width="3" filter="url(#blur2)"/>` plus a crisper one.
Also add a soft terminator shading: an ellipse over the moon's left with dark gradient? Skip or light.
Moon surface detail: add a few small rocks (paths) and dust texture dots.
Now the rider group:
```svg
<g id="rider">
<!-- shadow -->
<ellipse cx="500" cy="636" rx="180" ry="16" fill="#3d4258" opacity=".45" filter="url(#blur6)"/>
<ellipse cx="500" cy="632" rx="120" ry="9" fill="#2e3348" opacity=".35" filter="url(#blur6)"/>
...
</g>
```
Exhaust/dust puffs behind board:
```svg
<g opacity=".8">
<circle class="puff p1" cx="380" cy="612" r="8" fill="#eaf3ff" opacity=".7"/>
...
</g>
```
With CSS animation `puffs` and delays. But transform translate in CSS on an SVG element with cx/cy — translation works relative to the element's coordinate system, fine.
Place 5 puffs with varying sizes and delays.
Motion streaks:
```svg
<g stroke="#9fe9ff" stroke-linecap="round" opacity=".55">
<path d="M 250 596 H 330" stroke-width="3"/>
...
</g>
```
Maybe animate their opacity. Static is fine. Or use dashed lines that animate? Skip.
Now the cat.
Order:
1. tail (behind)
2. backpack
3. back arm
4. legs
5. torso
6. collar
7. front arm
8. head/ears
9. face
10. helmet glass + rim + highlight
11. helmet top antenna? A little antenna on the helmet: line from (560,325) to (585,290) with a glowing ball. Cute. But it would rotate with the helmet; static fine.
Hmm the helmet has ears inside that might poke through the glass; fine.
Wait: if the helmet glass is drawn over the head, and it's semi-transparent, the head is visible with a blue tint — correct look.
Let's write the shapes.
TAIL:
```svg
<g id="tail" style="transform-box: fill-box; transform-origin: 100% 85%; animation: tailsway 3.4s ease-in-out infinite;">
<path d="M 466 546 C 420 566 366 552 348 512 C 336 484 350 462 372 460"
fill="none" stroke="url(#furG)" stroke-width="20" stroke-linecap="round"/>
<path d="M 372 460 c 10 -2 18 4 18 12" fill="none" stroke="#ffe9cf" stroke-width="20" stroke-linecap="round"/>
</g>
```
Hmm, the tail tip: make the last bit cream. Actually stroke with a color change: two paths, the second overlapping. Simplify: tail stroke orange, tip circle cream.
Let's do:
```
<path d="M 468 548 C 415 572 358 550 348 508 C 342 482 356 466 378 466" fill="none" stroke="url(#furG)" stroke-width="19" stroke-linecap="round"/>
<circle cx="378" cy="466" r="9.5" fill="#ffe9cf"/>
```
Tail base at (468,548) — bottom right of bbox? bbox of that path: x from ~340 to 468, y from ~460 to 560. transform-origin 100% 100% → (468,560). Close to base. Good.
BACKPACK (behind torso, left side):
```svg
<g>
<rect x="398" y="472" width="86" height="100" rx="22" fill="#c9d4e8" stroke="#9fadc8" stroke-width="3"/>
<rect x="412" y="486" width="58" height="30" rx="10" fill="#e8eefa" stroke="#a9b6cf" stroke-width="2"/>
<circle cx="428" cy="530" r="6" fill="#6be1ff"/>
<circle cx="448" cy="530" r="6" fill="#6be1ff" opacity=".7"/>
<rect x="410" y="548" width="62" height="12" rx="6" fill="#b3c0d8"/>
</g>
```
Hmm, the backpack should be behind the torso, x 398..484 while torso starts at 452. It'd poke out to the left ~55px. Good.
Also add a little jet nozzle at the bottom-left of the backpack? Skip.
BACK ARM (left arm, behind torso):
```svg
<path d="M 470 500 C 448 512 430 528 424 546" fill="none" stroke="#dfe7f5" stroke-width="24" stroke-linecap="round"/>
<circle cx="420" cy="550" r="15" fill="#eef3fc" stroke="#c3cee2" stroke-width="3"/>
```
Hmm the hand should maybe be a paw with pads facing us. Let's make the back hand a rounded mitten with a pink pad:
`<ellipse cx="418" cy="552" rx="15" ry="13" fill="#f2f7ff" stroke="#c2cde2" stroke-width="3"/>` plus `<circle cx="418" cy="553" r="6" fill="#f7b0b8" opacity=".9"/>`. Cute.
Wait, an astronaut glove showing a paw pad? It's a stylized cat, sure — paw pads on gloves are adorable.
LEGS:
The legs are drawn from hips to feet, in white suit.
```svg
<!-- back leg -->
<path d="M 494 546 C 470 552 452 558 442 566" fill="none" stroke="#dfe7f5" stroke-width="30" stroke-linecap="round"/>
<!-- front leg -->
<path d="M 548 546 C 570 552 582 556 590 562" fill="none" stroke="#eef3fc" stroke-width="30" stroke-linecap="round"/>
```
Boots at the ends:
```svg
<g>
<path d="M 424 566 q 22 -2 26 8 q 2 10 -12 10 q -16 0 -18 -8 z" fill="#cfdaea" stroke="#b0bdd6" stroke-width="2"/>
</g>
```
Simpler: rounded rect rotated slightly, or ellipse:
`<ellipse cx="438" cy="570" rx="24" ry="12" fill="#d7e2f2" stroke="#aab8d2" stroke-width="2.5"/>` and a sole line `<path d="M 418 576 h 42" stroke="#93a3c0" stroke-width="4" stroke-linecap="round"/>`.
Hmm the deck top is at y=578, so boots at cy 570 with ry 12 → bottom 582. That overlaps the deck top by 4px. Fine, looks planted. Actually the deck rect y=578..598; boots bottom 582 slightly inside. Good.
Front boot: `<ellipse cx="590" cy="566" rx="24" ry="12" .../>`.
TORSO:
```svg
<path d="M 472 470
C 452 486 448 522 462 548
C 492 562 552 562 576 548
C 590 520 586 486 566 470 Z"
fill="url(#suitG)" stroke="#b9c6de" stroke-width="3"/>
```
Check: the torso is a barrel from (472,470) to (566,470), widening at the bottom to 462..576 at y=548. Good. Chest center around (519, 510).
Chest details:
- Panel: `<rect x="492" y="492" width="56" height="40" rx="10" fill="#dbe6f6" stroke="#a9b8d3" stroke-width="2.5"/>` then screen `<rect x="500" y="500" width="40" height="14" rx="4" fill="#4fd8f7"/>` with tiny bars.
- Buttons: circles r=4 at (502,522) green #7ef2a8 and (520,522) #ffd166.
- Belt: `<rect x="466" y="530" width="106" height="14" rx="7" fill="#c8d4e9" stroke="#a6b4cf"/>` but the torso narrows... At y=530, the torso spans roughly 458..580. Fine, belt x=464 w=110.
- A stripe: `<path d="M 476 476 C 470 486 468 496 468 506" stroke="#6be1ff" stroke-width="5" fill="none" stroke-linecap="round" opacity=".8"/>` on the shoulder.
- Mission patch: circle at (556, 486) r=10 fill #ffd166 with a star? Cute.
NECK/COLLAR:
```svg
<ellipse cx="519" cy="474" rx="52" ry="16" fill="#cdd9ec" stroke="#a7b5d0" stroke-width="3"/>
```
This sits at the bottom of the helmet (helmet bottom at 475). Good.
HEAD:
Head ellipse cx=520 cy=404 rx=55 ry=49 fill url(#furG).
But the helmet circle is cx=520 cy=395 r=80 → head fits inside (head bottom 453 < 475). Ears from y=322 to 375 — inside the helmet (top 315). Good.
Ears:
```svg
<g id="earL" style="transform-box: fill-box; transform-origin: 60% 100%; animation: ear 5s ease-in-out infinite;">
<path d="M 486 372 L 468 318 L 524 352 Z" fill="url(#furG)" stroke="#e08a41" stroke-width="2" stroke-linejoin="round"/>
<path d="M 490 366 L 478 330 L 512 352 Z" fill="#ffb9b0" opacity=".85"/>
</g>
```
Hmm inner ear should be smaller and inside. Fine.
Right ear:
```svg
<path d="M 554 372 L 572 318 L 516 352 Z" fill="url(#furG)" stroke="#e08a41" stroke-width="2"/>
<path d="M 550 366 L 562 330 L 528 352 Z" fill="#ffb9b0" opacity=".85"/>
```
Draw ears before the head so the head ellipse covers their bases. But then the inner ear might be covered too. Draw ears first (full triangles), then the head on top — the ear bases get covered, and the inner ear triangles extend above the head, still visible. Since the head top at cx 520 is y=355, the ear tips at 318 remain. Good.
Face:
Eyes at (498, 398) and (542, 398) — the head center x=520.
```svg
<g>
<ellipse cx="499" cy="398" rx="15" ry="16.5" fill="url(#eyeG)"/> <!-- gradient -->
<ellipse cx="543" cy="398" rx="15" ry="16.5" fill="url(#eyeG)"/>
<ellipse cx="499" cy="399" rx="4.5" ry="13" fill="#101a1c"/>
<ellipse cx="543" cy="399" rx="4.5" ry="13" fill="#101a1c"/>
<circle cx="494" cy="392" r="4.5" fill="#fff" opacity=".95"/>
<circle cx="538" cy="392" r="4.5" fill="#fff" opacity=".95"/>
<circle cx="503" cy="404" r="2.2" fill="#fff" opacity=".7"/>
<circle cx="547" cy="404" r="2.2" fill="#fff" opacity=".7"/>
</g>
```
eyeG: radial green: #b6ffcf → #34b47a → #14603f.
Muzzle:
```svg
<ellipse cx="510" cy="430" rx="16" ry="12" fill="#ffe9cf"/>
<ellipse cx="532" cy="430" rx="16" ry="12" fill="#ffe9cf"/>
```
Hmm they overlap at center. Fine, both cream. Maybe add a single rounded muzzle shape:
`<path d="M 502 424 q 18 -6 36 0 q 4 12 -8 16 q -10 3 -20 0 q -12 -4 -8 -16 z" fill="#ffe9cf"/>` — messy. Use two ellipses.
Nose: `<path d="M 514 415 L 528 514?"` no: `M 514 414 L 526 414 Q 527 419 520 423 Q 513 419 514 414 Z` fill #f28d9b.
Mouth: `<path d="M 520 423 v 5 M 520 428 q -7 6 -13 1 M 520 428 q 7 6 13 1" stroke="#a9713f" stroke-width="2.5" fill="none" stroke-linecap="round"/>`.
Whiskers:
```svg
<g stroke="#fff" stroke-width="2.2" stroke-linecap="round" opacity=".85">
<path d="M 498 426 L 462 418"/>
<path d="M 496 432 L 458 432"/>
<path d="M 498 438 L 464 446"/>
<path d="M 542 426 L 578 418"/>
<path d="M 544 432 L 582 432"/>
<path d="M 542 438 L 576 446"/>
</g>
```
Whiskers extending beyond the head (head spans 465..575) — at x=578, that's just inside the helmet circle (helmet at y=418 spans x 520±sqrt(6400-529)=520±76.6 → 443..597). OK, whiskers inside the helmet. Good.
Forehead stripes:
```svg
<g stroke="#e08a41" stroke-width="4" stroke-linecap="round" opacity=".7" fill="none">
<path d="M 508 366 l -4 -14"/>
<path d="M 520 362 l 0 -16"/>
<path d="M 532 366 l 4 -14"/>
</g>
```
Head top at 355 near center, so these strokes at y 346-366 are near the top edge. Fine.
Cheeks blush: `<ellipse cx="482" cy="424" rx="8" ry="5" fill="#ff9aa5" opacity=".45"/>` and mirrored.
HELMET:
```svg
<circle cx="520" cy="395" r="80" fill="url(#helmetG)" stroke="#dff4ff" stroke-width="4" stroke-opacity=".9"/>
<path d="M 462 350 A 78 78 0 0 1 528 322" fill="none" stroke="#ffffff" stroke-width="9" stroke-linecap="round" opacity=".75"/>
<path d="M 566 448 A 80 80 0 0 0 592 400" fill="none" stroke="#bfe9ff" stroke-width="6" stroke-linecap="round" opacity=".5"/>
```
The highlight arc on the upper-left. Good.
Antenna:
```svg
<line x1="580" y1="330" x2="606" y2="292" stroke="#cfd9ea" stroke-width="4" stroke-linecap="round"/>
<circle cx="608" cy="288" r="7" fill="#6be1ff"/>
<circle cx="608" cy="288" r="14" fill="#6be1ff" opacity=".3"/>
```
Hmm the antenna should attach to the helmet rim at the upper right. The helmet at y=330 spans x up to 520+sqrt(6400-4225)=520+46.6=566. So (580,330) is outside the helmet. Start at (566,332) → (596,298). Fine. But it may look like it's coming out of the glass. That's fine and fun.
Actually, the antenna might clutter. I'll include it small.
FRONT ARM (right, raised):
```svg
<path d="M 566 492 C 592 486 616 470 630 448" fill="none" stroke="#eef3fc" stroke-width="26" stroke-linecap="round"/>
```
Then a cuff stripe near the end: `<path d="M 596 482 l 12 -10" stroke="#6be1ff" stroke-width="6"/>` roughly perpendicular—hard. Skip or use a small arc.
Paw at (636, 440):
```svg
<ellipse cx="636" cy="440" rx="18" ry="17" fill="#f7fbff" stroke="#c2cde2" stroke-width="3"/>
<ellipse cx="636" cy="444" rx="9" ry="7" fill="#f7b0b8" opacity=".95"/>
<circle cx="626" cy="432" r="3.5" fill="#f7b0b8" opacity=".95"/>
<circle cx="636" cy="429" r="3.5" fill="#f7b0b8" opacity=".95"/>
<circle cx="646" cy="432" r="3.5" fill="#f7b0b8" opacity=".95"/>
```
Cute paw pad in a raised waving hand.
Now, the front arm overlaps the torso — draw after the torso.
Anything else: a "MEOW" text bubble? Let's skip.
Now check: is the head overlapping the collar? The head bottom is 453, collar at 474. There's a gap — the neck. Draw a neck rect from y=440 to 480 behind the collar: `<rect x="498" y="440" width="44" height="40" rx="18" fill="#e6edf8"/>` drawn after the head? Better drawn before the head, so the head overlaps it. Order: torso, neck, collar, head, ears... wait ears behind head. Order: backpack, back arm, legs, torso, neck, collar, ears, head, face, helmet, front arm (arm in front of torso but behind helmet? The raised arm attaches at the shoulder around (566,492), below the helmet. Fine either way — draw the arm before the helmet so the helmet rim is on top).
Hmm, the helmet bottom is at y=475, and the front arm starts at (566,492), below. No overlap. OK.
Let me reorder the rider group:
1. shadow
2. tail
3. backpack
4. back arm
5. legs (back & front), boots
6. torso
7. chest details, belt, patch
8. neck, collar
9. ears
10. head
11. face
12. helmet glass, rim, highlight, antenna
13. front arm + paw
Wait, the front arm should be over the torso, fine at 13.
But the front arm at the shoulder (566,492) — the helmet is at y up to 475, so no overlap. Good.
Skateboard: draw before the cat (so the cat's boots are on top of the deck):
- trucks, wheels, deck.
Order in the rider group: shadow, board (trucks, wheels, deck), then cat.
Board deck at y=578..598 and the cat's boots at 570 → boots overlap the deck top. Good.
Let me write the board:
```svg
<g id="board">
<!-- trucks -->
<path d="M 398 596 h 30 v 8 h -30 z" ... />
```
Simpler:
```svg
<rect x="400" y="592" width="26" height="14" rx="4" fill="#8f9cb8"/>
<rect x="574" y="592" width="26" height="14" rx="4" fill="#8f9cb8"/>
```
Then wheels at (413, 612) and (587, 612).
Wheel group:
```svg
<g class="wheel" style="transform-box: fill-box; transform-origin: 50% 50%;">
<circle cx="413" cy="612" r="19" fill="#1b2236" stroke="#0e1322" stroke-width="3"/>
<circle cx="413" cy="612" r="12" fill="#3c4a6b"/>
<g class="spokes" style="...animation: spin...">
<circle cx="413" cy="612" r="12" fill="none" stroke="#6be1ff" stroke-width="2.5" opacity=".8" stroke-dasharray="6 7"/>
</g>
<circle cx="413" cy="612" r="5" fill="#6be1ff"/>
</g>
```
A dashed circle spinning looks like a rotating hub — good trick.
Deck:
```svg
<path d="M 340 586
Q 336 574 352 574
H 648
Q 664 574 660 586
L 656 594
Q 654 600 644 600
H 356
Q 346 600 344 594 Z" fill="url(#deckG)" stroke="#0c1020" stroke-width="3"/>
```
Hmm, let me define a simpler deck: a rounded rect with slight upward curves at the ends (kicktails).
Deck:
```
M 330 578
C 330 570 336 568 348 568
L 652 568
C 664 568 670 570 670 578
L 670 586
C 670 594 664 596 652 596
L 348 596
C 336 596 330 594 330 586
Z
```
That's just a rounded rect 330..670, 568..596 with rounded ends. Fine. Top surface at 568? But I planned boots at 570 with the deck top at 578. Let me set the deck top at y=576 and bottom at 596, i.e. rounded rect x=330 y=576 w=340 h=20 rx=10. Then the boots at cy 570/566 with ry 12 → bottoms at 582/578, sitting into the deck. Good — the front boot at cy=566 (bottom 578) sits on top, the back boot at cy=570 (bottom 582) slightly in. Let's make both boots bottom ≈ 578: back boot cy=568 ry=11 → 579; front boot cy=566 ry=11 → 577. OK.
Deck: rounded rect x=330 y=576 w=340 h=20 rx=10, fill url(#deckG).
Grip tape top strip: rect x=336 y=578 w=328 h=6 rx=3 fill="#6be1ff" opacity=".55".
A star sticker: `<path d="M 620 586 l 3 6 7 1 -5 5 1 7 -6 -3 -6 3 1 -7 -5 -5 7 -1 z" fill="#ffd166"/>` small.
A stripe near the middle: rect x=480 y=584 w=60 h=4 rx=2 fill="#6be1ff" opacity=".5".
Wheels at (405, 612) and (595, 612), r=19, bottom = 631.
Trucks: rect x=392 y=594 w=26 h=14 and x=582 y=594 w=26 h=14, fill #93a0bb.
Hmm the wheel centers x=405 and 595; trucks should be at the same x. rect x=392 w=26 → center 405. Good.
Ground contact at y=631. Shadow ellipse cy=634.
Moon horizon at center y=480; board at 576-631. Fine.
Now, is the cat too high above the board relative to the horizon? It's fine.
Now scale check: the cat from y=318 (ear tip) to 631 (wheels) = 313 tall, x from ~330 to 660. Centered nicely in the 1000x700 canvas, slightly right of center at x=500.
Potential issue: the raised front paw at x=636..654 and the board's right end at 670. Fine.
Let's also add a small floating cat-themed detail? No.
Add a distant "lunar module" or flag? Might be nice for context but risks clutter. Maybe a tiny flag on the left horizon at (150, 470)? The horizon at x=150 is y = 1420 - sqrt(883600 - 122500) = 1420 - 872 = 548. So a flag pole base at (150, 548). Small flag with a star, height 60. It adds story. Let's add a simple flag: pole line from (140,548) to (140,488), flag path from (140,490) to (176,498) to (140,508). Fill red/white? For a moon scene, keep it neutral: a blue pennant. Could be cute but might distract. I'll add a small crater-side footprint trail instead? Footprints are a nice touch: small paw prints leading away on the moon surface. Actually cat paw prints on the moon — adorable! Let's add a trail of small paw prints curving from the bottom-left to the horizon.
Paw print: 4 small toe circles + a pad ellipse. At small scale, a simple version:
```svg
<g id="paw" fill="#9aa2ba" opacity=".55">
<ellipse cx="0" cy="0" rx="9" ry="7"/>
<circle cx="-7" cy="-8" r="3"/>
<circle cx="-1" cy="-11" r="3"/>
<circle cx="5" cy="-8" r="3"/>
</g>
```
Then `<use href="#paw" transform="translate(180,650) scale(1.2)"/>` etc. Making them recede toward the horizon with decreasing scale and lighter opacity. Place along a curve: (160,660) s=1.1; (240,630) 0.95; (310,608) 0.8... but that's under the board region. Put the trail on the left side, going from the bottom-left up toward the horizon mid-left: (150,690) → (230,650) → (300,615) → (350,590)? The board occupies 330-670 at y 576-630, so the trail would run into the board. That's fine — it's behind. Maybe just 4 prints at the left going off toward the horizon.
I think it adds charm. Keep opacity low (0.35) and color #b9c0d4 darker than the surface. Hmm, on the bright moon surface, the paws should be a slightly darker gray. Use fill "#8f96ad" opacity .35.
Placement: (120, 672) scale 1.3, (196, 640) scale 1.1, (262, 616) scale .95, (318, 598) scale .85, then maybe hidden behind the board.
Hmm, but the horizon at x=120 is y=560, so y=672 is well onto the surface. Good.
Careful: the paw prints are drawn inside the moon clip after the craters.
Now let's also add small rocks: a few polygon paths at the surface near the edges, fill #b6bdd0 with shadow.
Alright. Also add stars twinkling and a shooting star animation across the sky? A shooting star that loops every 8s would be a nice touch, and a screenshot at 3s might catch it. Let's add one with animation from 0 to 1 over 7s with 3s delay — might not be visible at the screenshot time. Keep it always partially visible: a static shooting star trail, plus a subtle animated one. I'll do a static streak.
Let me now think about the CSS animation names and avoid conflicts.
Animations:
- `twinkle` for stars (opacity)
- `spin` wheels
- `sway` cat body
- `tail` tail
- `earTwitch`
- `puff` dust
- `pulse` Earth glow / antenna glow
- `gleam` on helmet
I want the whole cat (not the board) to sway. Group `#cat` around all cat parts, with transform-box: view-box and origin at (520, 570). CSS:
```css
#cat{transform-box:view-box;transform-origin:520px 568px;animation:sway 4.2s ease-in-out infinite;}
@keyframes sway{0%,100%{transform:rotate(-1.3deg)}50%{transform:rotate(1.3deg)}}
```
Wait — `transform-box: view-box` means the transform origin is relative to the viewBox origin. `transform-origin: 520px 568px` then means the point (520,568) in the nearest SVG viewport coordinates. That should work in Chrome.
But careful: when `transform-box: view-box` is used with transform-origin percentages/px, it resolves against the viewBox. Yes, supported.
The tail is inside #cat with its own animation — nested transforms are fine.
Potential issue: `#cat` contains `#tail` which has its own transform with fill-box origin. Nested transforms compose fine.
Now, does a 1.3deg sway around (520,568) move the head noticeably? The head is ~230px above the pivot, so it moves ~5px. Nice subtle motion.
Dust puffs: they should be behind the board, drawn before the board in the "ground fx" group. Put them in `<g id="dust">` after the shadow but before the board.
Let's write the puff CSS:
```css
.puff{transform-box:fill-box;transform-origin:center;animation:puff 2.2s ease-out infinite;}
@keyframes puff{
0%{transform:translate(0,0) scale(.4);opacity:0}
15%{opacity:.85}
100%{transform:translate(-170px,22px) scale(1.5);opacity:0}
}
```
With delays 0, .45s, .9s, 1.35s, 1.8s on 4-5 circles near the back wheel (x≈390, y≈615) and maybe near the front wheel too.
Hmm, on the moon there's no air, but dust kicked by wheels is fine artistically.
The `translate` in CSS for SVG applies in the local coordinate system (user units). Good.
Also add motion streaks behind: 3 horizontal lines with a `dash` animation? Static is fine:
```svg
<g stroke="#8fe6ff" stroke-linecap="round" opacity=".35">
<path d="M 250 590 h 60" stroke-width="4"/>
<path d="M 210 612 h 90" stroke-width="3"/>
<path d="M 270 630 h 50" stroke-width="3"/>
</g>
```
These would be over the moon surface (drawn after the moon, but before the rider). Good.
Now, let's write the full code. I'll be careful with syntax.
One more consideration: the SVG is inside HTML, so `<style>` in the head applies. Fine.
Let me write out the whole file.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Astronaut Cat · Moon Skate</title>
<style>
html,body{margin:0;padding:0;height:100%;background:#05060f;overflow:hidden;}
body{
display:flex;align-items:center;justify-content:center;
background:radial-gradient(ellipse 75% 70% at 50% 48%, #10142e 0%, #080a18 55%, #05060f 100%);
}
svg{width:100%;height:100%;display:block;}
...
</style>
</head>
<body>
<svg viewBox="0 0 1000 700" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="An astronaut cat skateboarding on the moon">
...
</svg>
<script>...</script>
</body>
</html>
```
Now the defs and elements in full.
I should double check the total area: is the composition balanced? Cat centered at x≈500, y≈470. Earth at top-right (830,150). Ringed planet at top-left (150,130). Moon horizon at y≈480 at center. Cat head at 395 sits above the horizon, body crosses it. Good.
Sky is 0..480 in the center; stars fill 0..640 in the background, but they'd show only above the horizon. Some stars at y>480 will be covered by the moon. Fine.
Let's write the crater use elements with the clip.
Also add a subtle glow behind the moon's horizon: a path along the horizon with a blue glow.
I need a `#horizonGlow`: `<circle cx="500" cy="1420" r="940" fill="none" stroke="#bcd9ff" stroke-width="10" opacity=".35" filter="url(#blur6)"/>` drawn over the moon. Good.
Now let's write everything concretely.
```svg
<defs>
<radialGradient id="skyG" cx="50%" cy="50%" r="70%">
<stop offset="0" stop-color="#1a2350"/>
<stop offset="42%" stop-color="#0d1231"/>
<stop offset="100%" stop-color="#05060f"/>
</radialGradient>
<linearGradient id="moonG" x1="0" y1="470" x2="0" y2="780" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f7f9ff"/>
<stop offset="30%" stop-color="#d5dbeb"/>
<stop offset="68%" stop-color="#aab1c8"/>
<stop offset="100%" stop-color="#828aa3"/>
</linearGradient>
<radialGradient id="earthG" cx="34%" cy="28%" r="82%">
<stop offset="0" stop-color="#8fe4ff"/>
<stop offset="40%" stop-color="#2f86d8"/>
<stop offset="100%" stop-color="#0b2a5c"/>
</radialGradient>
<radialGradient id="earthGlowG">
<stop offset="0" stop-color="#5fc8ff" stop-opacity=".55"/>
<stop offset="55%" stop-color="#2b7fd0" stop-opacity=".18"/>
<stop offset="100%" stop-color="#2b7fd0" stop-opacity="0"/>
</radialGradient>
<linearGradient id="helmetG" x1="20%" y1="0%" x2="60%" y2="100%">
<stop offset="0" stop-color="#e8fbff" stop-opacity=".55"/>
<stop offset="50%" stop-color="#9fe0ff" stop-opacity=".10"/>
<stop offset="100%" stop-color="#2f6fa8" stop-opacity=".28"/>
</linearGradient>
<linearGradient id="suitG" x1="10%" y1="0%" x2="80%" y2="100%">
<stop offset="0" stop-color="#ffffff"/>
<stop offset="55%" stop-color="#e9eef8"/>
<stop offset="100%" stop-color="#c0cbe0"/>
</linearGradient>
<linearGradient id="furG" x1="0%" y1="0%" x2="20%" y2="100%">
<stop offset="0" stop-color="#ffcb8b"/>
<stop offset="100%" stop-color="#ee9345"/>
</linearGradient>
<radialGradient id="eyeG" cx="40%" cy="30%" r="75%">
<stop offset="0" stop-color="#c9ffd9"/>
<stop offset="55%" stop-color="#4fc98a"/>
<stop offset="100%" stop-color="#12603c"/>
</radialGradient>
<linearGradient id="deckG" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0" stop-color="#3d4a74"/>
<stop offset="50%" stop-color="#1d2542"/>
<stop offset="100%" stop-color="#101527"/>
</linearGradient>
<linearGradient id="ringG" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ffd9a0"/>
<stop offset="100%" stop-color="#c78d5a"/>
</linearGradient>
<linearGradient id="streakG" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#ffffff" stop-opacity="0"/>
<stop offset="100%" stop-color="#dff3ff" stop-opacity=".9"/>
</linearGradient>
<filter id="blurSoft" x="-40%" y="-40%" width="180%" height="180%">
<feGaussianBlur stdDeviation="7"/>
</filter>
<filter id="blurBig" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="18"/>
</filter>
<clipPath id="moonClip"><circle cx="500" cy="1420" r="940"/></clipPath>
<g id="crater">
<ellipse rx="40" ry="13" fill="#7c848f" opacity=".22"/>
<ellipse cy="-2" rx="34" ry="9" fill="#ffffff" opacity=".35"/>
<ellipse cy="1" rx="26" ry="6" fill="#8d95a4" opacity=".28"/>
</g>
<g id="pawPrint">
<ellipse cy="0" rx="9" ry="7.5" fill="#7f879b"/>
<circle cx="-7.5" cy="-8.5" r="3.2" fill="#7f879b"/>
<circle cx="-2.5" cy="-11" r="3.2" fill="#7f879b"/>
<circle cx="2.5" cy="-11" r="3.2" fill="#7f879b"/>
<circle cx="7.5" cy="-8.5" r="3.2" fill="#7f879b"/>
</g>
</defs>
```
Note on `<g id="crater">` inside defs with ellipses without cx/cy — default 0. Good.
Now the scene body.
```svg
<rect width="1000" height="700" fill="url(#skyG)"/>
<!-- nebula -->
<g filter="url(#blurBig)" opacity=".55">
<ellipse cx="190" cy="170" rx="200" ry="120" fill="#3a2f7d" opacity=".35"/>
<ellipse cx="850" cy="470" rx="160" ry="90" fill="#1d5a7d" opacity=".28"/>
<ellipse cx="620" cy="120" rx="150" ry="80" fill="#4a2b63" opacity=".22"/>
</g>
<g id="stars"></g>
<!-- sparkle stars (static) -->
<g fill="#ffffff">
<path d="M 300 90 l 3 10 10 3 -10 3 -3 10 -3 -10 -10 -3 10 -3 z" opacity=".9"/>
<path d="M 700 210 l 2.5 8 8 2.5 -8 2.5 -2.5 8 -2.5 -8 -8 -2.5 8 -2.5 z" opacity=".75"/>
<path d="M 860 300 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".6"/>
<path d="M 120 340 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".6"/>
</g>
```
Hmm, `path` with `l` commands and negative values — let me verify the first sparkle: start (300,90), l 3 10 → (303,100); l 10 3 → (313,103); l -10 3 → (303,106); l -3 10 → (300,116); l -3 -10 → (297,106); l -10 -3 → (287,103); l 10 -3 → (297,100); close → back to (300,90). Yes, a 4-point star.
Earth:
```svg
<g>
<circle cx="830" cy="150" r="120" fill="url(#earthGlowG)"/>
<circle cx="830" cy="150" r="46" fill="url(#earthG)"/>
<g opacity=".85">
<path d="M 806 128 q 16 -10 28 2 q 8 8 -2 16 q -12 8 -22 -2 q -8 -8 -4 -16 z" fill="#4fbf7a" opacity=".8"/>
<path d="M 848 160 q 14 -4 18 8 q 2 10 -10 12 q -12 0 -12 -10 q 0 -8 4 -10 z" fill="#4fbf7a" opacity=".7"/>
<ellipse cx="822" cy="176" rx="16" ry="6" fill="#4fbf7a" opacity=".5"/>
</g>
<path d="M 812 120 q 26 -14 48 6" stroke="#ffffff" stroke-width="4" fill="none" opacity=".55" stroke-linecap="round"/>
<path d="M 800 168 q 22 12 46 2" stroke="#ffffff" stroke-width="3" fill="none" opacity=".4" stroke-linecap="round"/>
<circle cx="830" cy="150" r="46" fill="none" stroke="#b9e8ff" stroke-width="2" opacity=".6"/>
</g>
```
Earth radius 46, center (830,150): top at 104, right at 876. OK.
Ringed planet top-left:
```svg
<g>
<circle cx="150" cy="120" r="24" fill="#e0a17a"/>
<circle cx="150" cy="120" r="24" fill="url(#ringG)" opacity=".35"/>
<ellipse cx="150" cy="120" rx="44" ry="12" fill="none" stroke="url(#ringG)" stroke-width="5" transform="rotate(-18 150 120)" opacity=".85"/>
<circle cx="142" cy="112" r="7" fill="#c9865f" opacity=".6"/>
<circle cx="158" cy="130" r="5" fill="#c9865f" opacity=".5"/>
</g>
```
The ring should ideally pass behind the planet on the far side. Simpler: draw the full ellipse ring, then re-draw the top half of the planet over it? Standard trick: draw ring, then circle, then the front half of the ring. Let's not over-engineer; a thin ellipse over the planet reads fine.
Actually the ring over the planet looks wrong. Let's do: ring ellipse (full), then planet circle on top, then the front arc of the ring (bottom half) on top:
```svg
<ellipse ... ring/>
<circle planet/>
<path d="M 106 120 A 44 12 0 0 0 194 120" transform="rotate(-18 150 120)" ... />
```
Hmm the arc math is fiddly. Alternative: draw the ring ellipse behind, then the planet, then a partial ellipse path via stroke-dasharray?
Easiest: draw the ring twice — full ellipse below the planet, and an arc below the planet's horizontal center drawn above. Since the ring is rotated -18deg, the "front" half is the lower half. Path: `M -44 0 A 44 12 0 0 0 44 0` in local coordinates (sweep going through the bottom), then transform translate(150,120) rotate(-18).
Path with A: from (-44,0) to (44,0), rx=44 ry=12, large-arc=0, sweep=0 → sweep 0 goes counterclockwise, which from the left point to the right point goes... In SVG, sweep-flag=1 means the arc is drawn in the positive angle direction (clockwise in the standard screen coordinate system where y is down). From (-44,0) to (44,0) with sweep=0 (counterclockwise) → passes through (0,-12) (top). With sweep=1 → passes through (0,12) (bottom). We want the bottom (front) → sweep=1.
So `<path d="M -44 0 A 44 12 0 0 1 44 0" transform="translate(150,120) rotate(-18)" fill="none" stroke="url(#ringG)" stroke-width="5"/>`.
And the planet radius 24 with the ring at ry=12: the ring will cross the planet. Good enough.
Hmm, ring rx=44 vs planet r=24 — the ring extends beyond. Fine.
Also add a small distant moon at (280,300) r=8 fill #cfd6e6 opacity .5.
Shooting star:
```svg
<g class="shoot" opacity=".85">
<path d="M 690 96 L 792 52" stroke="url(#streakG)" stroke-width="3" stroke-linecap="round"/>
<circle cx="792" cy="52" r="2.5" fill="#ffffff"/>
</g>
```
Hmm the streakG direction: from transparent at left to bright at right — the tail fades behind. Good.
Now the moon:
```svg
<g>
<circle cx="500" cy="1420" r="940" fill="url(#moonG)"/>
<g clip-path="url(#moonClip)">
<!-- craters -->
<use href="#crater" transform="translate(190,655) scale(1.7,1.5)"/>
<use href="#crater" transform="translate(320,570) scale(.85,.8)"/>
<use href="#crater" transform="translate(690,560) scale(.75,.7)"/>
<use href="#crater" transform="translate(790,640) scale(1.5,1.3)"/>
<use href="#crater" transform="translate(470,690) scale(1.2,1.1)"/>
<use href="#crater" transform="translate(90,610) scale(1.0,.9)"/>
<use href="#crater" transform="translate(880,700) scale(1.4,1.2)"/>
<use href="#crater" transform="translate(600,675) scale(.6,.55)"/>
<use href="#crater" transform="translate(380,640) scale(.45,.4)"/>
<use href="#crater" transform="translate(140,530) scale(.5,.45)"/>
<use href="#crater" transform="translate(740,520) scale(.4,.35)"/>
<!-- paw prints -->
<g opacity=".3">
<use href="#pawPrint" transform="translate(120,672) scale(1.3)"/>
<use href="#pawPrint" transform="translate(196,640) scale(1.1)"/>
<use href="#pawPrint" transform="translate(258,614) scale(.95)"/>
<use href="#pawPrint" transform="translate(310,596) scale(.8)"/>
<use href="#pawPrint" transform="translate(352,584) scale(.7)"/>
</g>
<!-- rocks -->
<g fill="#8f97ad" opacity=".55">
<path d="M 236 690 l 14 -10 16 6 4 14 -18 8 -16 -6 z"/>
<path d="M 706 668 l 10 -8 12 4 3 10 -13 6 -12 -4 z"/>
<path d="M 88 640 l 8 -6 9 3 2 8 -10 5 -9 -3 z"/>
</g>
</g>
<!-- horizon glow -->
<circle cx="500" cy="1420" r="940" fill="none" stroke="#cfe4ff" stroke-width="12" opacity=".5" filter="url(#blurSoft)"/>
<circle cx="500" cy="1420" r="940" fill="none" stroke="#ffffff" stroke-width="2" opacity=".55"/>
</g>
```
Wait: the crater at (140,530) — is it on the moon? At y=530, the moon spans x = 500 ± sqrt(883600 - (1420-530)²) = sqrt(883600-792100)=sqrt(91500)=302 → x from 198 to 802. So (140,530) is off the moon — clipped away, invisible. Fine, or move it to (240,540).
Similarly (740,520): at y=520, sqrt(883600-810000)=271 → x 229..771. So 740 is on the moon. Good.
Rocks at (88,640): at y=640, dy=780 → 608400; 883600-608400=275200 → 524.6 → x from -24.6 to 1024. So x=88 is on the moon. Good.
Crater (90,610): dy=810 → 656100; 883600-656100=227500 → 477 → x 23..977. Good.
Paw prints: (352,584) — the moon spans at y=584: dy=836 → 698896; 883600-698400... let me compute 883600-698896=184704 → 429.8 → x 70..930. Fine.
Now, the crater `use` with `scale(1.7,1.5)` — the shape has rx=40 → 68 wide. OK.
Note: `<use href="#crater">` uses the modern `href` attribute. Chrome supports `href` on `<use>` (SVG2). Yes, Chrome supports it.
The `#pawPrint` group has elements at negative cy, so with translate it's positioned around the translate point. Fine.
Hmm — will the paw prints at opacity .3 with fill #7f879b be visible against the moon gradient (#aab1c8 at that region)? At y=640, the moon gradient (470→780) is at 55% → around #b7bed2 maybe. A #7f879b at 30% opacity gives a subtle darker print. Good, subtle.
Now, motion streaks and dust, then the rider.
```svg
<!-- speed streaks -->
<g stroke="#a9efff" stroke-linecap="round" opacity=".35">
<path d="M 236 588 h 72" stroke-width="4"/>
<path d="M 186 612 h 118" stroke-width="3"/>
<path d="M 262 634 h 62" stroke-width="3"/>
<path d="M 150 660 h 70" stroke-width="2.5" opacity=".6"/>
</g>
```
Hmm these float over the moon surface. Fine.
Shadow + board:
```svg
<g id="rider">
<!-- shadow -->
<ellipse cx="500" cy="636" rx="190" ry="18" fill="#5b6480" opacity=".35" filter="url(#blurSoft)"/>
<ellipse cx="500" cy="632" rx="120" ry="10" fill="#414a66" opacity=".3" filter="url(#blurSoft)"/>
<!-- dust puffs -->
<g fill="#eaf4ff">
<circle class="puff" cx="392" cy="620" r="9" opacity="0"/>
...
</g>
```
With the `puff` animation controlling opacity, starting at opacity 0 in the keyframes. Set base opacity via CSS `opacity:0`? The animation sets it. Fine to just use the class.
Actually, the animation's 0% sets opacity 0 and 15% .85; before the animation starts (delay), the element uses its own specified opacity — set `.puff{opacity:0}` to avoid a flash. Good.
Where do the puffs start? Behind the back wheel at (405, 620). Start at (400, 618) and move left-down to (230, 640).
```svg
<circle class="puff p1" cx="400" cy="616" r="10"/>
<circle class="puff p2" cx="380" cy="624" r="7"/>
<circle class="puff p3" cx="392" cy="628" r="12"/>
<circle class="puff p4" cx="372" cy="612" r="6"/>
<circle class="puff p5" cx="386" cy="612" r="5"/>
```
Delays: `.p1{animation-delay:0s} .p2{.35s} .p3{.7s} .p4{1.05s} .p5{1.4s}`.
Then the board:
```svg
<g id="board">
<!-- trucks -->
<rect x="392" y="592" width="26" height="16" rx="5" fill="#8b98b6"/>
<rect x="582" y="592" width="26" height="16" rx="4" fill="#8b98b8"/>
...
```
Hmm the truck rects extend below the deck into the wheel area. Wheel center y=612, r=19 → top 593. The truck rect from 592 to 608 sits behind the wheel. Fine.
Wheels:
```svg
<g>
<circle cx="405" cy="612" r="19" fill="#1c2338" stroke="#0b0f1c" stroke-width="3"/>
<circle cx="405" cy="612" r="12" fill="#39476b"/>
<circle cx="405" cy="612" r="11" fill="none" stroke="#6be1ff" stroke-width="2.5" stroke-dasharray="5 7" opacity=".85" class="spin"/>
<circle cx="405" cy="612" r="4.5" fill="#6be1ff"/>
</g>
<g>
<circle cx="595" cy="612" r="19" .../>
...
</g>
```
For the spokes animation, I'll apply the CSS class `.spin{transform-box:fill-box;transform-origin:center;animation:spin 1.4s linear infinite}`. On a `<circle>` the fill-box is the circle's bbox → origin = the wheel center.
Deck:
```svg
<rect x="330" y="576" width="340" height="22" rx="11" fill="url(#deckG)" stroke="#0a0e1c" stroke-width="3"/>
<rect x="338" y="580" width="324" height="7" rx="3.5" fill="#6be1ff" opacity=".5"/>
<rect x="470" y="590" width="60" height="4" rx="2" fill="#6be1ff" opacity=".45"/>
<path d="M 620 582 l 3.2 6.4 7 1 -5 5 1.2 7 -6.4 -3.4 -6.4 3.4 1.2 -7 -5 -5 7 -1 z" fill="#ffd166"/>
```
Hmm the star at y≈582-602 would extend below the deck (which ends at 598). The star path spans y from 582 to 601 — slightly below. Let me shrink and shift up: use a smaller star centered at (620, 586) with radius ~8. Let's compute points for a 5-point star-ish sparkle: keep it simple as a 4-point sparkle:
`<path d="M 620 578 l 2.5 7 7 2.5 -7 2.5 -2.5 7 -2.5 -7 -7 -2.5 7 -2.5 z" fill="#ffd166"/>` spans y 578..597, x 613..627. Good, within the deck (576-598).
Also add a rocket decal on the deck? Skip.
Now the cat group.
```svg
<g id="cat">
<!-- tail -->
<g id="tail">
<path d="M 468 546 C 416 574 356 552 346 508 C 340 482 354 462 378 462"
fill="none" stroke="url(#furG)" stroke-width="19" stroke-linecap="round"/>
<circle cx="378" cy="462" r="9.5" fill="#ffe9cf"/>
<path d="M 366 470 q 14 -4 22 4" stroke="#e08a41" stroke-width="3" fill="none" opacity=".6" stroke-linecap="round"/>
</g>
```
Hmm, tail stripes: add a couple of short arcs across the tail. Might be fiddly. Add 2 small arcs.
Careful: the tail's stroke is 19 wide; the path from (468,546) sweeping to (346,508) and up to (378,462). Is the tail overlapping the board or the legs? The tail is behind the torso; its base at (468,546) is near the hip. It extends left to x=337. The board starts at x=330 — so the tail is above the deck (deck top at 576, tail at 462-574 at most). The tail's lowest point: control points at y≈574 → the curve might dip to ~560. That's above the deck at 576. Good.
Wait, the tail base at (468,546) is under the torso (which covers to y=548). Slight overlap. Good.
Backpack:
```svg
<g id="backpack">
<rect x="396" y="466" width="90" height="104" rx="24" fill="#c9d5e9" stroke="#9dabc6" stroke-width="3"/>
<rect x="410" y="480" width="62" height="30" rx="10" fill="#eaf1fb" stroke="#a8b6cf" stroke-width="2"/>
<circle cx="426" cy="527" r="6" fill="#6be1ff"/>
<circle cx="446" cy="527" r="6" fill="#6be1ff" opacity=".65"/>
<rect x="408" y="544" width="66" height="12" rx="6" fill="#aebbd4"/>
</g>
```
The backpack is at x 396-486, y 466-570. Hmm, it extends to y=570, below the hips — that's fine (a backpack/pack). But it might overlap the back leg/board. The back leg goes from (494,546) to (442,566). The backpack bottom is 570 at x 396-486, overlapping the leg region. Since the backpack is drawn before the legs, the leg draws over it. Fine.
Actually, the backpack at x 396 might collide with the tail (drawn first, so the backpack covers part of the tail). The tail goes through x 346-468 — the backpack covers its base. That's fine, natural.
Hmm, wait: draw order is tail, backpack, ... so the tail appears to come out from behind the backpack. Good.
Back arm:
```svg
<path d="M 470 500 C 446 512 428 530 422 548" fill="none" stroke="#dde6f5" stroke-width="24" stroke-linecap="round"/>
<ellipse cx="418" cy="552" rx="15" ry="13" transform="rotate(-20 418 552)" fill="#f2f7ff" stroke="#c2cde2" stroke-width="3"/>
<ellipse cx="416" cy="554" rx="6.5" ry="5.5" fill="#f7b0b8" opacity=".9"/>
```
Hmm, the arm at x 422-470 would be in front of the backpack (x 396-486). Since the backpack is drawn first, the arm covers it. It's the back arm — should be behind the torso, in front of the backpack. OK.
Legs:
```svg
<path d="M 496 544 C 472 552 454 558 444 566" fill="none" stroke="#dde6f5" stroke-width="30" stroke-linecap="round"/>
<path d="M 546 542 C 568 550 580 556 590 562" fill="none" stroke="#eef3fc" stroke-width="30" stroke-linecap="round"/>
```
Hmm both legs from the hip area. The back leg's hip at (494,546) and the front leg's at (548,546). The torso bottom is around 548-562. OK.
Boots:
```svg
<ellipse cx="440" cy="568" rx="23" ry="11.5" fill="#d5e0f0" stroke="#a9b8d2" stroke-width="2.5"/>
<path d="M 420 574 h 40" stroke="#8fa0be" stroke-width="4" stroke-linecap="round"/>
<ellipse cx="592" cy="564" rx="23" ry="11.5" fill="#e6edf9" stroke="#b3c1d8" stroke-width="2.5"/>
<path d="M 572 570 h 40" stroke="#9aa9c4" stroke-width="4" stroke-linecap="round"/>
```
Boot bottoms at 579.5 and 575.5 → the deck top is 576. Good.
Torso:
```svg
<path d="M 474 468 C 452 486 448 522 462 550 C 492 566 552 566 578 550 C 592 520 588 486 566 468 Z"
fill="url(#suitG)" stroke="#b7c4dc" stroke-width="3"/>
```
Torso top edge from (474,468) to (566,468) — a straight top, then curves down. The neck/collar covers the top center.
Chest details:
```svg
<rect x="492" y="492" width="58" height="42" rx="11" fill="#dce7f7" stroke="#a7b6d1" stroke-width="2.5"/>
<rect x="500" y="500" width="42" height="15" rx="4" fill="#4fd8f7"/>
<rect x="503" y="504" width="10" height="3" rx="1.5" fill="#0b3a52" opacity=".5"/>
<rect x="516" y="504" width="16" height="3" rx="1.5" fill="#0b3a52" opacity=".4"/>
<rect x="503" y="509" width="22" height="3" rx="1.5" fill="#0b3a52" opacity=".35"/>
<circle cx="503" cy="524" r="4.5" fill="#7ef2a8"/>
<circle cx="518" cy="524" r="4.5" fill="#ffd166"/>
<circle cx="533" cy="524" r="4.5" fill="#ff8a8a"/>
<rect x="466" y="534" width="106" height="14" rx="7" fill="#c8d4e9" stroke="#a4b3ce" stroke-width="2.5"/>
<circle cx="558" cy="480" r="11" fill="#ffd166" stroke="#d9a93f" stroke-width="2"/>
<path d="M 558 474 l 2 5 5.5 .6 -4 3.6 1.2 5.4 -4.7 -2.8 -4.7 2.8 1.2 -5.4 -4 -3.6 5.5 -.6 z" fill="#a97a1f" opacity=".8"/>
<path d="M 470 476 C 462 490 460 504 462 518" stroke="#6be1ff" stroke-width="5" fill="none" stroke-linecap="round" opacity=".8"/>
```
Wait, the belt at x 466..572, y 534..548. The torso at y=540 spans roughly 460..578. OK.
Hmm the mission patch at (558,480) — the torso's right edge near y=480 is around x=572. So a circle r=11 at 558 spans to 569, inside. Good.
Neck & collar:
```svg
<rect x="498" y="438" width="44" height="44" rx="20" fill="#e3eaf6"/>
<ellipse cx="520" cy="472" rx="54" ry="17" fill="#cfdaec" stroke="#a3b1cc" stroke-width="3"/>
<ellipse cx="520" cy="470" rx="44" ry="11" fill="#b9c7de" opacity=".6"/>
```
The collar at cy=472 with ry=17 spans 455..489. The helmet bottom is 475. Good overlap.
Ears: drawn before the head.
```svg
<path d="M 486 374 L 466 316 L 526 350 Z" fill="url(#furG)" stroke="#dc8440" stroke-width="2" stroke-linejoin="round"/>
<path d="M 490 366 L 478 330 L 512 350 Z" fill="#ffb7ae" opacity=".85"/>
<path d="M 554 374 L 574 316 L 514 350 Z" fill="url(#furG)" stroke="#dc8440" stroke-width="2" stroke-linejoin="round"/>
<path d="M 550 366 L 562 330 L 528 350 Z" fill="#ffb7ae" opacity=".85"/>
```
Wait, the right ear inner triangle: points (550,366), (562,330), (528,350). Is that inside the outer (554,374),(574,316),(514,350)? The inner's rightmost is 562, outer's right edge line goes from (574,316) to (554,374) — at y=340, x ≈ 574 - (20)*(340-316)/58 = 574-8.3=565.7. So 562 is inside. OK.
The head (ellipse rx=55 ry=49 at 520,404) top at y=355. The ears' bases at y=350-374 are near the head top; the head will cover the bases. Good.
Head:
```svg
<ellipse cx="520" cy="404" rx="55" ry="49" fill="url(#furG)"/>
<!-- cheek fluff -->
<path d="M 470 410 l -12 -6 6 12 -12 4 12 6 4 10 6 -10" fill="url(#furG)"/>
```
Skip the fluff; keep it clean.
Add fur stripes on the head sides:
```svg
<g stroke="#dd8a44" stroke-width="4" stroke-linecap="round" opacity=".55">
<path d="M 494 362 l -6 -14"/>
<path d="M 520 356 l 0 -14"/>
<path d="M 546 362 l 6 -14"/>
<path d="M 476 400 h -12"/>
<path d="M 476 412 l -12 4"/>
</g>
```
Hmm the last ones at x=464 might be outside the head (head spans 465..575 at cy). At y=400, the head's left edge is ~465. A stroke at x 464..476 would be right at the edge. Fine, looks like cheek stripes. Maybe skip those and keep only the forehead ones.
Eyes, muzzle, nose, mouth, whiskers as planned.
Helmet:
```svg
<circle cx="520" cy="396" r="80" fill="url(#helmetG)" stroke="#e2f6ff" stroke-width="4"/>
<circle cx="520" cy="396" r="80" fill="none" stroke="#8fc8ea" stroke-width="8" opacity=".18"/>
<path d="M 462 356 A 78 78 0 0 1 528 322" fill="none" stroke="#ffffff" stroke-width="9" stroke-linecap="round" opacity=".8"/>
<path d="M 470 430 A 80 80 0 0 1 448 390" fill="none" stroke="#ffffff" stroke-width="5" stroke-linecap="round" opacity=".35"/>
```
Arc check: `M 462 356 A 78 78 0 0 1 528 322` — radius 78 circle centered at (520,396): the point (462,356): dx=-58, dy=-40 → dist=70.4, not on the circle of r=78. The arc will be adjusted by the renderer (large radius scaling). It'll still look like a stroke along the upper-left of the helmet, roughly. To be exact, use points on the circle: angle 140° → (520+78cos140, 396+78sin140) = (520-59.8, 396+50.1) = (460,446) — that's lower-left. For the upper-left highlight: angle 200° → (520-73.3, 396-26.7) = (447,369); angle 250° → (520-26.7, 396-73.3) = (493,323). So the arc from (447,369) to (493,323) with r=78 sweep=1 (clockwise; going from lower-left to top, clockwise passes through the upper-left). Let's verify: sweep=1 draws clockwise. Starting at (447,369) [angle 200°] and going clockwise (increasing angle in screen coords) would go to 250°? In screen coordinates with y down, increasing angle goes clockwise visually. From 200° to 250° gives (493,323). Yes, that's along the upper-left. Good.
So: `<path d="M 452 372 A 76 76 0 0 1 496 326" ...>` with r=76 close to the helmet radius 80 minus a bit. Since the endpoints are on the r=78 circle, using r=76 gives an error but the renderer scales the radius up to fit; it'll still be a shallow arc. Let me just set points exactly: use r=76 and compute points on a 76 circle: angle 205° → (520-68.9, 396-32.1) = (451,364); angle 255° → (520-19.7, 396-73.4) = (500,323). So `M 451 364 A 76 76 0 0 1 500 323`.
Antenna: attach at the helmet's upper right: angle -30° (i.e., 330°) → (520+69, 396-40) = (589,356). Hmm, that's the right side, not upper. Upper-right at -50°: (520+51.4, 396-61.4) = (571,335). Let's do the antenna from (568,338) to (596,300) with a ball at (598,297). Fine.
Wait, the ears are inside the helmet, and the antenna is outside. OK.
Now, the front arm:
```svg
<path d="M 564 492 C 592 486 616 468 630 446" fill="none" stroke="#eef3fc" stroke-width="26" stroke-linecap="round"/>
<path d="M 566 494 C 592 488 614 472 628 452" fill="none" stroke="#cfdaea" stroke-width="4" stroke-linecap="round" opacity=".5"/>
```
Add a cuff: `<circle cx="618" cy="462" r="14" fill="#dbe6f6" stroke="#b3c0d8" stroke-width="3"/>`? That'd be a blob at the wrist. Instead, a stripe: `<path d="M 606 470 l 10 -12" stroke="#6be1ff" stroke-width="6" stroke-linecap="round"/>`. Eh.
Paw/glove at (636,440):
```svg
<ellipse cx="636" cy="440" rx="18" ry="17" fill="#f8fbff" stroke="#c2cde2" stroke-width="3"/>
<ellipse cx="636" cy="444" rx="9" ry="7" fill="#f7b0b8" opacity=".95"/>
<circle cx="626" cy="431" r="3.6" fill="#f7b0b8" opacity=".95"/>
<circle cx="636" cy="428" r="3.6" fill="#f7b0b8" opacity=".95"/>
<circle cx="646" cy="431" r="3.6" fill="#f7b0b8" opacity=".95"/>
```
This is a waving paw. Good.
Then close #cat, #rider.
Let's also add a little glow behind the cat: before the rider, a radial glow ellipse at (520,420) r 300 with cyan 8%.
`<ellipse cx="520" cy="420" rx="330" ry="300" fill="url(#catGlowG)"/>` with a radial gradient from #7fd8ff opacity .12 to transparent. Nice rim separation from the dark sky.
Now the JS for stars.
```js
(function(){
var g = document.getElementById('stars');
var svgns = 'http://www.w3.org/2000/svg';
var s = 20240607;
function rnd(){ s = (s * 1103515245 + 12345) & 0x7fffffff; return s / 0x7fffffff; }
var frag = document.createDocumentFragment();
for (var i = 0; i < 120; i++) {
var c = document.createElementNS(svgns, 'circle');
var x = rnd() * 1000, y = rnd() * 620;
c.setAttribute('cx', x.toFixed(1));
c.setAttribute('cy', y.toFixed(1));
c.setAttribute('r', (0.5 + rnd() * 1.6).toFixed(2));
c.setAttribute('fill', rnd() > 0.85 ? '#bfe4ff' : '#ffffff');
c.style.opacity = (0.25 + rnd() * 0.6).toFixed(2);
c.style.animation = 'twinkle ' + (2.4 + rnd() * 4).toFixed(1) + 's ease-in-out ' + (rnd() * 5).toFixed(1) + 's infinite';
frag.appendChild(c);
}
g.appendChild(frag);
})();
```
Careful: `c.style.opacity` set inline, but the animation `twinkle` also sets opacity — the animation overrides during its run, and since it's infinite with a delay, before the delay starts the fill uses the inline opacity. The keyframes at 0% set opacity .25 and 100% .25, 50% 1 — so all stars pulse to full regardless of the base opacity. To preserve variety, use `animation-fill-mode: both`? Simpler: vary opacity via the keyframe? We can't per-element. Alternative: vary the color brightness instead (some stars dimmer by fill color), and let opacity fully animate. Use fill colors like rgba(255,255,255,alpha)? Set fill with different opacities via `fill-opacity`. Yes: use fill-opacity attribute for the base brightness, and the CSS opacity animation for twinkling.
```js
c.setAttribute('fill-opacity', (0.3 + rnd()*0.7).toFixed(2));
```
and CSS animation on opacity.
Note: `& 0x7fffffff` with multiplication may exceed 2^53 for large s? s up to 2^31, times 1103515245 ≈ 2.4e18 > 2^53 → precision loss, and the bitwise & will coerce to int32 (works but with precision loss). It's fine for the demo, but let's use a simpler hash:
```js
function rnd(){ s = (s * 16807) % 2147483647; return s / 2147483647; }
```
with s initialized to 12345 (Lehmer RNG). s*16807 max 12345... s < 2^31, times 16807 ≈ 3.6e13 < 2^53. Good, exact.
Start s = 987654321 % 2147483647 → fine, but must not be 0. Use s = 123456789.
Then `%` gives exact results since the products are < 2^53.
Now, timing: the script runs after the SVG in the DOM, so `document.getElementById('stars')` works.
Add a small optional interaction? Not required. The task is a drawing. Maybe a subtle parallax on mouse move? Not needed; could be a nice touch but the screenshot doesn't depend on it. Keep it simple and safe.
Let me reconsider the CSS for the animations once more:
```css
@keyframes twinkle{0%,100%{opacity:.2}50%{opacity:1}}
@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@keyframes sway{0%,100%{transform:rotate(-1.4deg)}50%{transform:rotate(1.4deg)}}
@keyframes tailSway{0%,100%{transform:rotate(-6deg)}50%{transform:rotate(8deg)}}
@keyframes earTwitch{0%,88%,100%{transform:rotate(0)}91%{transform:rotate(-9deg)}95%{transform:rotate(5deg)}}
@keyframes puff{0%{transform:translate(0,0) scale(.35);opacity:0}12%{opacity:.85}100%{transform:translate(-180px,26px) scale(1.6);opacity:0}}
@keyframes pulse{0%,100%{opacity:.35}50%{opacity:.85}}
```
Applying:
```css
.spin{transform-box:fill-box;transform-origin:center;animation:spin 1.5s linear infinite;}
#cat{transform-box:view-box;transform-origin:520px 566px;animation:sway 4.6s ease-in-out infinite;}
#tail{transform-box:fill-box;transform-origin:100% 88%;animation:tailSway 3.2s ease-in-out infinite;}
#earL{transform-box:fill-box;transform-origin:80% 100%;animation:earTwitch 6s ease-in-out infinite;}
.puff{opacity:0;animation:puff 2.4s ease-out infinite;}
.p1{animation-delay:.1s} .p2{animation-delay:.6s} ...
.antennaGlow{animation:pulse 2s ease-in-out infinite;}
```
Careful: `#cat` uses transform-box view-box + px origin — but note that when an ancestor (the SVG) has a viewBox and the element is inside it, using `view-box` makes `transform-origin` resolve relative to the viewBox coordinate system. Chrome supports this. If unsupported, it falls back to... potentially the origin at 0,0 of the element's bbox. The sway would look like a rotation around a weird point. Chrome supports view-box (since ~M77). Fine.
Alternatively, use `transform-origin: 52% 94%` with fill-box — the cat's bbox is roughly x 330..670, y 315..582 (excluding the board? the cat group doesn't include the board). Using fill-box with origin 52% 94% ≈ (507, 566) — close enough to the pivot. And it's more broadly supported. Let's use fill-box with percentages: cat bbox: x from ~334 (tail left) to 654 (paw right) → width 320. y from 316 (ear) to 580 (boot) → height 264. Pivot (520,566) → x% = (520-334)/320 = 58%, y% = (566-316)/264 = 94.7%. So `transform-origin: 58% 95%` with fill-box.
For the tail: bbox x 337..478, y 452..564. Base at (468,546) → 96% x, 84% y. `transform-origin: 96% 84%`.
Ear: left ear bbox x 466..526, y 316..374. Base at the bottom-center-right (500,372) → 57% x, 100% y. Good.
Now the puff animation with transform on circles: `transform-box: fill-box; transform-origin: center;` isn't needed for pure translate+scale? Scale needs an origin; with fill-box it defaults to the bbox center, otherwise 0,0. The default `transform-box` is `view-box` for SVG elements in CSS, and `transform-origin` default is `0 0`? For SVG elements, the CSS transform-origin default is `0 0` (per spec, `transform-origin` initial value is 50% 50% but for SVG elements without `transform-box`, the reference box is the viewBox... hmm). Actually per CSS Transforms, `transform-box` initial is `view-box` for SVG, and `transform-origin: 50% 50%` resolves against that view box → the origin is the center of the viewBox (500,350) — that would make the puffs scale about the canvas center, causing them to move weirdly. To be safe, set `transform-box: fill-box; transform-origin: center;` on `.puff` — then scale happens around the puff's own center.
Hmm, but that could conflict with the translate. No, translate then scale about the element's own center — fine.
Now, also consider that the `.puff` circles have `cx`/`cy` set; the fill-box of a circle is its bounding box. Good.
Let me also double check the `sway` on #cat doesn't affect the board — the board is outside #cat (sibling). Good.
One more: the `#rider` group could have a `filter` — avoid, filters on large groups can be slow.
Let's think about the overall color harmony: deep blue space, warm orange cat, white suit, cyan accents, cool gray moon.
Now let me write the final code carefully, checking all tag closures.
Also: the `role="img"` and aria-label on the SVG — good practice.
Potential issue: `<use href="#crater">` inside a clip-path group — fine.
Let me write out the entire file now, being meticulous.
Also should I add `<title>` inside the SVG? Not necessary.
One more thought on the layout for mobile 375px: the whole thing scales to 375x262 centered vertically. The dark background surrounds it. It's fine, but the scene will be small. To improve, I could change the preserveAspectRatio via CSS media query? Not possible directly. I could use JS to switch `preserveAspectRatio` to "xMidYMid slice" when the aspect ratio is narrow, and adjust the viewBox to a narrower crop. Actually, a nice trick: on narrow screens, set the viewBox to "200 250 600 500" (zoom into the cat) via JS on resize. That gives a nice portrait framing. Let's do that — it's simple and safe:
```js
function fit(){
var svg = document.getElementById('scene');
if (window.innerWidth < 720) svg.setAttribute('viewBox','210 240 580 460');
else svg.setAttribute('viewBox','0 0 1000 700');
}
window.addEventListener('resize', fit); fit();
```
With a portrait viewport 375x800 and viewBox 210 240 580 460 (aspect 1.26), the SVG (375x800, aspect .47) with meet → the width fits: 375/580 = 0.647 scale → height 460*0.647 = 297 in the middle of 800. Still letterboxed, but the cat is bigger. Fine.
Hmm, but then the background rect only covers the viewBox area; the rest of the page shows the body background. The body is `#080a18` radial → should blend okay since the sky at the center is brighter and at the edges darker. There would be a visible seam because the scene edges are lighter than the page background. With the zoomed viewBox (210,240,580,460), the sky region is the brighter center — the seam would be obvious.
Alternative: when narrow, use `preserveAspectRatio="xMidYMid slice"` with the full viewBox — then the SVG covers the viewport fully, cropping horizontally. At 375x800: scale = max(375/1000, 800/700) = 1.143 → visible width = 328 units centered at 500 → x 336..664. The cat spans 334..654 and the board 330..670 — slight cropping of the board tips. Hmm, at width 375, the board's left tip would be just cut off. Not terrible but not great.
Better slice with slice-scale being driven by height... Alternatively, when narrow, keep meet but make the page background match the sky color at the edges better. The sky radial at the viewBox corners is #05060f (the outer stop). So the page background should just be #05060f with a radial that's uniform dark. If the SVG is letterboxed with `meet`, the scene's edge pixels are near #05060f at the corners, but at the left/right middle edges (y=350), the sky gradient at radius ~0.5 is around #0d1231 — noticeably lighter than #05060f. The seam would be visible as a rectangle.
Given that, maybe the cleanest: `preserveAspectRatio="xMidYMid meet"` and let the SVG's own background extend? Can't beyond the viewBox.
Option: make the background rect much larger than the viewBox (e.g., x=-1000 y=-500 w=3000 h=1700) so it overflows... but with meet, the SVG viewport is still the element's box, and overflow is hidden by default (SVG root clips to the viewport). So no.
Option: put a CSS background on the body that matches, plus make the sky gradient uniform near the edges. Setting the body background to a radial gradient with the same center/colors as the SVG sky is essentially what we have, but the alignment differs because the SVG is letterboxed.
Simplest robust solution: use `preserveAspectRatio="xMidYMid slice"`. Then the background always fills the viewport, no seams. The risk is cropping on extreme aspect ratios. For 1280x800 (aspect 1.6 vs 1.43), slice → scale = max(1280/1000, 800/700) = 1.28 → visible height = 800/1.28 = 625 units of 700 → crops 37 top and bottom. The top crop removes some sky/Earth? Earth at y 104-196 stays. The bottom crop removes y>662 — the paw prints at 672 and some craters. Acceptable.
For 375x800: scale = max(0.375, 1.143) = 1.143 → visible width 328 → x 336..664. The cat fits (334..654) but the tail tip at 337 is just at the edge. The board gets cut. Hmm.
Compromise: use `slice` for wide screens and `meet` for tall ones? The seam issue only arises with `meet`.
Alternatively, accept the letterbox but make the page background a solid color that matches the SVG's sky at mid-edge. With `meet` at 1280x800, the SVG fills 1143x800 (aspect 1.43 → 800*1.43=1143), so there are ~68px bars on the left and right. The sky at the left edge (x=0) at y=350: the radial gradient (cx 50%, cy 50%, r 70%) — the point (0,350) is at distance 500 from the center, and r = 0.7 * the diagonal-ish... For a radial gradient with `r="70%"`, the reference is the "farthest-corner"? SVG radialGradient percentages for r are relative to the normalized diagonal of the bounding box: r=70% of sqrt((1000²+700²)/2) = 70% of 860 = 602. So a point at distance 500 is at 83% of the radius → color between #0d1231 (42%) and #05060f (100%) → around #07091a. If the body bg is #07091a at that region, the seam is nearly invisible. I can make the body background a radial that at the left/right edges is ~#07091a.
Honestly, a subtle seam is acceptable — many demos have it. But let's minimize it: set the body background to `#07081a` (flat, near the sky edge color) and make the sky's outer stop #07081a. Then at the horizontal mid-edges the sky is close to that. There'd be a slight gradient mismatch vertically, but it'll read as a vignette.
Hmm, actually, let me do something better: use `preserveAspectRatio="xMidYMid meet"` plus apply a CSS filter/blur? No.
Alternative clean approach: Make the HTML page background a copy of the sky gradient via CSS:
```css
body{
background:
radial-gradient(ellipse 50% 50% at 50% 50%, #1a2350 0%, #0d1231 42%, #05060f 100%),
#05060f;
}
```
But when the SVG is letterboxed, its own sky center is at the SVG box center (which is centered in the viewport), so the radial centers coincide! At 1280x800 with meet, the SVG is 1143x800 centered — its center is the viewport center (640,400). The body's radial is centered at 50%/50% of the 1280x800 viewport. The colors won't perfectly match at the seam but the overall gradient direction is the same. The mismatch would be a subtle step in brightness at the vertical seam lines.
To eliminate this concern entirely, I'll go with `slice` — full-bleed always, which looks more immersive and professional, and keep the essential content within x 300..700. At 375px width, we see x 336..664 — the board tips (330/670) get slightly cropped, the raised paw at 654 is visible, and the tail at 337 is at the edge. Ugh, the tail would be right at the crop edge.
Let me shift the composition to be more compact: move everything inward a bit? Reduce the board width from 340 to ~300 (x 350..650), and the raised paw to x=630, the tail tip to x=360. Then the cat content spans 350..650, and at 375px wide we'd see 336..664 — everything fits with a small margin!
Let's redesign coordinates to fit within x 345..655:
- Deck: x=352..648 (width 296), wheels at (420, 612) and (580, 612).
- Tail tip at 365.
- Raised paw at 632.
- Board shadow rx=170 → 330..670, fine (it's just a shadow).
That works. And vertical: with slice at 1280x800, y 37..662 visible; content 316..640 — fits! At 375x800, y is not cropped (height scale 1.143 → visible height 700). Good.
At a very wide viewport (e.g., 1280x800 is 1.6), the crop is top/bottom only. At ultra-wide 2560x800 (3.2), scale = 2.56 → visible height 312 → y 194..506! That would crop the cat's body and the board. Hmm, but the required viewport is 1280x800. For extreme wide screens, it'd be bad. `meet` handles that safely.
OK here's my decision: use `meet` for safety and accept the letterbox, but make the letterbox blend by setting the page background to a matching dark radial and adding a soft vignette to the SVG edges so the boundary is less noticeable. Actually, a simpler idea: add a `<rect>` vignette overlay INSIDE the SVG at the very end with a radial gradient that fades to the page background color at the edges — then the SVG's own edges are uniformly dark and blend seamlessly into the page.
Yes! Add at the top of the SVG (after everything): a rect with a radial gradient (transparent center → #05060f at the edges) with opacity ~0.5. That gives a natural vignette and makes the boundary invisible against the #05060f body. But it darkens the corners of the art (fine, it's a vignette).
Even better: don't overlay; just accept the edges are darker.
Let me construct the vignette: `<radialGradient id="vig" cx="50%" cy="48%" r="70%"><stop offset="55%" stop-color="#05060f" stop-opacity="0"/><stop offset="100%" stop-color="#05060f" stop-opacity="0.85"/></radialGradient>` and `<rect width="1000" height="700" fill="url(#vig)" pointer-events="none"/>`. With the vignette at the edges reaching 0.85 opacity of #05060f, the SVG edges are nearly #05060f → blends with the body #05060f.
The corners will be quite dark, but the scene is centered, so it's fine. And the moon at the bottom corners gets darkened — it will look like the moon is fading into shadow. Acceptable and even nice.
I'll go with `meet` + vignette + body bg #04050d.
Now the composition: with meet at 1280x800, the SVG is 1143x800 centered, bars 68px on each side. Fine.
Let's finalize with the compacted coordinates (deck 352..648).
Revised numbers:
- Deck: x=352, y=576, w=296, h=22, rx=11. Top strip x=360 w=280.
- Trucks: x=408 w=26 (center 421), x=566 w=26 (center 579).
- Wheels: (421,612) and (579,612), r=19.
- Shadow: cx=500, cy=636, rx=175.
- Cat: torso/head same (centered at 520).
- Front paw at (632, 440) — the arm from (564,492) to (630,446). OK.
- Tail tip at 366.
Also the cat's front boot at cx=588 → within the deck (ends at 648). Back boot at 440. Both on the deck. Good.
Wait, the deck ends at 648 and the front paw at 632 — fine, different y.
Let me re-examine the front leg: hip (548,546) → foot (588,562). The boot ellipse at (588,564) rx=23 → 565..611. That's on the deck. Good.
The back boot at (440,568) rx=23 → 417..463. Good.
Now, the tail: `M 468 546 C 416 574 356 552 346 508 C 340 482 354 462 378 462` — the leftmost x ~341. Let me pull it in: `C 420 572 368 552 360 510 C 354 484 366 464 388 464`. Tip at (388,464). Leftmost ≈ 355. Good, within 345.
Tail transform origin: bottom-right of bbox (468, 570ish) → 100% 88%. The bbox x 355..478, y 454..572. Base at (468,546): x% = (468-355)/123 = 92%, y% = (546-454)/118 = 78%. Use `transform-origin: 92% 80%`.
Fine.
Now, let me double check the head/helmet proportions: helmet r=80 at (520,396). Head rx=55 ry=49 at (520,404). The head fills most of the helmet. Ears from y=316 — the helmet top is 316. The ears touch the top of the helmet exactly. Maybe lower the ears slightly: tips at y=326. Let's set left ear: (486,374) → (470,326), (524,352). And the inner triangle accordingly. Right ear mirrored. Then the head top is at 355, ears from 326. Good, a gap of 10px from the helmet top.
Head at cy=404 with ry=49 → top 355, bottom 453.
Helmet 316..476.
Eyes at y=398, muzzle at 428-440, chin at 453. Good.
Whiskers at y=418-446, extending to x=462 and 578 — inside the helmet (at y=430, the helmet spans 520±sqrt(6400-1156)=520±72.4 → 447..592). So whiskers ending at 462/578 are inside.
Now, the collar at y=472 with rx=54: 466..574. The helmet at y=472 spans 520±sqrt(6400-5776)=520±25 — so the helmet is narrow there, and the collar is wider. It sits at the base like a neck ring. Good.
Torso top at 468 — the collar covers 455..489. Good.
Let's write the final code.
One more check on the chest panel position: torso spans ~452..588 at mid-height. Panel at x=492 w=58 → 492..550, centered slightly left of 520. Fine. The mission patch at 558 r=11 → 547..569, might overlap the panel (ends at 550). Move the patch to (566, 484) r=10 → 556..576. The torso's right edge at y=484 is around 580. OK.
Actually, let me simplify: put the patch on the left shoulder area? The backpack is there. Keep it at (566,482), r=10.
Hmm, the front arm starts at (564,492) going right — the patch at (566,480) would be right above the shoulder. Slight overlap is fine.
Belt: x=466 w=106 → 466..572 at y 534..548. The torso at y=540 spans about 458..580. Good.
Now the star sticker on the deck at (600,586) with a small sparkle.
Let's write it all out.
Also, I want a subtle detail: a little rocket nozzle glow behind the board? No.
Final check on the SVG `filter` usage: `filter="url(#blurSoft)"` on ellipses — the filter region defaults to -10%,-10%,120%,120% of the bbox, which may clip the blur. I defined explicit regions. Good.
For the `#horizonGlow` circle with r=940 and a blur, the filter region is -40%..180% of a 1880x1880 bbox → huge but fine.
Performance: a few blurred large objects — fine.
Let me now write the final HTML.
Actually one concern: `<use href="#crater">` where #crater contains elements without cx/cy and is inside `<defs>`. Should render.
Another: the `clip-path="url(#moonClip)"` group — the clipPath contains a circle at cy=1420 r=940. Good.
Writing now.
I'll also add `shape-rendering` defaults; no.
Text: maybe add a tiny caption in the corner? Like "MEOW · 1/6 G" in a small monospace label at the bottom-left, subtle. That's a nice design touch. Let's add:
```svg
<g opacity=".55" fill="#cfe6ff" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="15" letter-spacing="3">
<text x="60" y="640">LUNAR SK8 · 1/6 g</text>
</g>
```
Hmm, could clutter. But a small mission-label adds polish. Place it at the bottom-right (x=940, text-anchor=end, y=650). With the vignette, it'll dim slightly. Keep it subtle. I'll add it — but the fonts allowed are system fonts only (no external), which is fine.
Actually, careful: text in the bottom-right at (940,650) may be over the moon's darker area, low contrast. Use fill #a9c4e2 opacity .5. Fine. Or skip. I'll include a small one at the top-left: "MOON RUN 001". Hmm, the ringed planet is there. Bottom-left at (60, 655): the moon is bright there, so dark text would read better: fill="#5b6480" opacity=".7". Let's do that.
Eh — I'll skip the text to keep the illustration pure. Actually no, a tiny bit of typographic polish is nice in a demo comparison. I'll add it small at the bottom-left: "LUNAR SK8 • 1/6 g" with fill #6b7796 opacity .8, font-size 14, letter-spacing 2.5. It sits on the moon surface.
Hmm, the paw prints are also at the bottom-left (120,672) — the text at y=655 x=60..250 might overlap the prints. Fine, it's a background element. Actually, let me place the text at the top-center-left, above the horizon: x=60, y=60, fill #8fa8c8 opacity .6. The ringed planet is at (150,120) r=24 plus the ring, so a text at y=60 above it is fine.
I'll place it at the top-left: `LUNAR SK8 · 1/6 G`. Fine.
Now writing for real.
Let me count the elements in the rider for draw order:
```
<g id="rider">
shadow ellipses
dust puffs
board group (trucks, wheels, deck)
<g id="cat">
tail
backpack
back arm
legs + boots
torso + details
neck + collar
ears
head + face
helmet
front arm + paw
</g>
</g>
```
Wait — the board should be drawn BEFORE the cat, yes. And the shadow before the board. Good.
But the front boot at cy=564 and the deck top at 576 → the boot bottom is 575.5, just touching. Good.
Now writing the whole thing.
For the puffs, I'll place them near the back wheel at (400, 618) and (390,625) etc.
Let me write out the file content now.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Astronaut Cat · Moon Skate</title>
<style>
:root{color-scheme:dark;}
html,body{height:100%;}
body{
margin:0;overflow:hidden;background:#04050d;
display:flex;align-items:center;justify-content:center;
font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
}
svg#scene{width:100%;height:100%;display:block;}
@keyframes twinkle{0%,100%{opacity:.15}50%{opacity:1}}
@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes sway{0%,100%{transform:rotate(-1.3deg)}50%{transform:rotate(1.3deg)}}
@keyframes tailSway{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(9deg)}}
@keyframes earTwitch{0%,86%,100%{transform:rotate(0deg)}90%{transform:rotate(-10deg)}94%{transform:rotate(5deg)}}
@keyframes puff{0%{transform:translate(0,0) scale(.3);opacity:0}14%{opacity:.8}100%{transform:translate(-170px,24px) scale(1.5);opacity:0}}
@keyframes pulse{0%,100%{opacity:.35}50%{opacity:.9}}
.spin{transform-box:fill-box;transform-origin:center;animation:spin 1.4s linear infinite;}
#cat{transform-box:fill-box;transform-origin:58% 95%;animation:sway 4.6s ease-in-out infinite;}
#tail{transform-box:fill-box;transform-origin:92% 80%;animation:tailSway 3.2s ease-in-out infinite;}
#earL{transform-box:fill-box;transform-origin:60% 100%;animation:earTwitch 5.6s ease-in-out infinite;}
.puff{opacity:0;transform-box:fill-box;transform-origin:center;animation:puff 2.4s ease-out infinite;}
.p1{animation-delay:.0s}.p2{animation-delay:.5s}.p3{animation-delay:1.0s}.p4{animation-delay:1.5s}.p5{animation-delay:1.9s}
.glowpulse{animation:pulse 2.6s ease-in-out infinite;}
</style>
</head>
<body>
<svg id="scene" viewBox="0 0 1000 700" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="An astronaut cat skateboarding across the moon">
...
</svg>
<script>...</script>
</body>
</html>
```
Note: I use `#earL` as a group id. Let me wrap the left ear in a `<g id="earL">`.
Now, full SVG content. Let me write it out.
I'm going to be careful that every `<g>` is closed.
After the scene, the vignette rect last.
Let me draft the SVG body:
```svg
<defs>
... gradients, filters, clip, symbols ...
</defs>
<!-- sky -->
<rect x="0" y="0" width="1000" height="700" fill="url(#skyG)"/>
<!-- nebula -->
<g filter="url(#blurBig)" opacity=".6">
<ellipse cx="200" cy="150" rx="210" ry="130" fill="#3b2f80" opacity=".5"/>
<ellipse cx="840" cy="470" rx="170" ry="100" fill="#1d5a7d" opacity=".45"/>
<ellipse cx="620" cy="90" rx="160" ry="90" fill="#4a2b63" opacity=".35"/>
</g>
<!-- stars -->
<g id="stars"></g>
<!-- sparkles -->
<g fill="#ffffff">
...
</g>
<!-- planets -->
<g>ringed planet</g>
<g>earth</g>
<g>small distant moon</g>
<g>shooting star</g>
<!-- moon -->
<g>...</g>
<!-- speed streaks -->
<g>...</g>
<!-- cat glow -->
<ellipse cx="520" cy="430" rx="320" ry="290" fill="url(#catGlowG)"/>
<!-- rider -->
<g id="rider">...</g>
<!-- vignette -->
<rect width="1000" height="700" fill="url(#vigG)"/>
<!-- label -->
<g>...</g>
```
The label should be above the vignette maybe. Put the label before the vignette so it gets dimmed... it's fine either way. Put it after (crisper).
Let's go.
For the earth glow, the radial gradient with `cx=35%` etc. is for the sphere shading. The outer glow uses a separate gradient.
Let me now write everything in final form, checking coordinates.
I also want to double-check the `sway` origin: `#cat` fill-box — the bbox of the cat group includes the tail (x 355..478), the paw (654), and the boots (417..611), y 326..580. So bbox x 355..654 (w 299), y 326..580 (h 254). Origin at 58% x = 355+173 = 528, 95% y = 326+241 = 567. Close to (520,566).
Now, `#tail` fill-box: the tail group includes the path and the tip circle and the stripe: x ~355..478, y ~452..570. Origin 92%/80% → (468, 546).
`#earL` bbox: x 466..526, y 326..374. Origin 60%/100% → (502, 374). Good (the ear base).
Let me write the final file.
One more consideration on the `<g id="crater">` symbol: since it's used with different scales, the stroke widths aren't used (no strokes). Fine.
Final code writing. I'll be thorough.
Also the Earth's tilt — whatever.
Let me write out the whole thing now in one go.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Astronaut Cat — Moon Skate</title>
<style>
html,body{height:100%}
body{margin:0;overflow:hidden;background:#04050d;display:flex;align-items:center;justify-content:center}
svg#scene{width:100%;height:100%;display:block}
@keyframes twinkle{0%,100%{opacity:.15}50%{opacity:1}}
@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@keyframes sway{0%,100%{transform:rotate(-1.3deg)}50%{transform:rotate(1.3deg)}}
@keyframes tailSway{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(9deg)}}
@keyframes earTwitch{0%,86%,100%{transform:rotate(0)}90%{transform:rotate(-10deg)}94%{transform:rotate(5deg)}}
@keyframes puff{0%{transform:translate(0,0) scale(.3);opacity:0}14%{opacity:.8}100%{transform:translate(-170px,26px) scale(1.55);opacity:0}}
@keyframes pulse{0%,100%{opacity:.35}50%{opacity:.9}}
.spin{transform-box:fill-box;transform-origin:center;animation:spin 1.4s linear infinite}
#cat{transform-box:fill-box;transform-origin:58% 95%;animation:sway 4.6s ease-in-out infinite}
#tail{transform-box:fill-box;transform-origin:92% 80%;animation:tailSway 3.2s ease-in-out infinite}
#earL{transform-box:fill-box;transform-origin:60% 100%;animation:earTwitch 5.6s ease-in-out infinite}
.puff{opacity:0;transform-box:fill-box;transform-origin:center;animation:puff 2.4s ease-out infinite}
.p1{animation-delay:0s}.p2{animation-delay:.5s}.p3{animation-delay:1s}.p4{animation-delay:1.5s}.p5{animation-delay:1.9s}
.glowpulse{animation:pulse 2.6s ease-in-out infinite}
</style>
</head>
<body>
<svg id="scene" viewBox="0 0 1000 700" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="An astronaut cat skateboarding across the moon">
<defs>
<radialGradient id="skyG" cx="50%" cy="50%" r="72%">
<stop offset="0" stop-color="#1a2350"/>
<stop offset="40%" stop-color="#0c1130"/>
<stop offset="100%" stop-color="#05060f"/>
</radialGradient>
...
</defs>
...
</svg>
<script>...</script>
</body>
</html>
```
Note the radial gradient `r="72%"` for the sky.
I'm ready. Let me write the full detailed markup carefully, then review.
For the craters, I'll list a reasonable set.
Also, I realize the horizon glow circle with `filter` might produce a big soft stroke — nice.
Let me write the final answer.Raw response
Here’s a self-contained SVG illustration of an astronaut cat skateboarding across the moon, with a lively animated space scene.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Astronaut Cat — Moon Skate</title>
<style>
html,body{height:100%}
body{margin:0;overflow:hidden;background:#04050d;display:flex;align-items:center;justify-content:center}
svg#scene{width:100%;height:100%;display:block}
@keyframes twinkle{0%,100%{opacity:.15}50%{opacity:1}}
@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@keyframes sway{0%,100%{transform:rotate(-1.3deg)}50%{transform:rotate(1.3deg)}}
@keyframes tailSway{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(9deg)}}
@keyframes earTwitch{0%,86%,100%{transform:rotate(0)}90%{transform:rotate(-10deg)}94%{transform:rotate(5deg)}}
@keyframes puff{0%{transform:translate(0,0) scale(.3);opacity:0}14%{opacity:.8}100%{transform:translate(-170px,26px) scale(1.55);opacity:0}}
@keyframes pulse{0%,100%{opacity:.3}50%{opacity:.9}}
.spin{transform-box:fill-box;transform-origin:center;animation:spin 1.4s linear infinite}
#cat{transform-box:fill-box;transform-origin:58% 95%;animation:sway 4.6s ease-in-out infinite}
#tail{transform-box:fill-box;transform-origin:92% 80%;animation:tailSway 3.2s ease-in-out infinite}
#earL{transform-box:fill-box;transform-origin:60% 100%;animation:earTwitch 5.6s ease-in-out infinite}
.puff{opacity:0;transform-box:fill-box;transform-origin:center;animation:puff 2.4s ease-out infinite}
.p1{animation-delay:0s}.p2{animation-delay:.5s}.p3{animation-delay:1s}.p4{animation-delay:1.5s}.p5{animation-delay:1.9s}
.glowpulse{animation:pulse 2.6s ease-in-out infinite}
</style>
</head>
<body>
<svg id="scene" viewBox="0 0 1000 700" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="An astronaut cat skateboarding across the moon">
<defs>
<radialGradient id="skyG" cx="50%" cy="50%" r="72%">
<stop offset="0" stop-color="#1a2350"/>
<stop offset="40%" stop-color="#0c1130"/>
<stop offset="100%" stop-color="#05060f"/>
</radialGradient>
<linearGradient id="moonG" x1="0" y1="470" x2="0" y2="790" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8faff"/>
<stop offset="28%" stop-color="#d7ddec"/>
<stop offset="66%" stop-color="#a9b0c7"/>
<stop offset="100%" stop-color="#7f879f"/>
</linearGradient>
<radialGradient id="earthG" cx="34%" cy="28%" r="82%">
<stop offset="0" stop-color="#9ceaff"/>
<stop offset="42%" stop-color="#2f86d8"/>
<stop offset="100%" stop-color="#0a2554"/>
</radialGradient>
<radialGradient id="earthGlowG">
<stop offset="0" stop-color="#5fc8ff" stop-opacity=".55"/>
<stop offset="55%" stop-color="#2b7fd0" stop-opacity=".16"/>
<stop offset="100%" stop-color="#2b7fd0" stop-opacity="0"/>
</radialGradient>
<linearGradient id="helmetG" x1="0.2" y1="0" x2="0.6" y2="1">
<stop offset="0" stop-color="#eaffff" stop-opacity=".6"/>
<stop offset="52%" stop-color="#9fe0ff" stop-opacity=".1"/>
<stop offset="100%" stop-color="#2f6fa8" stop-opacity=".3"/>
</linearGradient>
<linearGradient id="suitG" x1="0.1" y1="0" x2="0.8" y2="1">
<stop offset="0" stop-color="#ffffff"/>
<stop offset="55%" stop-color="#e9eef8"/>
<stop offset="100%" stop-color="#bfc9de"/>
</linearGradient>
<linearGradient id="furG" x1="0" y1="0" x2="0.2" y2="1">
<stop offset="0" stop-color="#ffcd8f"/>
<stop offset="100%" stop-color="#ee9345"/>
</linearGradient>
<radialGradient id="eyeG" cx="40%" cy="30%" r="78%">
<stop offset="0" stop-color="#d2ffdf"/>
<stop offset="55%" stop-color="#4fc98a"/>
<stop offset="100%" stop-color="#125c3b"/>
</radialGradient>
<linearGradient id="deckG" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#3f4d79"/>
<stop offset="52%" stop-color="#1d2542"/>
<stop offset="100%" stop-color="#0f1426"/>
</linearGradient>
<linearGradient id="ringG" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ffdcab"/>
<stop offset="100%" stop-color="#c78d5a"/>
</linearGradient>
<linearGradient id="streakG" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#ffffff" stop-opacity="0"/>
<stop offset="100%" stop-color="#e6f7ff" stop-opacity=".95"/>
</linearGradient>
<radialGradient id="catGlowG">
<stop offset="0" stop-color="#8fdcff" stop-opacity=".18"/>
<stop offset="60%" stop-color="#5aa6ff" stop-opacity=".07"/>
<stop offset="100%" stop-color="#5aa6ff" stop-opacity="0"/>
</radialGradient>
<radialGradient id="vigG" cx="50%" cy="47%" r="72%">
<stop offset="52%" stop-color="#05060f" stop-opacity="0"/>
<stop offset="100%" stop-color="#05060f" stop-opacity=".92"/>
</radialGradient>
<filter id="blurSoft" x="-45%" y="-45%" width="190%" height="190%">
<feGaussianBlur stdDeviation="7"/>
</filter>
<filter id="blurBig" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="20"/>
</filter>
<clipPath id="moonClip"><circle cx="500" cy="1420" r="940"/></clipPath>
<g id="crater">
<ellipse rx="40" ry="13" fill="#7c8496" opacity=".22"/>
<ellipse cy="-2" rx="34" ry="9" fill="#ffffff" opacity=".38"/>
<ellipse cy="1" rx="26" ry="6" fill="#8d95a4" opacity=".25"/>
</g>
<g id="pawPrint">
<ellipse cy="0" rx="9" ry="7.5" fill="#7c8499"/>
<circle cx="-7.5" cy="-8.5" r="3.2" fill="#7c8499"/>
<circle cx="-2.5" cy="-11" r="3.2" fill="#7c8499"/>
<circle cx="2.5" cy="-11" r="3.2" fill="#7c8499"/>
<circle cx="7.5" cy="-8.5" r="3.2" fill="#7c8499"/>
</g>
</defs>
<!-- ===== SKY ===== -->
<rect x="0" y="0" width="1000" height="700" fill="url(#skyG)"/>
<g filter="url(#blurBig)" opacity=".55">
<ellipse cx="200" cy="150" rx="210" ry="130" fill="#3b2f80"/>
<ellipse cx="850" cy="470" rx="170" ry="100" fill="#1d5a7d"/>
<ellipse cx="620" cy="90" rx="160" ry="90" fill="#4a2b63"/>
</g>
<g id="stars"></g>
<g fill="#ffffff">
<path d="M 300 84 l 3 10 10 3 -10 3 -3 10 -3 -10 -10 -3 10 -3 z" opacity=".9"/>
<path d="M 702 200 l 2.5 8 8 2.5 -8 2.5 -2.5 8 -2.5 -8 -8 -2.5 8 -2.5 z" opacity=".7"/>
<path d="M 862 296 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".55"/>
<path d="M 118 336 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".55"/>
<path d="M 430 60 l 2 7 7 2 -7 2 -2 7 -2 -7 -7 -2 7 -2 z" opacity=".5"/>
</g>
<!-- ===== RINGED PLANET ===== -->
<g>
<ellipse cx="150" cy="120" rx="46" ry="13" transform="rotate(-18 150 120)" fill="none" stroke="url(#ringG)" stroke-width="5" opacity=".7"/>
<circle cx="150" cy="120" r="24" fill="url(#ringG)"/>
<circle cx="151" cy="121" r="24" fill="#b8763f" opacity=".35"/>
<circle cx="142" cy="112" r="7" fill="#a9683a" opacity=".55"/>
<circle cx="158" cy="130" r="5" fill="#a9683a" opacity=".45"/>
<path d="M 104 120 A 46 13 0 0 1 196 120" transform="rotate(-18 150 120)" fill="none" stroke="url(#ringG)" stroke-width="5" opacity=".95"/>
</g>
<!-- ===== EARTH ===== -->
<g>
<circle cx="830" cy="150" r="118" fill="url(#earthGlowG)" class="glowpulse"/>
<circle cx="830" cy="150" r="46" fill="url(#earthG)"/>
<g opacity=".8">
<path d="M 806 128 q 16 -10 28 2 q 8 8 -2 16 q -12 8 -22 -2 q -8 -8 -4 -16 z" fill="#4fbf7a"/>
<path d="M 848 160 q 14 -4 18 8 q 2 10 -10 12 q -12 0 -12 -10 q 0 -8 4 -10 z" fill="#4fbf7a"/>
<ellipse cx="822" cy="176" rx="16" ry="6" fill="#4fbf7a" opacity=".6"/>
</g>
<path d="M 812 120 q 26 -14 48 6" stroke="#ffffff" stroke-width="4" fill="none" opacity=".5" stroke-linecap="round"/>
<path d="M 800 168 q 22 12 46 2" stroke="#ffffff" stroke-width="3" fill="none" opacity=".38" stroke-linecap="round"/>
<circle cx="830" cy="150" r="46" fill="none" stroke="#b9e8ff" stroke-width="2" opacity=".55"/>
</g>
<circle cx="286" cy="286" r="9" fill="#cfd8ea" opacity=".45"/>
<circle cx="283" cy="283" r="3" fill="#9aa6bd" opacity=".5"/>
<!-- ===== SHOOTING STAR ===== -->
<g opacity=".85">
<path d="M 686 92 L 790 50" stroke="url(#streakG)" stroke-width="3" stroke-linecap="round"/>
<circle cx="790" cy="50" r="2.6" fill="#ffffff"/>
</g>
<!-- ===== MOON ===== -->
<g>
<circle cx="500" cy="1420" r="940" fill="url(#moonG)"/>
<g clip-path="url(#moonClip)">
<use href="#crater" transform="translate(190,660) scale(1.7,1.5)"/>
<use href="#crater" transform="translate(322,566) scale(.85,.8)"/>
<use href="#crater" transform="translate(690,558) scale(.75,.7)"/>
<use href="#crater" transform="translate(792,642) scale(1.5,1.3)"/>
<use href="#crater" transform="translate(470,694) scale(1.2,1.1)"/>
<use href="#crater" transform="translate(92,616) scale(1,.9)"/>
<use href="#crater" transform="translate(884,702) scale(1.4,1.2)"/>
<use href="#crater" transform="translate(602,678) scale(.6,.55)"/>
<use href="#crater" transform="translate(384,644) scale(.45,.4)"/>
<use href="#crater" transform="translate(246,536) scale(.5,.45)"/>
<use href="#crater" transform="translate(742,520) scale(.4,.35)"/>
<use href="#crater" transform="translate(560,606) scale(.35,.3)"/>
<g opacity=".32">
<use href="#pawPrint" transform="translate(118,676) scale(1.3)"/>
<use href="#pawPrint" transform="translate(196,642) scale(1.1)"/>
<use href="#pawPrint" transform="translate(258,616) scale(.95)"/>
<use href="#pawPrint" transform="translate(310,598) scale(.8)"/>
<use href="#pawPrint" transform="translate(352,586) scale(.7)"/>
</g>
<g fill="#8b93a9" opacity=".5">
<path d="M 236 692 l 14 -10 16 6 4 14 -18 8 -16 -6 z"/>
<path d="M 708 670 l 10 -8 12 4 3 10 -13 6 -12 -4 z"/>
<path d="M 88 642 l 8 -6 9 3 2 8 -10 5 -9 -3 z"/>
</g>
</g>
<circle cx="500" cy="1420" r="940" fill="none" stroke="#cfe4ff" stroke-width="14" opacity=".45" filter="url(#blurSoft)"/>
<circle cx="500" cy="1420" r="940" fill="none" stroke="#ffffff" stroke-width="2" opacity=".5"/>
</g>
<!-- speed streaks -->
<g stroke="#a9efff" stroke-linecap="round" opacity=".32">
<path d="M 236 588 h 72" stroke-width="4"/>
<path d="M 186 612 h 118" stroke-width="3"/>
<path d="M 262 634 h 62" stroke-width="3"/>
<path d="M 150 662 h 70" stroke-width="2.5" opacity=".6"/>
</g>
<ellipse cx="520" cy="430" rx="330" ry="300" fill="url(#catGlowG)"/>
<!-- ===== RIDER ===== -->
<g id="rider">
<!-- shadow -->
<ellipse cx="500" cy="636" rx="180" ry="18" fill="#5b6480" opacity=".35" filter="url(#blurSoft)"/>
<ellipse cx="500" cy="632" rx="118" ry="10" fill="#3f4864" opacity=".3" filter="url(#blurSoft)"/>
<!-- dust puffs -->
<g fill="#eaf4ff">
<circle class="puff p1" cx="402" cy="618" r="10"/>
<circle class="puff p2" cx="382" cy="626" r="7"/>
<circle class="puff p3" cx="394" cy="630" r="12"/>
<circle class="puff p4" cx="374" cy="612" r="6"/>
<circle class="puff p5" cx="388" cy="610" r="5"/>
</g>
<!-- board -->
<g id="board">
<rect x="408" y="592" width="26" height="16" rx="5" fill="#8b98b6"/>
<rect x="566" y="592" width="26" height="16" rx="5" fill="#8b98b8"/>
<g>
<circle cx="421" cy="612" r="19" fill="#1c2338" stroke="#0b0f1c" stroke-width="3"/>
<circle cx="421" cy="612" r="12" fill="#39476b"/>
<circle class="spin" cx="421" cy="612" r="11" fill="none" stroke="#6be1ff" stroke-width="2.5" stroke-dasharray="5 7" opacity=".85"/>
<circle cx="421" cy="612" r="4.5" fill="#6be1ff"/>
</g>
<g>
<circle cx="579" cy="612" r="19" fill="#1c2338" stroke="#0b0f1c" stroke-width="3"/>
<circle cx="579" cy="612" r="12" fill="#39476b"/>
<circle class="spin" cx="579" cy="612" r="11" fill="none" stroke="#6be1ff" stroke-width="2.5" stroke-dasharray="5 7" opacity=".85"/>
<circle cx="579" cy="612" r="4.5" fill="#6be1ff"/>
</g>
<rect x="352" y="576" width="296" height="22" rx="11" fill="url(#deckG)" stroke="#0a0e1c" stroke-width="3"/>
<rect x="360" y="580" width="280" height="7" rx="3.5" fill="#6be1ff" opacity=".45"/>
<rect x="462" y="590" width="60" height="4" rx="2" fill="#6be1ff" opacity=".45"/>
<path d="M 600 578 l 2.5 7 7 2.5 -7 2.5 -2.5 7 -2.5 -7 -7 -2.5 7 -2.5 z" fill="#ffd166"/>
</g>
<!-- cat -->
<g id="cat">
<!-- tail -->
<g id="tail">
<path d="M 468 546 C 420 572 368 552 360 510 C 354 484 366 464 388 464"
fill="none" stroke="url(#furG)" stroke-width="19" stroke-linecap="round"/>
<circle cx="388" cy="464" r="9.5" fill="#ffe9cf"/>
<path d="M 404 496 q 14 -6 22 2" stroke="#dd8a44" stroke-width="3" fill="none" opacity=".55" stroke-linecap="round"/>
<path d="M 372 476 q 12 -6 20 0" stroke="#dd8a44" stroke-width="3" fill="none" opacity=".45" stroke-linecap="round"/>
</g>
<!-- backpack -->
<g id="backpack">
<rect x="396" y="466" width="90" height="104" rx="24" fill="#c9d5e9" stroke="#9dabc6" stroke-width="3"/>
<rect x="410" y="480" width="62" height="30" rx="10" fill="#eaf1fb" stroke="#a8b6cf" stroke-width="2"/>
<circle cx="426" cy="527" r="6" fill="#6be1ff"/>
<circle cx="446" cy="527" r="6" fill="#6be1ff" opacity=".6"/>
<rect x="408" y="544" width="66" height="12" rx="6" fill="#aebbd4"/>
</g>
<!-- back arm -->
<path d="M 470 500 C 446 512 428 530 422 548" fill="none" stroke="#dde6f5" stroke-width="24" stroke-linecap="round"/>
<ellipse cx="418" cy="552" rx="15" ry="13" transform="rotate(-20 418 552)" fill="#f2f7ff" stroke="#c2cde2" stroke-width="3"/>
<ellipse cx="416" cy="554" rx="6.5" ry="5.5" fill="#f7b0b8" opacity=".9"/>
<!-- legs -->
<path d="M 496 544 C 472 552 454 558 444 566" fill="none" stroke="#dde6f5" stroke-width="30" stroke-linecap="round"/>
<path d="M 546 542 C 568 550 580 556 590 562" fill="none" stroke="#eef3fc" stroke-width="30" stroke-linecap="round"/>
<!-- boots -->
<ellipse cx="440" cy="568" rx="23" ry="11.5" fill="#d5e0f0" stroke="#a9b8d2" stroke-width="2.5"/>
<path d="M 420 574 h 40" stroke="#8fa0be" stroke-width="4" stroke-linecap="round"/>
<ellipse cx="592" cy="564" rx="23" ry="11.5" fill="#e6edf9" stroke="#b3c1d8" stroke-width="2.5"/>
<path d="M 572 570 h 40" stroke="#9aa9c4" stroke-width="4" stroke-linecap="round"/>
<!-- torso -->
<path d="M 474 468 C 452 486 448 522 462 550 C 492 566 552 566 578 550 C 592 520 588 486 566 468 Z"
fill="url(#suitG)" stroke="#b7c4dc" stroke-width="3"/>
<!-- suit details -->
<rect x="492" y="492" width="58" height="42" rx="11" fill="#dce7f7" stroke="#a7b6d1" stroke-width="2.5"/>
<rect x="500" y="500" width="42" height="15" rx="4" fill="#4fd8f7"/>
<rect x="503" y="504" width="10" height="3" rx="1.5" fill="#0b3a52" opacity=".5"/>
<rect x="516" y="504" width="16" height="3" rx="1.5" fill="#0b3a52" opacity=".4"/>
<rect x="503" y="509" width="22" height="3" rx="1.5" fill="#0b3a52" opacity=".35"/>
<circle cx="503" cy="524" r="4.5" fill="#7ef2a8"/>
<circle cx="518" cy="524" r="4.5" fill="#ffd166"/>
<circle cx="533" cy="524" r="4.5" fill="#ff8a8a"/>
<rect x="466" y="534" width="106" height="14" rx="7" fill="#c8d4e9" stroke="#a4b3ce" stroke-width="2.5"/>
<circle cx="566" cy="482" r="10" fill="#ffd166" stroke="#d9a93f" stroke-width="2"/>
<path d="M 566 477 l 1.8 4.4 4.7 .5 -3.5 3.2 1 4.7 -4 -2.5 -4 2.5 1 -4.7 -3.5 -3.2 4.7 -.5 z" fill="#a97a1f" opacity=".8"/>
<path d="M 470 476 C 462 490 460 504 462 518" stroke="#6be1ff" stroke-width="5" fill="none" stroke-linecap="round" opacity=".8"/>
<!-- neck + collar -->
<rect x="498" y="438" width="44" height="44" rx="20" fill="#e3eaf6"/>
<ellipse cx="520" cy="472" rx="54" ry="17" fill="#cfdaec" stroke="#a3b1cc" stroke-width="3"/>
<ellipse cx="520" cy="470" rx="44" ry="11" fill="#b9c7de" opacity=".55"/>
<!-- ears -->
<g id="earL">
<path d="M 486 374 L 470 326 L 524 352 Z" fill="url(#furG)" stroke="#dc8440" stroke-width="2" stroke-linejoin="round"/>
<path d="M 490 366 L 479 334 L 512 352 Z" fill="#ffb7ae" opacity=".85"/>
</g>
<path d="M 554 374 L 570 326 L 516 352 Z" fill="url(#furG)" stroke="#dc8440" stroke-width="2" stroke-linejoin="round"/>
<path d="M 550 366 L 561 334 L 528 352 Z" fill="#ffb7ae" opacity=".85"/>
<!-- head -->
<ellipse cx="520" cy="404" rx="55" ry="49" fill="url(#furG)"/>
<g stroke="#dd8a44" stroke-width="4" stroke-linecap="round" opacity=".5">
<path d="M 496 366 l -6 -14"/>
<path d="M 520 360 l 0 -14"/>
<path d="M 544 366 l 6 -14"/>
</g>
<ellipse cx="482" cy="424" rx="8" ry="5" fill="#ff9aa5" opacity=".4"/>
<ellipse cx="558" cy="424" rx="8" ry="5" fill="#ff9aa5" opacity=".4"/>
<!-- eyes -->
<ellipse cx="499" cy="398" rx="15" ry="16.5" fill="url(#eyeG)"/>
<ellipse cx="543" cy="398" rx="15" ry="16.5" fill="url(#eyeG)"/>
<ellipse cx="499" cy="399" rx="4.5" ry="13" fill="#101a1c"/>
<ellipse cx="543" cy="399" rx="4.5" ry="13" fill="#101a1c"/>
<circle cx="494" cy="392" r="4.5" fill="#ffffff" opacity=".95"/>
<circle cx="538" cy="392" r="4.5" fill="#ffffff" opacity=".95"/>
<circle cx="503" cy="404" r="2.2" fill="#ffffff" opacity=".7"/>
<circle cx="547" cy="404" r="2.2" fill="#ffffff" opacity=".7"/>
<!-- muzzle -->
<ellipse cx="510" cy="430" rx="16" ry="12" fill="#ffe9cf"/>
<ellipse cx="532" cy="430" rx="16" ry="12" fill="#ffe9cf"/>
<path d="M 514 414 L 526 414 Q 527 419 520 423 Q 513 419 514 414 Z" fill="#f28d9b"/>
<path d="M 520 423 v 5 M 520 428 q -7 6 -13 1 M 520 428 q 7 6 13 1" stroke="#a9713f" stroke-width="2.4" fill="none" stroke-linecap="round"/>
<!-- whiskers -->
<g stroke="#ffffff" stroke-width="2.2" stroke-linecap="round" opacity=".85">
<path d="M 498 426 L 462 418"/>
<path d="M 496 432 L 458 432"/>
<path d="M 498 438 L 464 446"/>
<path d="M 542 426 L 578 418"/>
<path d="M 544 432 L 582 432"/>
<path d="M 542 438 L 576 446"/>
</g>
<!-- helmet -->
<circle cx="520" cy="396" r="80" fill="url(#helmetG)" stroke="#e2f6ff" stroke-width="4"/>
<circle cx="520" cy="396" r="80" fill="none" stroke="#8fc8ea" stroke-width="8" opacity=".16"/>
<path d="M 451 364 A 76 76 0 0 1 500 323" fill="none" stroke="#ffffff" stroke-width="9" stroke-linecap="round" opacity=".8"/>
<path d="M 464 448 A 76 76 0 0 1 444 404" fill="none" stroke="#ffffff" stroke-width="5" stroke-linecap="round" opacity=".3"/>
<!-- antenna -->
<line x1="568" y1="338" x2="596" y2="300" stroke="#cfd9ea" stroke-width="4" stroke-linecap="round"/>
<circle cx="598" cy="297" r="13" fill="#6be1ff" opacity=".28" class="glowpulse"/>
<circle cx="598" cy="297" r="6.5" fill="#6be1ff"/>
<!-- front arm -->
<path d="M 564 492 C 592 486 616 468 630 446" fill="none" stroke="#eef3fc" stroke-width="26" stroke-linecap="round"/>
<path d="M 572 500 C 596 494 616 478 628 458" fill="none" stroke="#cfdaea" stroke-width="3.5" stroke-linecap="round" opacity=".45"/>
<ellipse cx="632" cy="441" rx="18" ry="17" fill="#f8fbff" stroke="#c2cde2" stroke-width="3"/>
<ellipse cx="632" cy="445" rx="9" ry="7" fill="#f7b0b8" opacity=".95"/>
<circle cx="622" cy="432" r="3.6" fill="#f7b0b8" opacity=".95"/>
<circle cx="632" cy="429" r="3.6" fill="#f7b0b8" opacity=".95"/>
<circle cx="642" cy="432" r="3.6" fill="#f7b0b8" opacity=".95"/>
</g>
</g>
<!-- vignette -->
<rect x="0" y="0" width="1000" height="700" fill="url(#vigG)" pointer-events="none"/>
<!-- label -->
<g fill="#7d8aa8" opacity=".75" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="14" letter-spacing="3">
<text x="58" y="58">LUNAR SK8 · 1/6 g</text>
</g>
</svg>
<script>
(function () {
var g = document.getElementById('stars');
if (!g) return;
var NS = 'http://www.w3.org/2000/svg';
var seed = 123456789;
function rnd() {
seed = (s => (s * 16807) % 2147483647)(seed);
return seed / 2147483647;
}
var frag = document.createDocumentFragment();
for (var i = 0; i < 130; i++) {
var c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
c.setAttribute('cx', (rnd() * 1000).toFixed(1));
c.setAttribute('cy', (rnd() * 620).toFixed(1));
c.setAttribute('r', (0.5 + rnd() * 1.6).toFixed(2));
c.setAttribute('fill', rnd() > 0.86 ? '#c6e8ff' : '#ffffff');
c.setAttribute('fill-opacity', (0.3 + rnd() * 0.7).toFixed(2));
c.style.animation = 'twinkle ' + (2.4 + rnd() * 4).toFixed(1) + 's ease-in-out ' + (rnd() * 5).toFixed(1) + 's infinite';
frag.appendChild(c);
}
g.appendChild(frag);
})();
</script>
</body>
</html>
```
### Visual Highlights: An Astronaut Cat’s Lunar Ride
The scene leans into playful sci-fi charm, with the cat as the focal point and the moon’s quiet calm as its stage.
- **Warm vs. cool contrast:** The cat’s orange fur and pink paw pads stand out instantly against the deep blue space and cool silvery moon, giving the character a friendly, eye-catching presence.
- **Layered lunar canvas:** A soft radial sky glows behind scattered twinkling stars, while the moon’s surface is built from muted craters and paw prints, adding gentle texture without distracting from the cat.
- **Subtle motion and life:** The skateboard wheels spin, a dust trail puffs behind the board, the tail sways, and one ear twitches, making the whole scene feel quietly active rather than static.
- **Narrative details:** The astronaut suit, backpack, and antenna read clearly as “space gear,” while the little “LUNAR SK8 · 1/6 g” label in the corner gives it a playful mission-patch feel.