@maxr0ssi/chaos-chess 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,36 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0
4
+
5
+ ### Breaking
6
+
7
+ - `GameResult` has a new value, `'king-captured'`. Exhaustive `switch` statements over `GameResult` need a case for it.
8
+ - `onMove` now fires for the AI's moves too, not only the human's.
9
+
10
+ ### Added
11
+
12
+ - `initialState` and `onStateChange` props, and the exported `ChaosChessState` type, so a host can keep a game across unmounts. `initialState` is validated; an invalid one is ignored.
13
+ - "New game" button in the top bar, usable at any time, including during promotion and after the game ends.
14
+ - "AI unavailable" message and two-player mode when the engine fails to start 3 times in a row.
15
+ - Released engines are kept for 5 minutes and reused when a game mounts again (also under React StrictMode).
16
+
17
+ ### Fixed
18
+
19
+ - **The AI no longer gets stuck.** Chaos could create positions Stockfish refuses (more than 16 pieces or 8 pawns on a side, a missing king, the side not to move in check), and castling rights left over after a rook was removed could freeze Stockfish completely. Chaos now only creates positions both chess.js and Stockfish accept. If Stockfish still can't give a move, the AI plays a random legal move.
20
+ - The engine recovers from hangs and crashes: every wait has a timeout, a stuck worker is replaced, and a slow search plays its best move so far instead of starting over.
21
+ - A cancelled search's answer could be played on the next position.
22
+ - The human could move the AI's pieces while Stockfish was loading.
23
+ - AI moves were not recorded: no move history, last-move highlight, move sound or `onMove`. As a result, threefold repetition was never detected.
24
+ - The fifty-move rule is reported as `'fifty-move'`.
25
+ - Stale castling and en passant fields after chaos allowed castling without a rook, or en passant captures of missing pawns.
26
+ - Chaos kept firing in a hidden tab, could fire right after the AI's move, and ignored a new STUPID level until the countdown ended.
27
+ - New game during the AI's search could let the old search play into the new game.
28
+ - Restoring a finished game fired `onGameOver` again.
29
+ - Two games on one page shared the mute setting.
30
+ - `go depth 0` or a non-numeric depth never returned; depth is now clamped to 1-20.
31
+ - Buttons are `type="button"`, so they don't submit a surrounding form.
32
+ - No double-tap zoom on the board on iOS.
33
+
34
+ ## 0.1.7 and earlier
35
+
36
+ See the git history.
package/README.md CHANGED
@@ -1,73 +1,57 @@
1
- # React + TypeScript + Vite
1
+ # @maxr0ssi/chaos-chess
2
2
 
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
3
+ Chess against Stockfish, where random "chaos" events add and remove pieces while you think. A React component.
4
4
 
5
- Currently, two official plugins are available:
5
+ ## Install
6
6
 
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
7
+ ```bash
8
+ npm install @maxr0ssi/chaos-chess
9
+ ```
10
+
11
+ React 18 or later is a peer dependency.
9
12
 
10
- ## React Compiler
13
+ ## Serve the engine
11
14
 
12
- The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
15
+ The package ships Stockfish in `dist/stockfish/` (`stockfish-18-lite-single.js` and `.wasm`, about 7 MiB). Serve both files from one folder on your site. By default the component loads `/stockfish/stockfish-18-lite-single.js`; set `stockfishWorkerPath` to use another location.
13
16
 
14
- ## Expanding the ESLint configuration
17
+ With Vite, for example:
15
18
 
16
- If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
19
+ ```ts
20
+ import { viteStaticCopy } from 'vite-plugin-static-copy';
21
+
22
+ viteStaticCopy({
23
+ targets: [{ src: 'node_modules/@maxr0ssi/chaos-chess/dist/stockfish/*', dest: 'stockfish' }],
24
+ });
25
+ ```
17
26
 
18
- ```js
19
- export default defineConfig([
20
- globalIgnores(['dist']),
21
- {
22
- files: ['**/*.{ts,tsx}'],
23
- extends: [
24
- // Other configs...
27
+ ## Use
25
28
 
26
- // Remove tseslint.configs.recommended and replace with this
27
- tseslint.configs.recommendedTypeChecked,
28
- // Alternatively, use this for stricter rules
29
- tseslint.configs.strictTypeChecked,
30
- // Optionally, add this for stylistic rules
31
- tseslint.configs.stylisticTypeChecked,
29
+ ```tsx
30
+ import { ChaosChess } from '@maxr0ssi/chaos-chess';
31
+ import '@maxr0ssi/chaos-chess/styles';
32
32
 
