Remove (useless?) pingback logic + retry send move on client side
[xogo.git] / common.css
1 /* CSS reset */
2 *,
3 *::before,
4 *::after {
5 box-sizing: border-box;
6 margin: 0;
7 padding: 0;
8 border: 0;
9 font-size: 100%;
10 font: inherit;
11 vertical-align: baseline;
12 }
13
14 html {
15 height: 100%;
16 }
17
18 body {
19 height: 100%;
20 margin: 0;
21 background-color: #f8f8f8;
22 font-family: Arial, Verdana, Tahoma, sans-serif;
23 /* https://stackoverflow.com/a/24392249/12660887 */
24 position: relative;
25 }
26
27 main {
28 display: flex;
29 flex-direction: column;
30 justify-content: center;
31 align-items: center;
32 flex-wrap: nowrap;
33 font-size: 1.25rem;
34 }
35
36 main > div {
37 margin-top: 25vh;
38 min-height: 500px;
39 min-width: 320px;
40 max-width: 800px; /*useful for rules display only*/
41 }
42
43 @media(max-height: 800px) {
44 main > div {
45 margin-top: 30px;
46 }
47 }
48
49 @media(max-width: 767px) {
50 main > div {
51 padding: 0 10px;
52 }
53 }
54
55 #boardContainer {
56 margin: 0;
57 padding: 0;
58 border: none;
59 }
60
61 h1 {
62 font-size: 2rem;
63 font-weight: bold;
64 text-align: center;
65 display: block;
66 margin: 10px 0;
67 }
68
69 #gameInfos,
70 #boardContainer,
71 #gameStopped,
72 #pendingSeek,
73 #pendingRematch,
74 #newGameForm {
75 display: none;
76 }
77
78 .bold {
79 font-weight: bold;
80 }
81
82 #gameInfos > .players-info {
83 text-align: center;
84 }
85
86 #gameInfos > .options-info {
87 text-align: center;
88 color: #757575;
89 margin-bottom: 15px;
90 }
91
92 #gameInfos > div {
93 margin: 10px 0;
94 }
95
96 #gameInfos > .rules {
97 color: #732E6C;
98 }
99
100 #gameInfos > .rules > p,
101 #gameInfos > .rules > ul,
102 #gameInfos > .rules > ol {
103 margin: 10px 0;
104 }
105
106 #gameStopped > h1 {
107 margin-bottom: 10px;
108 }
109
110 /* "Sticky footer" */
111 #footer {
112 position: absolute;
113 bottom: 0;
114 left: 0;
115 right: 0;
116 height: 50px;
117 text-align: center;
118 }
119
120 a.left-link {
121 margin-right: 25px;
122 }
123 a.right-link {
124 margin-left: 25px;
125 }
126
127 #footer a > img {
128 height: 1.2em;
129 display: inline-block;
130 transform: translateY(3px);
131 }
132
133 button {
134 background-color: #757575;
135 border: none;
136 color: white;
137 padding: 10px 15px;
138 text-align: center;
139 text-decoration: none;
140 display: inline-block;
141 font-size: 1em;
142 cursor: pointer;
143 border-radius: 20%;
144 margin: 15px 0;
145 }
146
147 button:hover, button.block-btn:hover {
148 background-color: #b11adc;
149 }
150
151 button.block-btn {
152 display: block;
153 background-color: #01786F;
154 margin: 0 auto 20px auto;
155 font-size: 2rem;
156 padding: 15px 32px;
157 }
158
159 #upLeftInfos {
160 position: absolute;
161 left: 0;
162 top: 0;
163 }
164
165 #upRightStop {
166 position: absolute;
167 left: calc(100% - 25px);
168 top: 0;
169 }
170 #upLeftInfos > svg, #upRightStop > svg {
171 width: 25px;
172 cursor: pointer;
173 }
174
175 @media(max-width: 767px) {
176 #upRightStop {
177 left: calc(100% - 35px);
178 }
179 #upLeftInfos > svg, #upRightStop > svg {
180 width: 35px;
181 }
182 #upLeftInfos > svg path, #upRightStop > svg path {
183 fill: #999;
184 }
185 }
186
187 #ng-select {
188 margin-bottom: 20px;
189 }
190
191 /* Options when starting custom game */
192 .words {
193 line-height: 0.9em;
194 }
195 .words > .row {
196 margin: 0;
197 }
198 .words span {
199 cursor: pointer;
200 padding: 3px;
201 display: inline-block;
202 margin: 2px;
203 }
204 .highlight-word {
205 background-color: lightblue;
206 }
207
208 #gameOptions {
209 text-align: center;
210 }
211
212 .option-select, .option-check {
213 margin: 15px 0;
214 }
215
216 .btn-wrap {
217 text-align: center;
218 }
219
220 #gameLink {
221 width: inherit;
222 text-align: center;
223 }
224
225 a {
226 text-decoration: none;
227 }
228
229 /* Game link div + custom game "button" */
230 #gameLink span, #gameLink a, #footer a {
231 padding-bottom: 1px;
232 border-bottom: 1px dotted darkgrey;
233 color: darkred;
234 }
235
236 #gameLink span {
237 display: inline-box;
238 cursor: pointer;
239 }
240
241 #gameLink > p {
242 margin: 10px 0;
243 }
244
245 /* Board container (without reserves) */
246 #chessboard {
247 position: absolute;
248 cursor: pointer;
249 }
250
251 /* Board container can be resized */
252 .resizeable {
253 resize: both;
254 overflow: hidden;
255 min-width: 200px;
256 min-height: 200px;
257 }
258
259 piece {
260 position: absolute;
261 top: 0;
262 left: 0;
263 background-size: cover;
264 z-index: 2;
265 will-change: transform;
266 pointer-events: none;
267 }
268
269 /* Drawing of the board */
270 #chessboard_SVG {
271 width: 100%;
272 height: 100%;
273 }
274
275 .dark-square {
276 fill: #b58863;
277 }
278 .light-square {
279 fill: #f0d9b5;
280 }
281 .in-shadow {
282 filter: brightness(50%);
283 }
284
285 .reserves {
286 position: absolute;
287 display: block;
288 cursor: pointer;
289 }
290
291 .reserve-cell {
292 position: relative;
293 display: block;
294 float: left;
295 }
296
297 /* Pieces' counter for reserves */
298 .reserve-num {
299 color: red;
300 position: absolute;
301 display: block;
302 font-weight: bold;
303 /*z-index: 10;*/
304 }
305
306 /* Choices div after a promotion (TODO: do not hide board) */
307 #choices, .choice {
308 position: absolute;
309 cursor: pointer;
310 }
311
312
313 /* https://moderncss.dev/custom-select-styles-with-pure-css/ */
314 :root {
315 --select-border: #777;
316 --select-focus: #b11adc;
317 --select-arrow: var(--select-border);
318 }
319
320 select {
321 appearance: none;
322 background-color: transparent;
323 border: none;
324 padding: 0 1em 0 0;
325 margin: 0;
326 width: 100%;
327 font-family: inherit;
328 font-size: inherit;
329 cursor: inherit;
330 line-height: inherit;
331 z-index: 1;
332 outline: none;
333 }
334
335 .select {
336 display: grid;
337 grid-template-areas: "select";
338 align-items: center;
339 position: relative;
340 min-width: 15ch;
341 max-width: 30ch;
342 border: 1px solid var(--select-border);
343 border-radius: 0.25em;
344 padding: 0.25em 0.5em;
345 font-size: 1.25rem;
346 cursor: pointer;
347 line-height: 1.1;
348 background-color: #fff;
349 background-image: linear-gradient(to top, #f9f9f9, #fff 33%);
350 width: 100%;
351 margin: auto;
352 }
353
354 select, .select::after {
355 grid-area: select;
356 }
357
358 .select::after {
359 content: "";
360 justify-self: end;
361 width: 0.8em;
362 height: 0.5em;
363 background-color: var(--select-arrow);
364 clip-path: polygon(100% 0%, 0 0%, 50% 100%);
365 }
366
367 select:focus + .focus {
368 position: absolute;
369 top: -1px;
370 left: -1px;
371 right: -1px;
372 bottom: -1px;
373 border: 2px solid var(--select-focus);
374 border-radius: inherit;
375 }
376
377
378 /* https://auralinna.blog/post/2018/how-to-create-material-design-like-form-text-fields/ */
379 .form-field {
380 display: block;
381 margin-bottom: 16px;
382 }
383 .form-field--is-active .form-field__control::after {
384 border-bottom: 2px solid #b11adc;
385 transform: scaleX(150);
386 }
387 .form-field--is-active .form-field__label {
388 color: #b11adc;
389 font-size: 0.75rem;
390 transform: translateY(-14px);
391 }
392 .form-field--is-filled .form-field__label {
393 font-size: 0.75rem;
394 transform: translateY(-14px);
395 }
396 .form-field__label {
397 display: block;
398 font-size: 1.2rem;
399 font-weight: normal;
400 left: 0;
401 margin: 0;
402 padding: 18px 12px 0;
403 position: absolute;
404 top: 0;
405 transition: all 0.4s;
406 width: 100%;
407 }
408 .form-field__control {
409 background: #eee;
410 border-radius: 8px 8px 0 0;
411 overflow: hidden;
412 position: relative;
413 width: 100%;
414 }
415 .form-field__control::after {
416 border-bottom: 2px solid #b11adc;
417 bottom: 0;
418 content: "";
419 display: block;
420 left: 0;
421 margin: 0 auto;
422 position: absolute;
423 right: 0;
424 transform: scaleX(0);
425 transition: all 0.4s;
426 width: 1%;
427 }
428 .form-field__input {
429 appearance: none;
430 background: transparent;
431 border: 0;
432 border-bottom: 1px solid #999;
433 color: #333;
434 display: block;
435 font-size: 1.2rem;
436 margin-top: 24px;
437 outline: 0;
438 padding: 0 12px 10px 12px;
439 width: 100%;
440 }
441
442
443 /* https://dev.to/kallmanation/styling-a-checkbox-with-only-css-3o3p */
444 label.checkbox > input[type="checkbox"] {
445 display: none;
446 }
447 label.checkbox > input[type="checkbox"] + *::before {
448 content: "";
449 display: inline-block;
450 vertical-align: bottom;
451 margin-bottom: 3px;
452 width: 1.1rem;
453 height: 1.1rem;
454 border-radius: 10%;
455 border-style: solid;
456 border-width: 0.1rem;
457 border-color: gray;
458 }
459
460 label.checkbox > input[type="checkbox"]:checked + *::before {
461 content: "✓";
462 font-size: 1.1rem;
463 /*padding:10px;*/
464 color: white;
465 text-align: center;
466 background: teal;
467 border-color: teal;
468 }
469 label.checkbox > input[type="checkbox"]:checked + * {
470 color: teal;
471 }
472
473 /*label.checkbox {
474 color: teal;
475 }*/
476 label.checkbox > span.spacer {
477 width: 10px;
478 content: " ";
479 }
480
481
482 /* https://theanam.github.io/css-only-loaders/ ("hour-glass") */
483 :root{
484 --loader-width: 70px;
485 --loader-height: 70px;
486 --loader-color-primary: #01786F;
487 --loader-color-secondary: #EEE;
488 --line-width: 3px;
489 --animation-duration: 3s;
490 --loader-initial-scale: 0.1;
491 }
492 .loader,.loader:before,.loader:after{
493 box-sizing: border-box;
494 flex-grow: 0;
495 flex-shrink: 0;
496 }
497
498 @keyframes slide {
499 0% {
500 transform: translateY(0%);
501 }
502 25% {
503 transform: translateY(100%);
504 }
505 50% {
506 transform: translateY(100%);
507 }
508 75% {
509 transform: translateY(0%);
510 }
511 100% {
512 transform: translateY(0%);
513 }
514 }
515
516 @keyframes spin {
517 0% {
518 transform: rotate(0deg);
519 }
520 25% {
521 transform: rotate(0deg);
522 }
523 50% {
524 transform: rotate(180deg);
525 }
526 75% {
527 transform: rotate(180deg);
528 }
529 100% {
530 transform: rotate(360deg);
531 }
532 }
533
534 .loader.hour-glass {
535 position: relative;
536 width: var(--loader-width, 100px);
537 height: var(--loader-height, 100px);
538 background-color: var(--loader-color-primary, #00f);
539 -webkit-clip-path: polygon(0% 0%, 100% 0%, 50% 50%, 100% 100%, 0% 100%, 50% 50%);
540 clip-path: polygon(0% 0%, 100% 0%, 50% 50%, 100% 100%, 0% 100%, 50% 50%);
541 overflow: hidden;
542 animation: spin var(--animation-duration, 4s) infinite ease-in-out;
543 margin: 20px auto;
544 }
545
546 .hour-glass:before {
547 content: "";
548 position: absolute;
549 top: 0px;
550 left: 0px;
551 width: var(--loader-width, 100px);
552 height: 50%;
553 background-color: var(--loader-color-secondary, #eee);
554 animation: slide var(--animation-duration, 4s) infinite ease-in-out;
555 }