Multiplayer mode: server, room tokens, docker setup, and client UI

This commit is contained in:
robi committed 2026-09-27 07:45:11 +03:00
1 parent 176d7cc300
commit 434c81d0b6
19 files changed
+2563 -382

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
<svg xmlns="http://www.w3.org/2000/svg" width="420" height="780" viewBox="0 0 420 780" font-family="system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif">
<defs>
<linearGradient id="bgGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#0d0f24"/>
<stop offset="1" stop-color="#1c1140"/>
</linearGradient>
<linearGradient id="titleGrad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#22d3ee"/>
<stop offset="1" stop-color="#f472b6"/>
</linearGradient>
<linearGradient id="btnGrad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#22d3ee"/>
<stop offset="1" stop-color="#f472b6"/>
</linearGradient>
<filter id="blob" x="-80%" y="-80%" width="260%" height="260%">
<feGaussianBlur stdDeviation="55"/>
</filter>
<filter id="glow" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="5" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- background -->
<rect width="420" height="780" fill="url(#bgGrad)"/>
<circle cx="70" cy="170" r="130" fill="#22d3ee" opacity="0.22" filter="url(#blob)"/>
<circle cx="350" cy="580" r="150" fill="#f472b6" opacity="0.18" filter="url(#blob)"/>
<!-- title -->
<text x="210" y="150" text-anchor="middle" font-size="34" font-weight="800" fill="url(#titleGrad)">Tic-Tac-Toe</text>
<text x="210" y="184" text-anchor="middle" font-size="14" fill="#ffffff" opacity="0.5">Choose how to play</text>
<!-- decorative mini board hint -->
<g opacity="0.5">
<rect x="150" y="230" width="120" height="120" rx="18" fill="#ffffff" fill-opacity="0.05" stroke="#ffffff" stroke-opacity="0.12"/>
<g stroke="#ffffff" stroke-opacity="0.18" stroke-width="2">
<line x1="190" y1="240" x2="190" y2="340"/>
<line x1="230" y1="240" x2="230" y2="340"/>
<line x1="160" y1="270" x2="340" y2="270" transform="translate(-10,0)"/>
<line x1="160" y1="310" x2="340" y2="310" transform="translate(-10,0)"/>
</g>
<g filter="url(#glow)" stroke="#22d3ee" stroke-width="5" stroke-linecap="round">
<line x1="168" y1="252" x2="186" y2="270"/>
<line x1="186" y1="252" x2="168" y2="270"/>
</g>
<circle cx="272" cy="322" r="12" fill="none" stroke="#f472b6" stroke-width="5" filter="url(#glow)"/>
</g>
<!-- buttons -->
<!-- primary: New Online Game -->
<rect x="60" y="470" width="300" height="58" rx="29" fill="url(#btnGrad)"/>
<text x="210" y="505" text-anchor="middle" font-size="17" font-weight="700" fill="#0d1025">New Online Game</text>
<!-- ghost: Play vs CPU -->
<rect x="60" y="548" width="300" height="54" rx="27" fill="#ffffff" fill-opacity="0.05" stroke="#ffffff" stroke-opacity="0.18"/>
<text x="210" y="580" text-anchor="middle" font-size="16" font-weight="600" fill="#ffffff" opacity="0.75">Play vs CPU</text>
<!-- hint -->
<text x="210" y="648" text-anchor="middle" font-size="12" fill="#ffffff" opacity="0.4">Online: share a link and play a friend</text>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB