extremely claude-assisted go game based on atproto! working on cleaning up and giving a more unique design, still has a bit of a slop vibe to it.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix UI issues: spacing, hover, reload, checkboxes, share button

1. Game list spacing: Fixed inconsistent game item heights by using
flexbox gap and making game-info flex: 1

2. Board hover: The interactive check was already correct - verified
hover only shows when it's your turn

3. Move submission: Removed page reload after moves/passes - now
updates local state directly. Only reloads if game ends (double-pass)

4. Stone-style checkboxes: Styled "My games" and "Your turn" checkboxes
to look like Go stones (white unchecked, black checked)

5. Share button: Made lighter/subtler with cloud background and border,
replaced butterfly emoji with Bluesky SVG logo, shortened to "Share"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+70 -12
+22 -2
src/routes/+page.svelte
··· 767 767 768 768 .game-item { 769 769 display: flex; 770 - justify-content: space-between; 771 770 align-items: center; 771 + gap: 1rem; 772 772 padding: 1rem 1.25rem; 773 773 border: 1px solid var(--sky-blue-pale); 774 774 border-radius: 0.75rem; ··· 799 799 display: flex; 800 800 flex-direction: column; 801 801 gap: 0.375rem; 802 + flex: 1; 803 + min-width: 0; 802 804 } 803 805 804 806 .game-title-row { ··· 1044 1046 } 1045 1047 1046 1048 .toggle-label input { 1049 + appearance: none; 1050 + -webkit-appearance: none; 1051 + width: 18px; 1052 + height: 18px; 1053 + border-radius: 50%; 1054 + border: 2px solid var(--sky-gray-light); 1055 + background: linear-gradient(135deg, #fafafa 0%, #e0e0e0 100%); 1047 1056 cursor: pointer; 1048 - accent-color: var(--sky-apricot-dark); 1057 + transition: all 0.2s; 1058 + box-shadow: inset 0 1px 2px rgba(255, 255, 255, 0.8), 0 1px 2px rgba(0, 0, 0, 0.1); 1059 + } 1060 + 1061 + .toggle-label input:checked { 1062 + border-color: #1a1a1a; 1063 + background: radial-gradient(circle at 35% 35%, #4a4a4a 0%, #1a1a1a 100%); 1064 + box-shadow: inset 0 1px 2px rgba(255, 255, 255, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3); 1065 + } 1066 + 1067 + .toggle-label input:hover { 1068 + border-color: var(--sky-slate); 1049 1069 } 1050 1070 1051 1071 .waiting-games-grid {
+1 -1
src/routes/api/games/[id]/pass/+server.ts
··· 125 125 .execute(); 126 126 } 127 127 128 - return json({ success: true, uri: result.data.uri }); 128 + return json({ success: true, uri: result.data.uri, gameEnded: isConsecutivePass }); 129 129 } catch (err) { 130 130 console.error('Failed to record pass:', err); 131 131 throw error(500, 'Failed to record pass');
+47 -9
src/routes/game/[id]/+page.svelte
··· 256 256 }); 257 257 258 258 if (response.ok) { 259 - window.location.reload(); 259 + const result = await response.json(); 260 + // Add the new move to local state (board already shows it visually) 261 + const newMove: MoveRecord = { 262 + $type: 'boo.sky.go.move', 263 + game: data.gameAtUri, 264 + player: data.session!.did, 265 + moveNumber: moves.length + passes.length + 1, 266 + x, 267 + y, 268 + color: (moves.length + passes.length) % 2 === 0 ? 'black' : 'white', 269 + captureCount: captures, 270 + createdAt: new Date().toISOString(), 271 + uri: result.uri, 272 + }; 273 + moves = [...moves, newMove]; 260 274 } else { 261 275 alert('Failed to record move'); 276 + // Reload to reset board state 277 + window.location.reload(); 262 278 } 263 279 } catch (err) { 264 280 console.error('Failed to record move:', err); ··· 278 294 }); 279 295 280 296 if (response.ok) { 281 - window.location.reload(); 297 + const result = await response.json(); 298 + // Add the new pass to local state 299 + const newPass: PassRecord = { 300 + $type: 'boo.sky.go.pass', 301 + game: data.gameAtUri, 302 + player: data.session!.did, 303 + moveNumber: moves.length + passes.length + 1, 304 + color: (moves.length + passes.length) % 2 === 0 ? 'black' : 'white', 305 + createdAt: new Date().toISOString(), 306 + }; 307 + passes = [...passes, newPass]; 308 + 309 + // If this was a consecutive pass (game ended), reload to show scoring UI 310 + if (result.gameEnded) { 311 + window.location.reload(); 312 + } 282 313 } else { 283 314 alert('Failed to record pass'); 284 315 } ··· 652 683 <p><strong>Board:</strong> {gameBoardSize}x{gameBoardSize}</p> 653 684 <p><strong>Moves:</strong> {#if loadingMoves}<span class="skeleton-text">...</span>{:else}{moves.length}{/if}</p> 654 685 <a href={getShareUrl()} target="_blank" rel="noopener noreferrer" class="share-button-small"> 655 - 🦋 Share on Bluesky 686 + <svg viewBox="0 0 16 16" fill="currentColor"><path d="M3.468 1.948C5.303 3.325 7.276 6.118 8 7.616c.725-1.498 2.698-4.29 4.532-5.668C13.855.955 16 .186 16 2.632c0 .489-.28 4.105-.444 4.692-.572 2.04-2.653 2.561-4.504 2.246 3.236.551 4.06 2.375 2.281 4.2-3.376 3.464-4.852-.87-5.23-1.98-.07-.204-.103-.3-.103-.218 0-.081-.033.014-.102.218-.379 1.11-1.855 5.444-5.231 1.98-1.778-1.825-.955-3.65 2.28-4.2-1.85.315-3.932-.205-4.503-2.246C.28 6.737 0 3.12 0 2.632 0 .186 2.145.955 3.468 1.948"/></svg> 687 + Share 656 688 </a> 657 689 </div> 658 690 ··· 1192 1224 align-items: center; 1193 1225 gap: 0.375rem; 1194 1226 padding: 0.375rem 0.75rem; 1195 - background: linear-gradient(135deg, #0085ff 0%, #0066cc 100%); 1196 - color: white; 1197 - border: none; 1227 + background: var(--sky-cloud); 1228 + color: var(--sky-slate); 1229 + border: 1px solid var(--sky-blue-pale); 1198 1230 border-radius: 0.375rem; 1199 1231 font-size: 0.75rem; 1200 - font-weight: 600; 1232 + font-weight: 500; 1201 1233 cursor: pointer; 1202 1234 transition: all 0.2s; 1203 1235 text-decoration: none; ··· 1205 1237 } 1206 1238 1207 1239 .share-button-small:hover { 1208 - transform: translateY(-1px); 1209 - box-shadow: 0 2px 8px rgba(0, 133, 255, 0.3); 1240 + background: var(--sky-blue-pale); 1241 + color: var(--sky-slate-dark); 1242 + border-color: #0085ff; 1243 + } 1244 + 1245 + .share-button-small svg { 1246 + width: 14px; 1247 + height: 14px; 1210 1248 } 1211 1249 1212 1250 .copy-invite-btn {