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