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