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