33
- // Other configs...
34
- ],
35
- languageOptions: {
36
- parserOptions: {
37
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
38
- tsconfigRootDir: import.meta.dirname,
39
- },
40
- // other options...
41
- },
42
- },
43
- ])
33
+ export function ChessPage() {
34
+ return <ChaosChess />;
35
+ }
44
36
  ```
45
37
 
46
- You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
47
-
48
- ```js
49
- // eslint.config.js
50
- import reactX from 'eslint-plugin-react-x'
51
- import reactDom from 'eslint-plugin-react-dom'
52
-
53
- export default defineConfig([
54
- globalIgnores(['dist']),
55
- {
56
- files: ['**/*.{ts,tsx}'],
57
- extends: [
58
- // Other configs...
59
- // Enable lint rules for React
60
- reactX.configs['recommended-typescript'],
61
- // Enable lint rules for React DOM
62
- reactDom.configs.recommended,
63
- ],
64
- languageOptions: {
65
- parserOptions: {
66
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
67
- tsconfigRootDir: import.meta.dirname,
68
- },
69
- // other options...
70
- },
71
- },
72
- ])
38
+ Without `defaultHumanColor`, the player picks a side first. Useful props:
39
+
40
+ | Prop | Purpose |
41
+ |---|---|
42
+ | `defaultHumanColor`, `defaultDepth`, `defaultStupidLevel`, `defaultMuted` | Starting settings |
43
+ | `depth` / `onDepthChange`, `stupidLevel` / `onStupidLevelChange` | Controlled settings |
44
+ | `initialState` / `onStateChange` | Save a game and restore it after unmounting |
45
+ | `onMove`, `onGameOver`, `onChaosAction`, `onRestart` | Events |
46
+ | `stockfishWorkerPath` | Where the engine is served |
47
+ | `showControls`, `showMuteButton`, `skipSetup`, `className` | Layout |
48
+
49
+ `INTEGRATION.md` has the full props reference, theming variables and the save/restore pattern. `CHANGELOG.md` lists changes by version.
50
+
51
+ ## Develop
52
+
53
+ ```bash
54
+ npm run dev # standalone app
55
+ npm test # unit, component and engine integration tests
56
+ npm run build:lib # library build into dist/
73
57
  ```
