chesspal 0.1.0 → 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.
Files changed (209) hide show
  1. package/README.md +45 -82
  2. package/dist/cli/chat-hook.js +1 -1
  3. package/dist/cli/command-line.d.ts +1 -2
  4. package/dist/cli/command-line.js +2 -3
  5. package/dist/commands/agents.d.ts +26 -0
  6. package/dist/commands/agents.js +72 -0
  7. package/dist/commands/ai-move.d.ts +5 -14
  8. package/dist/commands/ai-move.js +28 -35
  9. package/dist/commands/ai-say.d.ts +3 -1
  10. package/dist/commands/ai-say.js +24 -6
  11. package/dist/commands/analyse-game.d.ts +4 -0
  12. package/dist/commands/analyse-game.js +43 -16
  13. package/dist/commands/annotate-game.d.ts +4 -0
  14. package/dist/commands/annotate-game.js +65 -12
  15. package/dist/commands/answer-lines.d.ts +28 -0
  16. package/dist/commands/answer-lines.js +144 -0
  17. package/dist/commands/coach.d.ts +45 -0
  18. package/dist/commands/coach.js +344 -0
  19. package/dist/commands/context.d.ts +16 -5
  20. package/dist/commands/context.js +1 -0
  21. package/dist/commands/delete-game.d.ts +7 -0
  22. package/dist/commands/delete-game.js +30 -0
  23. package/dist/commands/delete-review.d.ts +8 -0
  24. package/dist/commands/delete-review.js +34 -0
  25. package/dist/commands/drawings.d.ts +0 -2
  26. package/dist/commands/drawings.js +5 -3
  27. package/dist/commands/end-game.js +5 -2
  28. package/dist/commands/export-game.d.ts +1 -1
  29. package/dist/commands/export-game.js +4 -3
  30. package/dist/commands/game-summary.d.ts +21 -38
  31. package/dist/commands/game-summary.js +30 -167
  32. package/dist/commands/index.d.ts +15 -0
  33. package/dist/commands/index.js +47 -2
  34. package/dist/commands/init.d.ts +3 -3
  35. package/dist/commands/init.js +4 -4
  36. package/dist/commands/lead-input.d.ts +8 -0
  37. package/dist/commands/lead-input.js +21 -0
  38. package/dist/commands/look.js +4 -1
  39. package/dist/commands/new-game.d.ts +2 -3
  40. package/dist/commands/new-game.js +7 -4
  41. package/dist/commands/play-move.d.ts +8 -15
  42. package/dist/commands/play-move.js +5 -13
  43. package/dist/commands/player-move.d.ts +2 -6
  44. package/dist/commands/player-move.js +13 -6
  45. package/dist/commands/player-say.d.ts +1 -1
  46. package/dist/commands/player-say.js +1 -1
  47. package/dist/commands/ponder.d.ts +10 -0
  48. package/dist/commands/ponder.js +33 -21
  49. package/dist/commands/position.d.ts +1 -1
  50. package/dist/commands/position.js +3 -1
  51. package/dist/commands/profiles.d.ts +13 -4
  52. package/dist/commands/profiles.js +49 -15
  53. package/dist/commands/registry.d.ts +8 -3
  54. package/dist/commands/registry.js +12 -11
  55. package/dist/commands/say.d.ts +1 -1
  56. package/dist/commands/say.js +16 -16
  57. package/dist/commands/speech.d.ts +8 -0
  58. package/dist/commands/speech.js +20 -0
  59. package/dist/commands/status.d.ts +9 -3
  60. package/dist/commands/status.js +40 -15
  61. package/dist/commands/study-games.js +1 -1
  62. package/dist/commands/study.js +3 -19
  63. package/dist/core/facts.js +15 -15
  64. package/dist/core/game.d.ts +3 -1
  65. package/dist/core/game.js +8 -4
  66. package/dist/core/illegal.js +1 -1
  67. package/dist/core/index.d.ts +5 -4
  68. package/dist/core/index.js +5 -4
  69. package/dist/core/lead.d.ts +15 -0
  70. package/dist/core/lead.js +40 -0
  71. package/dist/core/levels.d.ts +1 -1
  72. package/dist/core/levels.js +1 -1
  73. package/dist/core/moods.d.ts +0 -2
  74. package/dist/core/moods.js +2 -2
  75. package/dist/core/openings.d.ts +0 -2
  76. package/dist/core/openings.js +1 -1
  77. package/dist/core/profile.js +1 -1
  78. package/dist/core/record.d.ts +1 -1
  79. package/dist/core/record.js +1 -1
  80. package/dist/core/review.d.ts +9 -3
  81. package/dist/core/review.js +29 -9
  82. package/dist/games/analysis.d.ts +1 -1
  83. package/dist/games/archive.d.ts +24 -3
  84. package/dist/games/archive.js +96 -22
  85. package/dist/games/coach.d.ts +57 -0
  86. package/dist/games/coach.js +144 -0
  87. package/dist/games/current-game.d.ts +2 -0
  88. package/dist/games/current-game.js +7 -1
  89. package/dist/games/files.js +1 -0
  90. package/dist/games/index.d.ts +4 -3
  91. package/dist/games/index.js +4 -3
  92. package/dist/games/talk.d.ts +1 -5
  93. package/dist/games/talk.js +14 -14
  94. package/dist/home/open-folder.js +1 -1
  95. package/dist/host-files/{ponder-agents.d.ts → agents.d.ts} +10 -2
  96. package/dist/host-files/agents.js +53 -0
  97. package/dist/host-files/host-files.d.ts +7 -2
  98. package/dist/host-files/host-files.js +27 -12
  99. package/dist/host-files/index.d.ts +2 -2
  100. package/dist/host-files/index.js +3 -3
  101. package/dist/index.d.ts +1 -3
  102. package/dist/index.js +1 -0
  103. package/dist/page/app/anchor.js +88 -0
  104. package/dist/page/{app.js → app/app.js} +112 -230
  105. package/dist/page/app/keys.js +94 -0
  106. package/dist/page/app/phase.js +30 -0
  107. package/dist/page/app/served.js +73 -0
  108. package/dist/page/avatars/avatars.js +19 -0
  109. package/dist/page/avatars/thought.js +10 -0
  110. package/dist/page/base.css +160 -0
  111. package/dist/page/board/board.css +959 -0
  112. package/dist/page/board/board.js +125 -0
  113. package/dist/page/{explain.js → board/explain.js} +1 -1
  114. package/dist/page/board/marks.js +160 -0
  115. package/dist/page/board/motion.js +71 -0
  116. package/dist/page/board/pointer.js +239 -0
  117. package/dist/page/board/squares.js +26 -0
  118. package/dist/page/dialogs/analyses.js +195 -0
  119. package/dist/page/{dialog.js → dialogs/dialog.js} +1 -1
  120. package/dist/page/dialogs/dialogs.css +1228 -0
  121. package/dist/page/{new-game-dialog.js → dialogs/new-game.js} +3 -3
  122. package/dist/page/{profile-dialogs.js → dialogs/profiles.js} +40 -11
  123. package/dist/page/dialogs/search.js +31 -0
  124. package/dist/page/dialogs/settings.js +42 -0
  125. package/dist/page/dialogs/studied.js +39 -0
  126. package/dist/page/dialogs/study.js +51 -0
  127. package/dist/page/{badges.js → game/badges.js} +1 -1
  128. package/dist/page/{browse.js → game/browse.js} +1 -1
  129. package/dist/page/game/card-fold.js +40 -0
  130. package/dist/page/game/column.js +51 -0
  131. package/dist/page/{ending.js → game/ending.js} +2 -2
  132. package/dist/page/game/game.css +577 -0
  133. package/dist/page/{move-list.js → game/move-list.js} +10 -6
  134. package/dist/page/{plies.js → game/plies.js} +30 -10
  135. package/dist/page/game/result-tile.js +14 -0
  136. package/dist/page/helps/helps.css +689 -0
  137. package/dist/page/helps/helps.js +220 -0
  138. package/dist/page/helps/view.js +127 -0
  139. package/dist/page/layout/fold-tab.js +11 -0
  140. package/dist/page/{folds.js → layout/folds.js} +1 -1
  141. package/dist/page/{header.js → layout/header.js} +5 -4
  142. package/dist/page/layout/layout.css +834 -0
  143. package/dist/page/lead/lead.js +82 -0
  144. package/dist/page/lead/view.js +38 -0
  145. package/dist/page/main.js +2 -2
  146. package/dist/page/pieces/CREDITS.md +12 -29
  147. package/dist/page/pieces/capablanca-small.svg +20 -0
  148. package/dist/page/pieces/capablanca.svg +22 -0
  149. package/dist/page/pieces/nitida-small.svg +3 -2
  150. package/dist/page/pieces/nitida.svg +3 -2
  151. package/dist/page/{pieces.js → pieces/pieces.js} +2 -2
  152. package/dist/page/pieces/torretta-small.svg +15 -14
  153. package/dist/page/pieces/torretta.svg +17 -15
  154. package/dist/page/{player-card.js → players/card.js} +2 -6
  155. package/dist/page/{clock-time.js → players/clock-time.js} +2 -2
  156. package/dist/page/{profile.js → profile/profile.js} +9 -5
  157. package/dist/page/{settings.js → profile/settings.js} +5 -4
  158. package/dist/page/style.css +9 -4398
  159. package/dist/page/talk/talk.css +958 -0
  160. package/dist/page/{talk.js → talk/talk.js} +39 -46
  161. package/dist/page/text.js +137 -19
  162. package/dist/page/theme.css +292 -0
  163. package/dist/profiles/index.d.ts +1 -1
  164. package/dist/profiles/profiles.d.ts +15 -4
  165. package/dist/profiles/profiles.js +24 -7
  166. package/dist/server/bell.d.ts +10 -2
  167. package/dist/server/bell.js +28 -12
  168. package/dist/server/caller.d.ts +14 -3
  169. package/dist/server/caller.js +44 -11
  170. package/dist/server/mcp.d.ts +1 -2
  171. package/dist/server/mcp.js +42 -14
  172. package/dist/server/page/analyses.d.ts +23 -0
  173. package/dist/server/page/analyses.js +65 -0
  174. package/dist/server/page/files.d.ts +5 -0
  175. package/dist/server/page/files.js +92 -0
  176. package/dist/server/page/game.d.ts +6 -0
  177. package/dist/server/page/game.js +381 -0
  178. package/dist/server/{http.d.ts → page/http.d.ts} +13 -0
  179. package/dist/server/{http.js → page/http.js} +11 -0
  180. package/dist/server/{page.d.ts → page/page.d.ts} +8 -13
  181. package/dist/server/page/page.js +229 -0
  182. package/dist/server/{profile-routes.d.ts → page/profiles.d.ts} +2 -2
  183. package/dist/server/{profile-routes.js → page/profiles.js} +47 -18
  184. package/instructions/analysis.md +4 -0
  185. package/instructions/analyst-agent.md +8 -0
  186. package/instructions/analyst.md +3 -7
  187. package/instructions/coach.md +11 -0
  188. package/instructions/opponent.md +4 -4
  189. package/package.json +1 -1
  190. package/dist/host-files/ponder-agents.js +0 -40
  191. package/dist/page/avatars.js +0 -16
  192. package/dist/page/board.js +0 -566
  193. package/dist/page/fold-tab.js +0 -9
  194. package/dist/page/game-column.js +0 -44
  195. package/dist/page/helps-view.js +0 -51
  196. package/dist/page/helps.js +0 -90
  197. package/dist/page/pieces/cburnett-small.svg +0 -20
  198. package/dist/page/pieces/cburnett.svg +0 -20
  199. package/dist/page/settings-panel.js +0 -32
  200. package/dist/page/studied.js +0 -14
  201. package/dist/page/study-dialog.js +0 -58
  202. package/dist/server/analyses.d.ts +0 -17
  203. package/dist/server/analyses.js +0 -46
  204. package/dist/server/page.js +0 -657
  205. /package/dist/page/{torretta.js → avatars/torretta.js} +0 -0
  206. /package/dist/page/{opening-book.js → game/opening-book.js} +0 -0
  207. /package/dist/page/{model-name.js → players/model-name.js} +0 -0
  208. /package/dist/page/{sounds.js → sounds/sounds.js} +0 -0
  209. /package/dist/page/{voice.js → talk/voice.js} +0 -0
@@ -0,0 +1,1228 @@
1
+ /* The dialogs: the settings, the profiles and the wizard of the first one, the new game, the study of a game and the analyses */
2
+
3
+ /* A dialog over the page, the settings' (D-56) and the others alike */
4
+ .dialog {
5
+ width: min(740px, calc(100vw - 32px));
6
+ max-height: calc(100vh - 48px);
7
+ padding: 0 20px 20px;
8
+ border: 1px solid var(--line);
9
+ border-radius: var(--radius);
10
+ background: var(--card);
11
+ color: var(--ink);
12
+ box-shadow: var(--shadow);
13
+ }
14
+
15
+ .dialog::backdrop {
16
+ background: rgba(16, 22, 29, 0.4);
17
+ }
18
+
19
+ /* Its title, with the way back before it when there is one and the close button at the end */
20
+ .dialog header {
21
+ position: sticky;
22
+ top: 0;
23
+ z-index: 1;
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 4px;
27
+ padding: 16px 0 8px;
28
+ background: var(--card);
29
+ }
30
+
31
+ .dialog h2 {
32
+ flex: 1;
33
+ min-width: 0;
34
+ margin: 0;
35
+ font-size: 17px;
36
+ font-weight: 600;
37
+ }
38
+
39
+ .dialog .note {
40
+ margin: 0 0 12px;
41
+ }
42
+
43
+ /* The settings (D-56), each choice shown at once, in cards of two columns, one under 600px (Stefano): the look on the left; the play and the language
44
+ on the right */
45
+ .setting-columns {
46
+ display: grid;
47
+ grid-template-columns: 1fr 1fr;
48
+ gap: 14px;
49
+ align-items: start;
50
+ }
51
+
52
+ .setting-column {
53
+ display: grid;
54
+ gap: 14px;
55
+ }
56
+
57
+ /* A section: a card with its icon and a title stronger than the labels under it */
58
+ .setting-card {
59
+ min-width: 0;
60
+ padding: 14px;
61
+ border: 1px solid var(--line);
62
+ border-radius: 8px;
63
+ background: var(--page);
64
+ }
65
+
66
+ .setting-card h3 {
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 8px;
70
+ margin: 0 0 12px;
71
+ font-size: 15px;
72
+ font-weight: 650;
73
+ }
74
+
75
+ .setting-card h3 .icon {
76
+ width: 18px;
77
+ height: 18px;
78
+ stroke-width: 2;
79
+ color: var(--accent);
80
+ }
81
+
82
+ .setting-group {
83
+ margin: 0 0 14px;
84
+ }
85
+
86
+ .setting-group:last-child {
87
+ margin-bottom: 0;
88
+ }
89
+
90
+ /* A choice's label, and beside it the name of a skin, whose tiles have none */
91
+ .setting-label {
92
+ display: flex;
93
+ gap: 6px;
94
+ align-items: baseline;
95
+ margin: 0 0 6px;
96
+ font-size: 13px;
97
+ color: var(--soft);
98
+ }
99
+
100
+ .setting-label b {
101
+ color: var(--ink);
102
+ font-weight: 600;
103
+ }
104
+
105
+ /* The pieces' colours and the arrows' side by side, one under the other where four dots would not fit */
106
+ .setting-pair {
107
+ display: grid;
108
+ grid-template-columns: repeat(auto-fit, minmax(122px, 1fr));
109
+ gap: 14px;
110
+ }
111
+
112
+ /* Three words in a segmented bar: the theme, the language */
113
+ .segments {
114
+ display: flex;
115
+ padding: 2px;
116
+ border: 1px solid var(--line);
117
+ border-radius: 8px;
118
+ background: var(--card);
119
+ }
120
+
121
+ .segments button {
122
+ flex: 1;
123
+ padding: 5px 6px;
124
+ border: 0;
125
+ border-radius: 6px;
126
+ background: none;
127
+ color: var(--soft);
128
+ font-size: 13px;
129
+ white-space: nowrap;
130
+ }
131
+
132
+ .segments button:hover {
133
+ color: var(--ink);
134
+ }
135
+
136
+ .segments button[aria-checked="true"] {
137
+ background: var(--card);
138
+ color: var(--ink);
139
+ font-weight: 600;
140
+ box-shadow: 0 0 0 1px var(--line), 0 1px 2px rgba(0, 0, 0, 0.12);
141
+ }
142
+
143
+ /* The colours as dots, the skins as tiles of four squares, the last one gold as the last move; their names in their titles */
144
+ .swatches {
145
+ display: flex;
146
+ flex-wrap: wrap;
147
+ gap: 8px;
148
+ }
149
+
150
+ .swatches.skins {
151
+ display: grid;
152
+ grid-template-columns: repeat(9, minmax(0, 36px));
153
+ gap: 7px;
154
+ }
155
+
156
+ .swatch {
157
+ width: 26px;
158
+ height: 26px;
159
+ padding: 0;
160
+ border: 0;
161
+ border-radius: 50%;
162
+ box-shadow: 0 0 0 1px var(--line);
163
+ }
164
+
165
+ .swatch[data-board] {
166
+ display: grid;
167
+ grid-template: 1fr 1fr / 1fr 1fr;
168
+ width: auto;
169
+ height: auto;
170
+ aspect-ratio: 1;
171
+ border-radius: 6px;
172
+ overflow: hidden;
173
+ }
174
+
175
+ .swatch[data-board] i:first-child {
176
+ background: var(--light-square);
177
+ }
178
+
179
+ .swatch[data-board] i:nth-child(2),
180
+ .swatch[data-board] i:nth-child(3) {
181
+ background: var(--dark-square);
182
+ }
183
+
184
+ .swatch[data-board] i:nth-child(4) {
185
+ background: var(--light-square) linear-gradient(var(--last-move), var(--last-move));
186
+ }
187
+
188
+ .swatch[data-pieces] {
189
+ background: linear-gradient(90deg, var(--white-piece) 50%, var(--black-piece) 50%);
190
+ }
191
+
192
+ .swatch[data-marks] {
193
+ background: var(--mark);
194
+ }
195
+
196
+ /* The piece sets: a white and a black knight over the set's name */
197
+ .piece-sets {
198
+ display: grid;
199
+ grid-template-columns: repeat(3, 1fr);
200
+ gap: 8px;
201
+ }
202
+
203
+ .piece-sets button {
204
+ display: flex;
205
+ flex-direction: column;
206
+ align-items: center;
207
+ gap: 2px;
208
+ padding: 6px 4px 5px;
209
+ border: 0;
210
+ border-radius: 8px;
211
+ background: var(--card);
212
+ color: var(--ink);
213
+ font-size: 13px;
214
+ box-shadow: 0 0 0 1px var(--line);
215
+ }
216
+
217
+ .sample {
218
+ display: inline-flex;
219
+ }
220
+
221
+ .sample .piece {
222
+ width: 26px;
223
+ height: 26px;
224
+ }
225
+
226
+ .swatch:hover,
227
+ .piece-sets button:hover {
228
+ box-shadow: 0 0 0 1px var(--soft);
229
+ }
230
+
231
+ .swatch[aria-checked="true"],
232
+ .piece-sets button[aria-checked="true"] {
233
+ box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--accent);
234
+ }
235
+
236
+ /* The keyboard's focus in ink, outside the chosen ring, so the two never read the same */
237
+ .swatch:focus-visible,
238
+ .piece-sets button:focus-visible {
239
+ outline-color: var(--ink);
240
+ outline-offset: 4px;
241
+ }
242
+
243
+ /* The switches, one per line, the label on the left */
244
+ .switch {
245
+ display: flex;
246
+ align-items: center;
247
+ justify-content: space-between;
248
+ gap: 12px;
249
+ padding: 7px 0;
250
+ border-top: 1px solid var(--line);
251
+ font-size: 14px;
252
+ cursor: pointer;
253
+ }
254
+
255
+ h3 + .switch {
256
+ padding-top: 0;
257
+ border-top: 0;
258
+ }
259
+
260
+ .switch input {
261
+ appearance: none;
262
+ flex: none;
263
+ position: relative;
264
+ width: 34px;
265
+ height: 20px;
266
+ margin: 0;
267
+ border-radius: 10px;
268
+ background: color-mix(in oklab, var(--soft) 45%, var(--card));
269
+ cursor: pointer;
270
+ transition: background 120ms;
271
+ }
272
+
273
+ .switch input::after {
274
+ content: "";
275
+ position: absolute;
276
+ top: 2px;
277
+ left: 2px;
278
+ width: 16px;
279
+ height: 16px;
280
+ border-radius: 50%;
281
+ background: #fff;
282
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
283
+ transition: translate 120ms;
284
+ }
285
+
286
+ .switch input:checked {
287
+ background: var(--accent);
288
+ }
289
+
290
+ .switch input:checked::after {
291
+ translate: 14px 0;
292
+ }
293
+
294
+ @media (prefers-reduced-motion: reduce) {
295
+ .switch input,
296
+ .switch input::after {
297
+ transition: none;
298
+ }
299
+ }
300
+
301
+ /* On a phone the cards go one under the other, and the skins in two rows of tiles big enough for a finger */
302
+ @media (max-width: 600px) {
303
+ .setting-columns {
304
+ grid-template-columns: 1fr;
305
+ }
306
+
307
+ .swatches {
308
+ gap: 6px;
309
+ }
310
+
311
+ .swatches.skins {
312
+ grid-template-columns: repeat(5, minmax(0, 40px));
313
+ gap: 10px;
314
+ }
315
+ }
316
+
317
+ /* On the narrowest phones a segment's words may go on two lines */
318
+ @media (max-width: 360px) {
319
+ .segments button {
320
+ white-space: normal;
321
+ }
322
+ }
323
+
324
+ /* A choice among a few words, in the profiles' list */
325
+ .choice {
326
+ display: inline-flex;
327
+ align-items: center;
328
+ gap: 8px;
329
+ padding: 6px 10px;
330
+ border: 1px solid var(--line);
331
+ border-radius: 8px;
332
+ background: none;
333
+ font-size: 14px;
334
+ }
335
+
336
+ .choice:hover {
337
+ border-color: var(--soft);
338
+ }
339
+
340
+ .choice[aria-checked="true"] {
341
+ border-color: var(--accent);
342
+ box-shadow: inset 0 0 0 1px var(--accent);
343
+ }
344
+
345
+ .wizard {
346
+ max-width: 480px;
347
+ margin: 32px auto;
348
+ padding: 28px;
349
+ border: 1px solid var(--line);
350
+ border-radius: var(--radius);
351
+ background: var(--card);
352
+ box-shadow: var(--shadow);
353
+ }
354
+
355
+ .wizard h1 {
356
+ margin: 12px 0 4px;
357
+ font-size: 24px;
358
+ }
359
+
360
+ .wizard .lead {
361
+ margin: 0 0 24px;
362
+ color: var(--soft);
363
+ }
364
+
365
+ .wizard .lead span {
366
+ display: block;
367
+ margin-top: 4px;
368
+ }
369
+
370
+ @media (max-width: 520px) {
371
+ .wizard {
372
+ margin: 0;
373
+ padding: 20px 16px;
374
+ border: 0;
375
+ border-radius: 0;
376
+ box-shadow: none;
377
+ }
378
+ }
379
+
380
+ .profile-form fieldset {
381
+ min-width: 0;
382
+ margin: 0 0 20px;
383
+ padding: 0;
384
+ border: 0;
385
+ }
386
+
387
+ .profile-form legend,
388
+ .profile-form .field > span {
389
+ display: block;
390
+ margin-bottom: 8px;
391
+ padding: 0;
392
+ font-size: 15px;
393
+ font-weight: 600;
394
+ }
395
+
396
+ .profile-form legend small {
397
+ font-weight: 400;
398
+ color: var(--soft);
399
+ }
400
+
401
+ .profile-form .field {
402
+ display: block;
403
+ margin-bottom: 20px;
404
+ }
405
+
406
+ .profile-form input[type="text"],
407
+ .profile-form input[type="number"],
408
+ .profile-form select {
409
+ width: 100%;
410
+ padding: 10px 12px;
411
+ border: 1px solid var(--line);
412
+ border-radius: 8px;
413
+ background: var(--page);
414
+ color: var(--ink);
415
+ font: inherit;
416
+ font-size: 16px;
417
+ }
418
+
419
+ /* The account's name suggested in the wizard: Chrome's arrow, quieter than the selects' chevron, is the only sign of it */
420
+ .profile-form input::-webkit-calendar-picker-indicator {
421
+ opacity: 0.45;
422
+ }
423
+
424
+ .study textarea {
425
+ width: 100%;
426
+ padding: 10px 12px;
427
+ border: 1px solid var(--line);
428
+ border-radius: 8px;
429
+ background: var(--page);
430
+ color: var(--ink);
431
+ font: 13px/1.4 ui-monospace, monospace;
432
+ resize: vertical;
433
+ }
434
+
435
+ .study .file input {
436
+ font: inherit;
437
+ font-size: 14px;
438
+ color: var(--soft);
439
+ }
440
+
441
+ /* The file button as our secondary buttons, in both themes */
442
+ .study .file input::file-selector-button {
443
+ margin-right: 10px;
444
+ padding: 6px 12px;
445
+ border: 1px solid var(--line);
446
+ border-radius: 8px;
447
+ background: var(--card);
448
+ color: var(--ink);
449
+ font: inherit;
450
+ cursor: pointer;
451
+ }
452
+
453
+ .study .note {
454
+ margin: 0 0 16px;
455
+ }
456
+
457
+ /* The analyses (D-92): the row that loads a game, dashed, then a row for each game, its result on a tile, who played, when, the opening and how long, who
458
+ reviewed it, and the score with how it went for the player; the menu of each row, and the question a row asks in its place (Zoe) */
459
+ /* The analyses' dialog scrolls with the wheel or a finger, without a scrollbar (Stefano) */
460
+ .dialog:has(> .analyses) {
461
+ scrollbar-width: none;
462
+ }
463
+
464
+ .dialog:has(> .analyses)::-webkit-scrollbar {
465
+ display: none;
466
+ }
467
+
468
+ /* The search over the analyses, a magnifier in the field */
469
+ .analyses .search {
470
+ display: flex;
471
+ align-items: center;
472
+ gap: 8px;
473
+ margin: 0 0 10px;
474
+ padding: 0 12px;
475
+ border: 1px solid var(--line);
476
+ border-radius: 10px;
477
+ background: var(--page);
478
+ color: var(--soft);
479
+ }
480
+
481
+ .analyses .search:focus-within {
482
+ border-color: var(--accent);
483
+ }
484
+
485
+ .analyses .search input {
486
+ flex: 1;
487
+ min-width: 0;
488
+ padding: 10px 0;
489
+ border: 0;
490
+ outline: 0;
491
+ background: none;
492
+ color: var(--ink);
493
+ font: inherit;
494
+ font-size: 14px;
495
+ }
496
+
497
+ .analyses > .none {
498
+ margin: 12px 0;
499
+ color: var(--soft);
500
+ font-size: 14px;
501
+ text-align: center;
502
+ }
503
+
504
+ .load-row {
505
+ display: flex;
506
+ align-items: center;
507
+ gap: 12px;
508
+ width: 100%;
509
+ margin: 0 0 10px;
510
+ padding: 10px 12px;
511
+ border: 1px dashed var(--line);
512
+ border-radius: 10px;
513
+ background: none;
514
+ color: var(--ink);
515
+ font: inherit;
516
+ font-size: 14px;
517
+ text-align: left;
518
+ cursor: pointer;
519
+ }
520
+
521
+ .load-row:hover {
522
+ border-color: var(--accent);
523
+ }
524
+
525
+ .load-row .plus {
526
+ display: grid;
527
+ flex: none;
528
+ place-items: center;
529
+ width: 44px;
530
+ height: 44px;
531
+ border-radius: 8px;
532
+ background: var(--page);
533
+ color: var(--accent);
534
+ }
535
+
536
+ .load-row small,
537
+ .row-menu small,
538
+ .ask small {
539
+ display: block;
540
+ color: var(--soft);
541
+ font-size: 12px;
542
+ font-weight: 400;
543
+ }
544
+
545
+ .analyses .games {
546
+ display: grid;
547
+ gap: 6px;
548
+ margin: 0;
549
+ padding: 0;
550
+ list-style: none;
551
+ }
552
+
553
+ .analyses .game {
554
+ position: relative;
555
+ display: flex;
556
+ align-items: stretch;
557
+ border: 1px solid var(--line);
558
+ border-radius: 10px;
559
+ background: var(--card);
560
+ }
561
+
562
+ .analyses .game:hover,
563
+ .analyses .game:has(.row-actions .on) {
564
+ border-color: var(--accent);
565
+ }
566
+
567
+ /* As tall with the reviewed line as without it, so that the rows keep one height */
568
+ .analyses .reopen {
569
+ display: flex;
570
+ flex: 1;
571
+ align-items: center;
572
+ gap: 12px;
573
+ min-width: 0;
574
+ min-height: 65px;
575
+ padding: 8px 4px 8px 8px;
576
+ border: 0;
577
+ background: none;
578
+ color: var(--ink);
579
+ font: inherit;
580
+ text-align: left;
581
+ cursor: pointer;
582
+ }
583
+
584
+ .analyses .tile {
585
+ width: 44px;
586
+ height: 44px;
587
+ border-radius: 8px;
588
+ }
589
+
590
+ .analyses .tile.over .piece {
591
+ width: 27px;
592
+ height: 27px;
593
+ }
594
+
595
+ .analyses .tile.win .up {
596
+ right: 4px;
597
+ bottom: 3px;
598
+ width: 26px;
599
+ height: 26px;
600
+ }
601
+
602
+ .analyses .tile.win .down {
603
+ left: 3px;
604
+ bottom: -1px;
605
+ width: 22px;
606
+ height: 22px;
607
+ }
608
+
609
+ .analyses .tile.draw .piece + .piece {
610
+ margin-left: -11px;
611
+ }
612
+
613
+ /* A game without a result: its star on a coin of the card's colour, readable where the four squares meet */
614
+ .analyses .tile.open {
615
+ background: radial-gradient(circle, var(--card) 0 11px, transparent 11.5px), conic-gradient(var(--dark-square) 0 25%, var(--light-square) 0 50%, var(--dark-square) 0 75%, var(--light-square) 0);
616
+ color: var(--soft);
617
+ font-size: 18px;
618
+ font-weight: 700;
619
+ line-height: 1;
620
+ }
621
+
622
+ .analyses .what {
623
+ display: grid;
624
+ flex: 1;
625
+ gap: 1px;
626
+ min-width: 0;
627
+ line-height: 1.3;
628
+ }
629
+
630
+ .analyses .who,
631
+ .analyses .meta {
632
+ overflow: hidden;
633
+ white-space: nowrap;
634
+ text-overflow: ellipsis;
635
+ }
636
+
637
+ .analyses .who {
638
+ font-size: 14px;
639
+ }
640
+
641
+ .analyses .meta,
642
+ .analyses .state {
643
+ color: var(--soft);
644
+ font-size: 12px;
645
+ }
646
+
647
+ .analyses .state {
648
+ overflow: hidden;
649
+ white-space: nowrap;
650
+ text-overflow: ellipsis;
651
+ }
652
+
653
+ /* A game reviewed: the AI's speech bubble in the accent, and the model that wrote it; a game still to review has nothing (Zoe) */
654
+ .analyses .state.reviewed {
655
+ display: flex;
656
+ align-items: center;
657
+ gap: 5px;
658
+ }
659
+
660
+ .analyses .state .icon {
661
+ flex: none;
662
+ width: 14px;
663
+ height: 14px;
664
+ stroke: var(--accent);
665
+ stroke-width: 1.75;
666
+ }
667
+
668
+ .analyses .state span {
669
+ overflow: hidden;
670
+ text-overflow: ellipsis;
671
+ }
672
+
673
+ /* The score with tabular figures, and how it went for the player as chess.com marks it, in columns that do not move from row to row */
674
+ .analyses .score {
675
+ display: grid;
676
+ grid-template-columns: auto 16px;
677
+ flex: none;
678
+ justify-items: end;
679
+ align-items: center;
680
+ gap: 6px;
681
+ min-width: 62px;
682
+ padding-right: 4px;
683
+ line-height: 1.2;
684
+ }
685
+
686
+ .analyses .outcome {
687
+ width: 16px;
688
+ height: 16px;
689
+ }
690
+
691
+ .analyses .outcome path {
692
+ fill: none;
693
+ stroke: var(--badge-ink);
694
+ stroke-width: 2;
695
+ stroke-linecap: round;
696
+ }
697
+
698
+ .analyses .outcome.won rect {
699
+ fill: var(--result-win);
700
+ }
701
+
702
+ .analyses .outcome.lost rect {
703
+ fill: var(--result-loss);
704
+ }
705
+
706
+ .analyses .outcome.drawn rect {
707
+ fill: var(--result-draw);
708
+ }
709
+
710
+ .analyses .score b {
711
+ font-size: 15px;
712
+ font-variant-numeric: tabular-nums;
713
+ }
714
+
715
+ .analyses .row-actions {
716
+ display: flex;
717
+ flex: none;
718
+ align-items: center;
719
+ padding: 0 8px 0 4px;
720
+ border-left: 1px solid var(--line);
721
+ }
722
+
723
+ .analyses .row-actions .icon-button {
724
+ width: 34px;
725
+ height: 34px;
726
+ border-color: transparent;
727
+ }
728
+
729
+ .analyses .row-actions .icon-button .icon {
730
+ stroke-width: 3;
731
+ }
732
+
733
+ .analyses .row-actions .icon-button:hover,
734
+ .analyses .row-actions .icon-button.on {
735
+ border-color: var(--line);
736
+ background: var(--page);
737
+ color: var(--ink);
738
+ }
739
+
740
+ /* Over the dialog in the browser's top layer, placed by its button */
741
+ .row-menu {
742
+ position: fixed;
743
+ inset: auto;
744
+ display: grid;
745
+ min-width: 230px;
746
+ max-width: calc(100vw - 16px);
747
+ margin: 0;
748
+ padding: 6px;
749
+ overflow: visible;
750
+ color: var(--ink);
751
+ border: 1px solid var(--line);
752
+ border-radius: 10px;
753
+ background: var(--card);
754
+ box-shadow: var(--shadow);
755
+ }
756
+
757
+ .row-menu button {
758
+ display: flex;
759
+ align-items: center;
760
+ gap: 10px;
761
+ padding: 9px 10px;
762
+ border: 0;
763
+ border-radius: 6px;
764
+ background: none;
765
+ color: var(--ink);
766
+ font: inherit;
767
+ font-size: 14px;
768
+ text-align: left;
769
+ cursor: pointer;
770
+ }
771
+
772
+ .row-menu button:hover,
773
+ .row-menu button:focus-visible {
774
+ background: var(--page);
775
+ }
776
+
777
+ .row-menu hr {
778
+ margin: 4px 6px;
779
+ border: 0;
780
+ border-top: 1px solid var(--line);
781
+ }
782
+
783
+ .row-menu .danger {
784
+ color: var(--low-time);
785
+ }
786
+
787
+ /* The question in place of the row: red for a deletion, the accent to analyse again */
788
+ .analyses .ask {
789
+ --asked: var(--low-time);
790
+ display: grid;
791
+ grid-template-columns: minmax(0, 1fr) auto;
792
+ align-items: center;
793
+ gap: 8px 16px;
794
+ padding: 10px 12px;
795
+ border: 1px solid var(--asked);
796
+ border-radius: 10px;
797
+ background: color-mix(in oklab, var(--asked) 7%, var(--card));
798
+ }
799
+
800
+ .analyses .ask.redo {
801
+ --asked: var(--accent);
802
+ }
803
+
804
+ .ask p {
805
+ margin: 0;
806
+ font-size: 14px;
807
+ line-height: 1.35;
808
+ }
809
+
810
+ .ask .buttons {
811
+ display: flex;
812
+ flex-wrap: wrap;
813
+ justify-content: flex-end;
814
+ gap: 8px;
815
+ }
816
+
817
+ .ask button {
818
+ display: inline-flex;
819
+ align-items: center;
820
+ gap: 6px;
821
+ height: 36px;
822
+ padding: 0 14px;
823
+ border: 1px solid var(--line);
824
+ border-radius: 8px;
825
+ background: var(--card);
826
+ color: var(--ink);
827
+ font: inherit;
828
+ font-size: 14px;
829
+ cursor: pointer;
830
+ }
831
+
832
+ .ask button.yes {
833
+ border-color: var(--asked);
834
+ background: var(--asked);
835
+ color: var(--on-accent);
836
+ font-weight: 600;
837
+ }
838
+
839
+ @media (max-width: 600px) {
840
+ .analyses .reopen {
841
+ gap: 10px;
842
+ }
843
+
844
+ .analyses .tile {
845
+ width: 40px;
846
+ height: 40px;
847
+ }
848
+
849
+ .analyses .row-actions {
850
+ padding: 0 4px;
851
+ border-left: 0;
852
+ }
853
+
854
+ .analyses .row-actions .icon-button {
855
+ width: 40px;
856
+ height: 44px;
857
+ }
858
+
859
+ .analyses .who {
860
+ display: -webkit-box;
861
+ white-space: normal;
862
+ -webkit-line-clamp: 2;
863
+ -webkit-box-orient: vertical;
864
+ line-height: 1.25;
865
+ }
866
+
867
+ .analyses .score {
868
+ min-width: 56px;
869
+ padding-right: 0;
870
+ }
871
+
872
+ .analyses .ask {
873
+ grid-template-columns: 1fr;
874
+ }
875
+ }
876
+
877
+ .profile-form textarea:focus-visible,
878
+ .profile-form input:focus-visible,
879
+ .profile-form select:focus-visible {
880
+ outline: 2px solid var(--accent);
881
+ outline-offset: -1px;
882
+ }
883
+
884
+ /* The drawn avatars: always two rows of five, smaller on a narrow screen (Zoe) */
885
+ .avatars {
886
+ display: grid;
887
+ grid-template-columns: repeat(5, minmax(0, 62px));
888
+ justify-content: space-between;
889
+ gap: 8px;
890
+ justify-items: center;
891
+ }
892
+
893
+ .avatars .avatar-choice {
894
+ width: 100%;
895
+ }
896
+
897
+ .avatar-choice {
898
+ position: relative;
899
+ padding: 3px;
900
+ border: 2px solid transparent;
901
+ border-radius: 50%;
902
+ background: none;
903
+ line-height: 0;
904
+ cursor: pointer;
905
+ }
906
+
907
+ .avatar-choice input {
908
+ position: absolute;
909
+ width: 1px;
910
+ height: 1px;
911
+ opacity: 0;
912
+ }
913
+
914
+ .avatar-choice:has(input:checked),
915
+ .avatar-choice[aria-pressed="true"],
916
+ .avatar-choice.on {
917
+ border-color: var(--accent);
918
+ }
919
+
920
+ .avatar-choice:has(input:focus-visible) {
921
+ outline: 2px solid var(--accent);
922
+ outline-offset: 2px;
923
+ }
924
+
925
+ .avatar-choice .avatar {
926
+ display: block;
927
+ width: 100%;
928
+ height: auto;
929
+ }
930
+
931
+ /* The player's own photo: a line of its own under the drawn avatars, at every width */
932
+ .avatar-choice.upload {
933
+ display: flex;
934
+ align-items: center;
935
+ gap: 10px;
936
+ width: fit-content;
937
+ margin-top: 10px;
938
+ padding-right: 14px;
939
+ border-radius: 30px;
940
+ color: var(--accent);
941
+ font-size: 14px;
942
+ line-height: 1.2;
943
+ }
944
+
945
+ .avatar-choice.upload .avatar {
946
+ width: 36px;
947
+ height: 36px;
948
+ }
949
+
950
+ .ring {
951
+ display: grid;
952
+ place-items: center;
953
+ width: 36px;
954
+ height: 36px;
955
+ border: 2px dashed var(--line);
956
+ border-radius: 50%;
957
+ color: var(--soft);
958
+ }
959
+
960
+ .ring .icon {
961
+ width: 18px;
962
+ height: 18px;
963
+ }
964
+
965
+ /* How the player plays: two by two, each with its note under it */
966
+ .levels {
967
+ display: grid;
968
+ grid-template-columns: 1fr 1fr;
969
+ gap: 8px;
970
+ }
971
+
972
+ .level {
973
+ position: relative;
974
+ cursor: pointer;
975
+ }
976
+
977
+ .level input {
978
+ position: absolute;
979
+ opacity: 0;
980
+ }
981
+
982
+ .level > span {
983
+ display: flex;
984
+ flex-direction: column;
985
+ gap: 2px;
986
+ height: 100%;
987
+ padding: 9px 12px;
988
+ border: 1px solid var(--line);
989
+ border-radius: 8px;
990
+ background: var(--page);
991
+ }
992
+
993
+ .level small {
994
+ color: var(--soft);
995
+ font-size: 13px;
996
+ }
997
+
998
+ .level:has(input:checked) > span {
999
+ border-color: var(--accent);
1000
+ box-shadow: inset 0 0 0 1px var(--accent);
1001
+ }
1002
+
1003
+ .level:has(input:focus-visible) > span {
1004
+ outline: 2px solid var(--accent);
1005
+ outline-offset: 2px;
1006
+ }
1007
+
1008
+ .rating {
1009
+ display: grid;
1010
+ grid-template-columns: 1fr 1fr;
1011
+ gap: 8px;
1012
+ }
1013
+
1014
+ .profile-form .start {
1015
+ width: 100%;
1016
+ padding: 13px;
1017
+ border: 0;
1018
+ border-radius: 8px;
1019
+ background: var(--accent);
1020
+ color: var(--on-accent);
1021
+ font: inherit;
1022
+ font-size: 16px;
1023
+ font-weight: 600;
1024
+ cursor: pointer;
1025
+ }
1026
+
1027
+ .profile-form .start:disabled {
1028
+ opacity: 0.6;
1029
+ cursor: default;
1030
+ }
1031
+
1032
+ .profile-form .problem,
1033
+ .dialog .problem {
1034
+ margin: 0 0 12px;
1035
+ padding: 0;
1036
+ color: var(--low-time);
1037
+ font-size: 14px;
1038
+ }
1039
+
1040
+ .dialog .avatars {
1041
+ margin-top: 8px;
1042
+ }
1043
+
1044
+ .dialog .avatar-choice.upload {
1045
+ margin-bottom: 12px;
1046
+ }
1047
+
1048
+ .profile-list {
1049
+ display: grid;
1050
+ gap: 6px;
1051
+ margin: 8px 0 12px;
1052
+ }
1053
+
1054
+ .profile-list .choice {
1055
+ min-width: 0;
1056
+ font-size: 15px;
1057
+ text-align: left;
1058
+ }
1059
+
1060
+ /* The profile in use: a tick at the end of its line, not the ring of a field being typed in */
1061
+ .profile-list .choice[aria-checked="true"] {
1062
+ border-color: var(--line);
1063
+ box-shadow: none;
1064
+ }
1065
+
1066
+ .profile-list .choice span {
1067
+ flex: 1;
1068
+ min-width: 0;
1069
+ overflow: hidden;
1070
+ white-space: nowrap;
1071
+ text-overflow: ellipsis;
1072
+ }
1073
+
1074
+ .profile-list .in-use {
1075
+ flex: none;
1076
+ width: 18px;
1077
+ height: 18px;
1078
+ color: var(--accent);
1079
+ }
1080
+
1081
+ .profile-list .choice:disabled {
1082
+ opacity: 0.6;
1083
+ cursor: default;
1084
+ }
1085
+
1086
+ .profile-list .avatar {
1087
+ flex: none;
1088
+ width: 32px;
1089
+ height: 32px;
1090
+ }
1091
+
1092
+ /* The names on Lichess and chess.com of the player in use, under their line: the site, the name, a tick once saved (D-93) */
1093
+ .dialog .accounts {
1094
+ display: grid;
1095
+ grid-template-columns: auto 1fr 18px;
1096
+ align-items: center;
1097
+ gap: 6px 10px;
1098
+ margin: -4px 0 12px;
1099
+ }
1100
+
1101
+ .accounts label {
1102
+ display: contents;
1103
+ }
1104
+
1105
+ .accounts span {
1106
+ color: var(--soft);
1107
+ font-size: 14px;
1108
+ }
1109
+
1110
+ .accounts input {
1111
+ min-width: 0;
1112
+ padding: 6px 10px;
1113
+ border: 1px solid var(--line);
1114
+ border-radius: 8px;
1115
+ background: var(--page);
1116
+ color: var(--ink);
1117
+ font: inherit;
1118
+ font-size: 15px;
1119
+ }
1120
+
1121
+ .accounts input:invalid {
1122
+ border-color: var(--low-time);
1123
+ }
1124
+
1125
+ .accounts .in-use {
1126
+ width: 18px;
1127
+ height: 18px;
1128
+ color: var(--accent);
1129
+ }
1130
+
1131
+ .accounts .problem {
1132
+ grid-column: 1 / -1;
1133
+ }
1134
+
1135
+ .dialog .new-profile {
1136
+ border-color: var(--line);
1137
+ color: var(--ink);
1138
+ }
1139
+
1140
+ .dialog .new-profile:disabled {
1141
+ color: var(--soft);
1142
+ cursor: default;
1143
+ }
1144
+
1145
+ /* Where the games are, under the wizard's form and the players' menu, with the button that opens it */
1146
+ .data-folder {
1147
+ display: flex;
1148
+ flex-wrap: wrap;
1149
+ align-items: center;
1150
+ gap: 8px 12px;
1151
+ margin-top: 20px;
1152
+ padding-top: 16px;
1153
+ border-top: 1px solid var(--line);
1154
+ }
1155
+
1156
+ .data-folder .note {
1157
+ flex: 1 1 220px;
1158
+ margin: 0;
1159
+ }
1160
+
1161
+ .data-folder b {
1162
+ color: var(--ink);
1163
+ font-weight: 600;
1164
+ overflow-wrap: anywhere;
1165
+ }
1166
+
1167
+ .data-folder .command {
1168
+ border-color: var(--line);
1169
+ color: var(--ink);
1170
+ }
1171
+
1172
+ .data-folder .command:disabled {
1173
+ color: var(--soft);
1174
+ cursor: default;
1175
+ }
1176
+
1177
+ .data-folder .problem {
1178
+ flex-basis: 100%;
1179
+ margin: 0;
1180
+ }
1181
+
1182
+ /* The new game: the colours and the clocks in a row, the levels two by two with what the AI sees under them */
1183
+ .new-game .row {
1184
+ display: grid;
1185
+ grid-template-columns: repeat(auto-fit, minmax(52px, 1fr));
1186
+ gap: 8px;
1187
+ }
1188
+
1189
+ .new-game .row .level > span {
1190
+ align-items: center;
1191
+ gap: 4px;
1192
+ padding: 9px 4px;
1193
+ }
1194
+
1195
+ /* Each colour by its king, either by both, and each clock by its minutes as a slice of the hour */
1196
+ .new-game .row .piece {
1197
+ width: 30px;
1198
+ height: 30px;
1199
+ margin: -3px 0;
1200
+ }
1201
+
1202
+ .new-game .kings {
1203
+ display: flex;
1204
+ }
1205
+
1206
+ .new-game .kings .piece + .piece {
1207
+ margin-left: -8px;
1208
+ }
1209
+
1210
+ .new-game .clock-icon {
1211
+ width: 24px;
1212
+ height: 24px;
1213
+ }
1214
+
1215
+ .new-game .clock-icon .slice {
1216
+ fill: currentColor;
1217
+ stroke: none;
1218
+ }
1219
+
1220
+ .new-game .sees {
1221
+ margin: 10px 0 0;
1222
+ color: var(--soft);
1223
+ font-size: 13px;
1224
+ }
1225
+
1226
+ .new-game .levels {
1227
+ grid-auto-rows: 1fr;
1228
+ }