@@ -1 +1 @@
1
- ._square_1tsnw_1{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:100%;cursor:pointer;transition:background-color .15s ease;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}._light_1tsnw_14{background-color:var(--cc-square-light)}._dark_1tsnw_18{background-color:var(--cc-square-dark)}._selected_1tsnw_22{background-color:rgba(var(--cc-accent-rgb),.35)!important}._legalMove_1tsnw_26:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:28%;height:28%;border-radius:50%;background-color:rgba(var(--cc-accent-rgb),.3);pointer-events:none}._legalCapture_1tsnw_39:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:85%;height:85%;border-radius:50%;border:3px solid rgba(var(--cc-accent-rgb),.35);background:transparent;pointer-events:none;box-sizing:border-box}._check_1tsnw_54{background-color:rgba(var(--cc-check-rgb),.5)!important}._lastMoveFrom_1tsnw_58{background-color:rgba(var(--cc-orange-rgb),.2)!important}._lastMoveTo_1tsnw_62{background-color:rgba(var(--cc-orange-rgb),.3)!important}._chaosFlash_1tsnw_66{animation:_cc-chaosFlash_1tsnw_1 .6s ease-out}._piece_1tsnw_70{font-size:calc(min(560px,90vw)*.09375);line-height:1;filter:drop-shadow(0 2px 4px rgba(0,0,0,.5));transition:transform .15s ease;pointer-events:none}._pieceWhite_1tsnw_78{color:var(--cc-piece-white, #F5F5F5);filter:drop-shadow(0 2px 4px rgba(0,0,0,.5))}._pieceBlack_1tsnw_83{color:var(--cc-piece-black, #1a1a1a);filter:drop-shadow(0 1px 3px rgba(255,255,255,.3))}._pieceAppear_1tsnw_88{animation:_cc-pieceAppear_1tsnw_1 .4s ease-out}._pieceDisappear_1tsnw_92{animation:_cc-pieceDisappear_1tsnw_1 .3s ease-in forwards}._board_1jwdv_1{display:grid;grid-template-columns:repeat(8,1fr);grid-template-rows:repeat(8,1fr);width:min(560px,90vw);height:min(560px,90vw);border-radius:12px;overflow:hidden;box-shadow:var(--cc-shadow-board);border:1px solid var(--cc-border-subtle)}._rankLabel_1jwdv_13{position:absolute;top:2px;left:4px;font-size:10px;font-family:var(--cc-font-body);color:rgba(var(--cc-text-rgb),.35);pointer-events:none;-webkit-user-select:none;user-select:none}._fileLabel_1jwdv_24{position:absolute;bottom:2px;right:4px;font-size:10px;font-family:var(--cc-font-body);color:rgba(var(--cc-text-rgb),.35);pointer-events:none;-webkit-user-select:none;user-select:none}._boardLocked_1jwdv_35{opacity:.85;pointer-events:none}._promotionOverlay_1p5vy_2{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#0009;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);z-index:100;animation:_cc-fadeIn_1p5vy_1 .2s ease-out}._promotionDialog_1p5vy_14{display:flex;flex-direction:column;align-items:center;gap:16px;padding:24px 32px;background:var(--cc-surface-glass);border:1px solid rgba(var(--cc-accent-rgb),.2);border-radius:20px;box-shadow:var(--cc-shadow-dialog);animation:_cc-bounceIn_1p5vy_1 .4s ease-out}._promotionTitle_1p5vy_27{font-family:var(--cc-font-display);font-size:16px;color:var(--cc-text);margin:0}._promotionOptions_1p5vy_34{display:flex;gap:12px}._promotionBtn_1p5vy_39{display:flex;align-items:center;justify-content:center;width:64px;height:64px;font-size:40px;background:var(--cc-btn-bg);border:1px solid var(--cc-border-light);border-radius:12px;cursor:pointer;transition:all .15s ease;filter:drop-shadow(0 2px 4px rgba(0,0,0,.5))}._promotionBtn_1p5vy_39:hover{background:var(--cc-btn-bg-hover);border-color:var(--cc-btn-border-hover);transform:scale(1.08)}._gameOverOverlay_1p5vy_61{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#000000a6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:100;animation:_cc-fadeIn_1p5vy_1 .3s ease-out}._gameOverBanner_1p5vy_73{display:flex;flex-direction:column;align-items:center;gap:20px;padding:32px 48px;background:var(--cc-surface-glass-heavy);border:1px solid rgba(var(--cc-accent-rgb),.2);border-radius:20px;box-shadow:var(--cc-shadow-banner);animation:_cc-bounceIn_1p5vy_1 .5s ease-out}._gameOverResult_1p5vy_86{font-family:var(--cc-font-display);font-size:28px;font-weight:700;color:var(--cc-accent);margin:0;text-align:center}._gameOverDetail_1p5vy_95{font-family:var(--cc-font-body);font-size:14px;color:rgba(var(--cc-text-rgb),.7);margin:0}._restartBtn_1p5vy_102{padding:10px 32px;font-family:var(--cc-font-display);font-size:15px;font-weight:600;color:var(--cc-bg);background:var(--cc-accent);border:none;border-radius:999px;cursor:pointer;transition:all .15s ease}._restartBtn_1p5vy_102:hover{transform:scale(1.05);box-shadow:0 0 16px rgba(var(--cc-accent-rgb),.4)}._chaosBar_1p5vy_121{display:flex;align-items:center;gap:10px;width:100%;padding:0 4px}._chaosBarLabel_1p5vy_129{font-family:var(--cc-font-body);font-size:10px;font-weight:700;letter-spacing:1.5px;color:rgba(var(--cc-accent-rgb),.7);white-space:nowrap}._chaosBarTrack_1p5vy_138{flex:1;height:6px;border-radius:3px;background:var(--cc-border-subtle);overflow:hidden}._chaosBarFill_1p5vy_146{height:100%;border-radius:3px;background:var(--cc-accent);transition:width .3s ease;box-shadow:0 0 calc(4px + 12px * var(--glow, 0)) rgba(var(--cc-accent-rgb),calc(.3 + .5 * var(--glow, 0)))}._difficultySelector_1p5vy_155{display:flex;flex-direction:column;gap:4px;flex:1}._difficultyLabel_1p5vy_162{font-family:var(--cc-font-body);font-size:11px;color:rgba(var(--cc-text-rgb),.5)}._difficultySlider_1p5vy_168{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:2px;background:var(--cc-slider-track);outline:none}._difficultySlider_1p5vy_168::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border-radius:50%;background:var(--cc-accent);cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._difficultySlider_1p5vy_168::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._difficultyValue_1p5vy_199{font-family:var(--cc-font-display);font-size:11px;color:var(--cc-accent)}._sidePickerOverlay_1p5vy_206{display:flex;align-items:center;justify-content:center;width:100%;min-height:min(560px,90vw)}._sidePickerCard_1p5vy_214{display:flex;flex-direction:column;align-items:center;gap:28px;padding:40px 48px;background:var(--cc-surface-glass);border:1px solid rgba(var(--cc-accent-rgb),.2);border-radius:20px;box-shadow:var(--cc-shadow-dialog);animation:_cc-bounceIn_1p5vy_1 .5s ease-out}._sidePickerTitle_1p5vy_227{font-family:var(--cc-font-display);font-size:22px;font-weight:700;color:var(--cc-text);margin:0}._sidePickerOptions_1p5vy_235{display:flex;gap:20px}._sidePickerBtn_1p5vy_240{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 28px;background:var(--cc-btn-bg);border:1px solid var(--cc-border-light);border-radius:16px;cursor:pointer;transition:all .2s ease}._sidePickerBtn_1p5vy_240:hover{background:rgba(var(--cc-accent-rgb),.12);border-color:var(--cc-btn-border-hover);transform:scale(1.06);box-shadow:0 0 20px rgba(var(--cc-accent-rgb),.25)}._sidePickerIcon_1p5vy_260{font-size:56px;line-height:1}._sidePickerWhite_1p5vy_265{color:var(--cc-piece-white);filter:drop-shadow(0 2px 6px rgba(0,0,0,.6))}._sidePickerBlack_1p5vy_270{color:var(--cc-piece-black);filter:drop-shadow(0 0 4px rgba(var(--cc-text-rgb),.3))}._sidePickerLabel_1p5vy_275{font-family:var(--cc-font-display);font-size:15px;font-weight:600;color:var(--cc-text)}._sidePickerSettings_1p5vy_282{display:flex;gap:24px;width:100%;padding-top:8px;border-top:1px solid var(--cc-border-subtle)}._stupidLevel_1p5vy_291{display:flex;flex-direction:column;gap:4px;min-width:100px}._stupidLevelHeader_1p5vy_298{display:flex;justify-content:space-between;align-items:center}._stupidLevelLabel_1p5vy_304{font-family:var(--cc-font-display);font-size:10px;font-weight:700;letter-spacing:1px;color:rgba(var(--cc-text-rgb),.5)}._stupidLevelValue_1p5vy_312{font-family:var(--cc-font-display);font-size:10px;font-weight:700;color:var(--cc-accent)}._stupidLevelSlider_1p5vy_319{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:2px;background:var(--cc-slider-track);outline:none}._stupidLevelSlider_1p5vy_319::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border-radius:50%;background:var(--cc-accent);cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._stupidLevelSlider_1p5vy_319::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._muteBtn_1p5vy_351{display:flex;align-items:center;justify-content:center;width:32px;height:32px;font-size:16px;background:none;border:1px solid rgba(255,255,255,.1);border-radius:8px;cursor:pointer;color:var(--cc-accent);transition:all .15s ease}._muteBtn_1p5vy_351:hover{background:rgba(var(--cc-accent-rgb),.1);border-color:rgba(var(--cc-accent-rgb),.25)}._muteBtnMuted_1p5vy_371{color:rgba(var(--cc-text-rgb),.3)}._muteBtnMuted_1p5vy_371:hover{background:var(--cc-btn-bg);border-color:#ffffff26}._chaosToast_1p5vy_381{position:absolute;top:24px;left:50%;transform:translate(-50%);padding:10px 24px;font-family:var(--cc-font-body);font-size:14px;font-weight:600;color:var(--cc-orange);background:var(--cc-surface-glass);border:1px solid rgba(var(--cc-orange-rgb),.3);border-radius:12px;box-shadow:0 4px 24px #0006,0 0 12px rgba(var(--cc-orange-rgb),.15);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:200;white-space:nowrap;animation:_cc-slideIn_1p5vy_1 .3s ease-out}._chaosToastFading_1p5vy_401{animation:_cc-slideOut_1p5vy_1 .4s ease-in forwards}._container_hob8y_1{display:flex;flex-direction:column;align-items:center;gap:12px;width:min(560px,90vw);margin:0 auto;font-family:var(--cc-font-body)}._topBar_hob8y_11{display:flex;align-items:center;justify-content:space-between;width:100%;padding:8px 4px}._topBarLeft_hob8y_19{display:flex;align-items:center;gap:8px}._statusText_hob8y_25{font-family:var(--cc-font-display);font-size:14px;color:var(--cc-text)}._thinking_hob8y_31{display:flex;align-items:center;gap:6px;font-family:var(--cc-font-display);font-size:13px;color:var(--cc-accent);animation:_cc-thinkingPulse_hob8y_1 1.2s ease-in-out infinite}._bottomBar_hob8y_41{display:flex;align-items:center;justify-content:space-between;width:100%;padding:8px 4px;gap:16px}[data-chaos-chess]{--cc-accent: var(--color-accent-primary, #82FFF4);--cc-accent-rgb: var(--color-accent-primary-rgb, 130, 255, 244);--cc-bg: var(--color-surface-base, #242222);--cc-surface-glass: rgba(36, 34, 34, .92);--cc-surface-glass-heavy: rgba(36, 34, 34, .95);--cc-text: var(--color-text-primary, #F5F5F5);--cc-text-rgb: 245, 245, 245;--cc-orange: var(--color-accent-orange-soft, #FFB67A);--cc-orange-rgb: 255, 182, 122;--cc-red-rgb: 255, 80, 80;--cc-check-rgb: 255, 50, 50;--cc-border-subtle: rgba(255, 255, 255, .08);--cc-border-light: rgba(255, 255, 255, .12);--cc-square-light: rgba(255, 255, 255, .12);--cc-square-dark: rgba(0, 0, 0, .25);--cc-font-body: var(--font-sans, "Inter", sans-serif);--cc-font-display: var(--font-display, "Comfortaa", cursive);--cc-btn-bg: rgba(255, 255, 255, .06);--cc-btn-bg-hover: rgba(var(--cc-accent-rgb), .15);--cc-btn-border-hover: rgba(var(--cc-accent-rgb), .3);--cc-slider-track: rgba(255, 255, 255, .1);--cc-shadow-board: 0 8px 32px rgba(0, 0, 0, .4);--cc-shadow-dialog: 0 8px 40px rgba(0, 0, 0, .5), 0 0 20px rgba(var(--cc-accent-rgb), .1);--cc-shadow-banner: 0 12px 48px rgba(0, 0, 0, .5), 0 0 24px rgba(var(--cc-accent-rgb), .1);--cc-piece-white: #F5F5F5;--cc-piece-black: #1a1a1a;position:relative}html.light-mode [data-chaos-chess]{--cc-piece-white: #F5F5F5;--cc-piece-black: #1a1a1a;--cc-bg: var(--color-surface-base, #f5f5f5);--cc-surface-glass: rgba(255, 255, 255, .92);--cc-surface-glass-heavy: rgba(255, 255, 255, .95);--cc-text-rgb: 30, 30, 30;--cc-border-subtle: rgba(0, 0, 0, .08);--cc-border-light: rgba(0, 0, 0, .12);--cc-square-light: rgba(0, 0, 0, .08);--cc-square-dark: rgba(0, 0, 0, .22);--cc-btn-bg: rgba(0, 0, 0, .05);--cc-slider-track: rgba(0, 0, 0, .1);--cc-shadow-board: 0 8px 32px rgba(0, 0, 0, .15);--cc-shadow-dialog: 0 8px 40px rgba(0, 0, 0, .2), 0 0 20px rgba(var(--cc-accent-rgb), .08);--cc-shadow-banner: 0 12px 48px rgba(0, 0, 0, .2), 0 0 24px rgba(var(--cc-accent-rgb), .08)}@keyframes cc-bounceIn{0%{transform:scale(.3);opacity:0}50%{transform:scale(1.08)}70%{transform:scale(.95)}to{transform:scale(1);opacity:1}}@keyframes cc-glowPulse{0%,to{box-shadow:0 0 8px #82fff44d}50%{box-shadow:0 0 20px #82fff499}}@keyframes cc-chaosFlash{0%{background-color:#ff505080}to{background-color:transparent}}@keyframes cc-pieceAppear{0%{transform:scale(0);opacity:0}60%{transform:scale(1.15)}to{transform:scale(1);opacity:1}}@keyframes cc-pieceDisappear{0%{transform:scale(1);opacity:1}to{transform:scale(0);opacity:0}}@keyframes cc-thinkingPulse{0%,to{opacity:.4}50%{opacity:1}}@keyframes cc-slideIn{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes cc-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes cc-chaosBarPulse{0%,to{box-shadow:0 0 4px #ff50504d}50%{box-shadow:0 0 16px #ff5050b3}}@keyframes cc-slideOut{0%{transform:translateY(0);opacity:1}to{transform:translateY(-20px);opacity:0}}
1
+ ._square_1tsnw_1{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:100%;cursor:pointer;transition:background-color .15s ease;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}._light_1tsnw_14{background-color:var(--cc-square-light)}._dark_1tsnw_18{background-color:var(--cc-square-dark)}._selected_1tsnw_22{background-color:rgba(var(--cc-accent-rgb),.35)!important}._legalMove_1tsnw_26:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:28%;height:28%;border-radius:50%;background-color:rgba(var(--cc-accent-rgb),.3);pointer-events:none}._legalCapture_1tsnw_39:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:85%;height:85%;border-radius:50%;border:3px solid rgba(var(--cc-accent-rgb),.35);background:transparent;pointer-events:none;box-sizing:border-box}._check_1tsnw_54{background-color:rgba(var(--cc-check-rgb),.5)!important}._lastMoveFrom_1tsnw_58{background-color:rgba(var(--cc-orange-rgb),.2)!important}._lastMoveTo_1tsnw_62{background-color:rgba(var(--cc-orange-rgb),.3)!important}._chaosFlash_1tsnw_66{animation:_cc-chaosFlash_1tsnw_1 .6s ease-out}._piece_1tsnw_70{font-size:calc(min(560px,90vw)*.09375);line-height:1;filter:drop-shadow(0 2px 4px rgba(0,0,0,.5));transition:transform .15s ease;pointer-events:none}._pieceWhite_1tsnw_78{color:var(--cc-piece-white, #F5F5F5);filter:drop-shadow(0 2px 4px rgba(0,0,0,.5))}._pieceBlack_1tsnw_83{color:var(--cc-piece-black, #1a1a1a);filter:drop-shadow(0 1px 3px rgba(255,255,255,.3))}._pieceAppear_1tsnw_88{animation:_cc-pieceAppear_1tsnw_1 .4s ease-out}._pieceDisappear_1tsnw_92{animation:_cc-pieceDisappear_1tsnw_1 .3s ease-in forwards}._board_119uf_1{display:grid;touch-action:manipulation;grid-template-columns:repeat(8,1fr);grid-template-rows:repeat(8,1fr);width:min(560px,90vw);height:min(560px,90vw);border-radius:12px;overflow:hidden;box-shadow:var(--cc-shadow-board);border:1px solid var(--cc-border-subtle)}._rankLabel_119uf_15{position:absolute;top:2px;left:4px;font-size:10px;font-family:var(--cc-font-body);color:rgba(var(--cc-text-rgb),.35);pointer-events:none;-webkit-user-select:none;user-select:none}._fileLabel_119uf_26{position:absolute;bottom:2px;right:4px;font-size:10px;font-family:var(--cc-font-body);color:rgba(var(--cc-text-rgb),.35);pointer-events:none;-webkit-user-select:none;user-select:none}._boardLocked_119uf_37{opacity:.85;pointer-events:none}._promotionOverlay_lr711_2{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#0009;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);z-index:100;animation:_cc-fadeIn_lr711_1 .2s ease-out}._promotionDialog_lr711_14{display:flex;flex-direction:column;align-items:center;gap:16px;padding:24px 32px;background:var(--cc-surface-glass);border:1px solid rgba(var(--cc-accent-rgb),.2);border-radius:20px;box-shadow:var(--cc-shadow-dialog);animation:_cc-bounceIn_lr711_1 .4s ease-out}._promotionTitle_lr711_27{font-family:var(--cc-font-display);font-size:16px;color:var(--cc-text);margin:0}._promotionOptions_lr711_34{display:flex;gap:12px}._promotionBtn_lr711_39{display:flex;align-items:center;justify-content:center;width:64px;height:64px;font-size:40px;background:var(--cc-btn-bg);border:1px solid var(--cc-border-light);border-radius:12px;cursor:pointer;transition:all .15s ease;filter:drop-shadow(0 2px 4px rgba(0,0,0,.5))}._promotionBtn_lr711_39:hover{background:var(--cc-btn-bg-hover);border-color:var(--cc-btn-border-hover);transform:scale(1.08)}._gameOverOverlay_lr711_61{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#000000a6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:100;animation:_cc-fadeIn_lr711_1 .3s ease-out}._gameOverBanner_lr711_73{display:flex;flex-direction:column;align-items:center;gap:20px;padding:32px 48px;background:var(--cc-surface-glass-heavy);border:1px solid rgba(var(--cc-accent-rgb),.2);border-radius:20px;box-shadow:var(--cc-shadow-banner);animation:_cc-bounceIn_lr711_1 .5s ease-out}._gameOverResult_lr711_86{font-family:var(--cc-font-display);font-size:28px;font-weight:700;color:var(--cc-accent);margin:0;text-align:center}._gameOverDetail_lr711_95{font-family:var(--cc-font-body);font-size:14px;color:rgba(var(--cc-text-rgb),.7);margin:0}._restartBtn_lr711_102{padding:10px 32px;font-family:var(--cc-font-display);font-size:15px;font-weight:600;color:var(--cc-bg);background:var(--cc-accent);border:none;border-radius:999px;cursor:pointer;transition:all .15s ease}._restartBtn_lr711_102:hover{transform:scale(1.05);box-shadow:0 0 16px rgba(var(--cc-accent-rgb),.4)}._chaosBar_lr711_121{display:flex;align-items:center;gap:10px;width:100%;padding:0 4px}._chaosBarLabel_lr711_129{font-family:var(--cc-font-body);font-size:10px;font-weight:700;letter-spacing:1.5px;color:rgba(var(--cc-accent-rgb),.7);white-space:nowrap}._chaosBarTrack_lr711_138{flex:1;height:6px;border-radius:3px;background:var(--cc-border-subtle);overflow:hidden}._chaosBarFill_lr711_146{height:100%;border-radius:3px;background:var(--cc-accent);transition:width .3s ease;box-shadow:0 0 calc(4px + 12px * var(--glow, 0)) rgba(var(--cc-accent-rgb),calc(.3 + .5 * var(--glow, 0)))}._difficultySelector_lr711_155{display:flex;flex-direction:column;gap:4px;flex:1}._difficultyLabel_lr711_162{font-family:var(--cc-font-body);font-size:11px;color:rgba(var(--cc-text-rgb),.5)}._difficultySlider_lr711_168{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:2px;background:var(--cc-slider-track);outline:none}._difficultySlider_lr711_168::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border-radius:50%;background:var(--cc-accent);cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._difficultySlider_lr711_168::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._difficultyValue_lr711_199{font-family:var(--cc-font-display);font-size:11px;color:var(--cc-accent)}._sidePickerOverlay_lr711_206{display:flex;align-items:center;justify-content:center;width:100%;min-height:min(560px,90vw)}._sidePickerCard_lr711_214{display:flex;flex-direction:column;align-items:center;gap:28px;padding:40px 48px;background:var(--cc-surface-glass);border:1px solid rgba(var(--cc-accent-rgb),.2);border-radius:20px;box-shadow:var(--cc-shadow-dialog);animation:_cc-bounceIn_lr711_1 .5s ease-out}._sidePickerTitle_lr711_227{font-family:var(--cc-font-display);font-size:22px;font-weight:700;color:var(--cc-text);margin:0}._sidePickerOptions_lr711_235{display:flex;gap:20px}._sidePickerBtn_lr711_240{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 28px;background:var(--cc-btn-bg);border:1px solid var(--cc-border-light);border-radius:16px;cursor:pointer;transition:all .2s ease}._sidePickerBtn_lr711_240:hover{background:rgba(var(--cc-accent-rgb),.12);border-color:var(--cc-btn-border-hover);transform:scale(1.06);box-shadow:0 0 20px rgba(var(--cc-accent-rgb),.25)}._sidePickerIcon_lr711_260{font-size:56px;line-height:1}._sidePickerWhite_lr711_265{color:var(--cc-piece-white);filter:drop-shadow(0 2px 6px rgba(0,0,0,.6))}._sidePickerBlack_lr711_270{color:var(--cc-piece-black);filter:drop-shadow(0 0 4px rgba(var(--cc-text-rgb),.3))}._sidePickerLabel_lr711_275{font-family:var(--cc-font-display);font-size:15px;font-weight:600;color:var(--cc-text)}._sidePickerSettings_lr711_282{display:flex;gap:24px;width:100%;padding-top:8px;border-top:1px solid var(--cc-border-subtle)}._stupidLevel_lr711_291{display:flex;flex-direction:column;gap:4px;min-width:100px}._stupidLevelHeader_lr711_298{display:flex;justify-content:space-between;align-items:center}._stupidLevelLabel_lr711_304{font-family:var(--cc-font-display);font-size:10px;font-weight:700;letter-spacing:1px;color:rgba(var(--cc-text-rgb),.5)}._stupidLevelValue_lr711_312{font-family:var(--cc-font-display);font-size:10px;font-weight:700;color:var(--cc-accent)}._stupidLevelSlider_lr711_319{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:2px;background:var(--cc-slider-track);outline:none}._stupidLevelSlider_lr711_319::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border-radius:50%;background:var(--cc-accent);cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._stupidLevelSlider_lr711_319::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--cc-accent);border:none;cursor:pointer;box-shadow:0 0 8px rgba(var(--cc-accent-rgb),.4)}._muteBtn_lr711_351{display:flex;align-items:center;justify-content:center;width:32px;height:32px;font-size:16px;background:none;border:1px solid rgba(255,255,255,.1);border-radius:8px;cursor:pointer;color:var(--cc-accent);transition:all .15s ease}._muteBtn_lr711_351:focus-visible{outline:2px solid var(--cc-accent);outline-offset:2px}._muteBtn_lr711_351:hover{background:rgba(var(--cc-accent-rgb),.1);border-color:rgba(var(--cc-accent-rgb),.25)}._muteBtnMuted_lr711_376{color:rgba(var(--cc-text-rgb),.3)}._muteBtnMuted_lr711_376:hover{background:var(--cc-btn-bg);border-color:#ffffff26}._chaosToast_lr711_386{position:absolute;top:24px;left:50%;transform:translate(-50%);padding:10px 24px;font-family:var(--cc-font-body);font-size:14px;font-weight:600;color:var(--cc-orange);background:var(--cc-surface-glass);border:1px solid rgba(var(--cc-orange-rgb),.3);border-radius:12px;box-shadow:0 4px 24px #0006,0 0 12px rgba(var(--cc-orange-rgb),.15);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:200;white-space:nowrap;animation:_cc-slideIn_lr711_1 .3s ease-out}._chaosToastFading_lr711_406{animation:_cc-slideOut_lr711_1 .4s ease-in forwards}._container_1lkfq_1{display:flex;flex-direction:column;align-items:center;gap:12px;width:min(560px,90vw);margin:0 auto;font-family:var(--cc-font-body)}._topBar_1lkfq_11{display:flex;align-items:center;justify-content:space-between;width:100%;padding:8px 4px;position:relative;z-index:101}._topBarLeft_1lkfq_23,._topBarRight_1lkfq_29{display:flex;align-items:center;gap:8px}._newGameBtn_1lkfq_35{height:32px;padding:0 12px;font-family:var(--cc-font-display);font-size:13px;color:var(--cc-text);background:none;border:1px solid rgba(var(--cc-text-rgb),.15);border-radius:8px;cursor:pointer;touch-action:manipulation;transition:all .15s ease}._newGameBtn_1lkfq_35:hover{background:rgba(var(--cc-accent-rgb),.1);border-color:rgba(var(--cc-accent-rgb),.25)}._newGameBtn_1lkfq_35:focus-visible{outline:2px solid var(--cc-accent);outline-offset:2px}._aiUnavailable_1lkfq_59{font-family:var(--cc-font-display);font-size:13px;color:var(--cc-orange)}._statusText_1lkfq_65{font-family:var(--cc-font-display);font-size:14px;color:var(--cc-text)}._thinking_1lkfq_71{display:flex;align-items:center;gap:6px;font-family:var(--cc-font-display);font-size:13px;color:var(--cc-accent);animation:_cc-thinkingPulse_1lkfq_1 1.2s ease-in-out infinite}._bottomBar_1lkfq_81{display:flex;align-items:center;justify-content:space-between;width:100%;padding:8px 4px;gap:16px}[data-chaos-chess]{--cc-accent: var(--color-accent-primary, #82FFF4);--cc-accent-rgb: var(--color-accent-primary-rgb, 130, 255, 244);--cc-bg: var(--color-surface-base, #242222);--cc-surface-glass: rgba(36, 34, 34, .92);--cc-surface-glass-heavy: rgba(36, 34, 34, .95);--cc-text: var(--color-text-primary, #F5F5F5);--cc-text-rgb: 245, 245, 245;--cc-orange: var(--color-accent-orange-soft, #FFB67A);--cc-orange-rgb: 255, 182, 122;--cc-red-rgb: 255, 80, 80;--cc-check-rgb: 255, 50, 50;--cc-border-subtle: rgba(255, 255, 255, .08);--cc-border-light: rgba(255, 255, 255, .12);--cc-square-light: rgba(255, 255, 255, .12);--cc-square-dark: rgba(0, 0, 0, .25);--cc-font-body: var(--font-sans, "Inter", sans-serif);--cc-font-display: var(--font-display, "Comfortaa", cursive);--cc-btn-bg: rgba(255, 255, 255, .06);--cc-btn-bg-hover: rgba(var(--cc-accent-rgb), .15);--cc-btn-border-hover: rgba(var(--cc-accent-rgb), .3);--cc-slider-track: rgba(255, 255, 255, .1);--cc-shadow-board: 0 8px 32px rgba(0, 0, 0, .4);--cc-shadow-dialog: 0 8px 40px rgba(0, 0, 0, .5), 0 0 20px rgba(var(--cc-accent-rgb), .1);--cc-shadow-banner: 0 12px 48px rgba(0, 0, 0, .5), 0 0 24px rgba(var(--cc-accent-rgb), .1);--cc-piece-white: #F5F5F5;--cc-piece-black: #1a1a1a;position:relative}html.light-mode [data-chaos-chess]{--cc-piece-white: #F5F5F5;--cc-piece-black: #1a1a1a;--cc-bg: var(--color-surface-base, #f5f5f5);--cc-surface-glass: rgba(255, 255, 255, .92);--cc-surface-glass-heavy: rgba(255, 255, 255, .95);--cc-text-rgb: 30, 30, 30;--cc-border-subtle: rgba(0, 0, 0, .08);--cc-border-light: rgba(0, 0, 0, .12);--cc-square-light: rgba(0, 0, 0, .08);--cc-square-dark: rgba(0, 0, 0, .22);--cc-btn-bg: rgba(0, 0, 0, .05);--cc-slider-track: rgba(0, 0, 0, .1);--cc-shadow-board: 0 8px 32px rgba(0, 0, 0, .15);--cc-shadow-dialog: 0 8px 40px rgba(0, 0, 0, .2), 0 0 20px rgba(var(--cc-accent-rgb), .08);--cc-shadow-banner: 0 12px 48px rgba(0, 0, 0, .2), 0 0 24px rgba(var(--cc-accent-rgb), .08)}@keyframes cc-bounceIn{0%{transform:scale(.3);opacity:0}50%{transform:scale(1.08)}70%{transform:scale(.95)}to{transform:scale(1);opacity:1}}@keyframes cc-glowPulse{0%,to{box-shadow:0 0 8px #82fff44d}50%{box-shadow:0 0 20px #82fff499}}@keyframes cc-chaosFlash{0%{background-color:#ff505080}to{background-color:transparent}}@keyframes cc-pieceAppear{0%{transform:scale(0);opacity:0}60%{transform:scale(1.15)}to{transform:scale(1);opacity:1}}@keyframes cc-pieceDisappear{0%{transform:scale(1);opacity:1}to{transform:scale(0);opacity:0}}@keyframes cc-thinkingPulse{0%,to{opacity:.4}50%{opacity:1}}@keyframes cc-slideIn{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes cc-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes cc-chaosBarPulse{0%,to{box-shadow:0 0 4px #ff50504d}50%{box-shadow:0 0 16px #ff5050b3}}@keyframes cc-slideOut{0%{transform:translateY(0);opacity:1}to{transform:translateY(-20px);opacity:0}}