/* Font declarations */

@font-face {
    font-family: "IBMPlexMono";
    src: url(fonts/IBMPlexMono-Medium.ttf);
    font-weight: 500;
    font-style: normal;
    unicode-range: U+000-5FF
}

@font-face {
    font-family: "Archivo";
    src: url(fonts/Archivo-Medium.ttf);
    font-weight: 500;
    font-style: normal;
    unicode-range: U+000-5FF
}

@font-face {
    font-family: "Archivo";
    src: url(fonts/Archivo-SemiBold.ttf);
    font-weight: 600;
    font-style: normal;
    unicode-range: U+000-5FF
}

* {
    font-family: 'Archivo', system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    --gradient-turquoise: #79e9db;
    --gradient-purple: #8f7fd9;
    --turquoise: #85d2d5;
    --purple: #8f8dd7;
    --transparent-black: #0001
}

body {
    position: relative;
    height: calc(100vh - 50px);
    display: grid;
    place-content: center;
    color: #fff;
}

button {
    position: relative;
    appearance: none;
    font-weight: 600;
    background-color: transparent;
    color: var(--font-color);
    border: 0;
    cursor: pointer
}

/* Top buttons:

1. Change opponent
2. Reset score
3. Play again 

*/

.change-opponent,
.reset-score,
.play-again {
    z-index: 0;
    text-transform: uppercase;
    font-size: 1.1rem;
    border-radius: .3rem;
    box-shadow: 0 0 16px 0 var(--transparent-black);
    padding: 1.5rem;
    transition: .3s transform, .3s color;
    transition-timing-function: ease-out;
    will-change: transform, color
}

.change-opponent,
.reset-score {
    margin-bottom: 1rem
}

.change-opponent {
    overflow: hidden;
    display: grid;
    grid-template-columns: 30% 15% 68%;
    background-image: linear-gradient(to right, var(--gradient-turquoise), var(--gradient-purple))
}

.reset-score {
    background-color: var(--turquoise)
}

/* By default, the Play Again button is greyed out (linear gradient), and unable to be interacted with (pointer events).
As soon as the game ends either by a win or by a tie, the Play Again button receives the .clickable class, and becomes
interactive */

.play-again {
    background-image: linear-gradient(to right, #aaa, #5c5c5c);
    margin-bottom: 2rem;
    transform: translateX(-25%);
}

.play-again.clickable {
    background-image: none;
    background-color: var(--purple);
    transform: translateX(0)
}

/* The Change Opponent button is separated in three sections using <span> elements:

First section: a <span> element with the "Player" text content
Second section: a <span> element with the "VS" text content
Third section: a <span> element with two nested <span> elements, one containing the Opponent type, which changes between
Player and Computer on click, and one containing the Opponent difficulty level, which changes between easy, medium, and
unbeatable (also on click).

*/

/* A background hover effect will be added only for the third section of the button using ::before, 
since this is the only section that has is content changed when user clicks the button. */

.change-opponent::before {
    z-index: -1;
    content: "";
    position: absolute;
    top: 4px;
    right: 4px;
    bottom: 4px;
    left: calc(50% + 2px);
    background-color: #ffffffe6;
    border-top-right-radius: .2rem;
    border-bottom-right-radius: .2rem;
    transform: scale(0);
    opacity: 0;
    transition: .3s transform, .2s opacity;
    will-change: transform, opacity
}

/* The first two span elements are visually delimited from the third element with a border */

.change-opponent span:nth-child(1)::before {
    box-sizing: border-box;
    z-index: -1;
    content: "";
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: -2px;
    width: 50%;
    border-right: 4px solid #ffffff90
}

/* The third span element, containing information regarding the current Opponent type and Opponent difficulty (if applicable) */

.change-opponent span:nth-child(3) {
    display: flex;
    flex-direction: column;
    transition: .3s color;
    will-change: color
}

.change-opponent span:nth-child(3) .opponent-difficulty {
    justify-self: center;
    font-size: .8rem;
    font-weight: 500;
    line-height: 0;
    transform: translateY(6px);
}

/* The Reset Score and Play Again buttons will share the same hover effect as the one used by the Change Opponent button,
however since the buttons do not have nested sections, their ::before hover effect will cover the entire width and 
height (minus few pixels to simulate borders) */

.reset-score::before,
.play-again::before {
    z-index: -1;
    content: "";
    position: absolute;
    top: 4px;
    left: 4px;
    right: 4px;
    bottom: 4px;
    background-color: #ffffffe6;
    border-radius: .2rem;
    transform: scale(0);
    opacity: 0;
    transition: .3s transform, .2s opacity;
    will-change: transform, opacity
}

/* Hover effects */

@media (hover: hover) {
    .change-opponent:hover span:nth-child(3) {
        color: #8CA6D7
    }

    .reset-score:hover {
        color: var(--turquoise)
    }

    .play-again.clickable:hover {
        color: var(--purple)
    }

    .change-opponent:hover::before,
    .reset-score:hover::before,
    .play-again.clickable:hover::before {
        transform: scale(1);
        opacity: 1
    }

    .change-opponent:active::before,
    .reset-score:active::before,
    .play-again.clickable:active::before {
        background-color: #ffffffb3;
    }
}

/* Game container, containing two score panels, one for each player (x and zero), followed by the Game panel */

.container {
    justify-self: center;
    display: grid;
    grid-template-rows: 40px auto;
    grid-template-columns: auto auto
}

/* The two score panels, each containing the value of each player and their corresponding score. The X player is located
on the left and the Zero player is located on the right

By default, the score panels have a grey color. Each score panel has its color changed by the .show class, which
is added and removed from each panel based on the current player turn 

If a winner is found, a .winner class is added to the winner's corresponding panel, which applies a translateY transform
animation, to differentiate the winner's panel from the loser's panel.
If the game is in a Tie state, the .show class is removed from both score panels, visually informing the user
that both players lost, or that both players did not win

*/


#x,
#zero {
    z-index: -1;
    width: 90px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background-color: #858585;
    border-top-left-radius: .2rem;
    border-top-right-radius: .2rem;
    box-shadow: 0 -4px 16px 0 var(--transparent-black);
    transform: translateY(30%);
    transition: .3s background-color, .3s transform;
    will-change: transform, background-color
}

#x {
    padding: 0 10px 0 4px
}

#zero {
    padding: 0 4px 0 10px;
    justify-self: end
}

#x .score,
#x svg,
#zero .score,
#zero svg {
    transform: translateY(-25%);
    transition: .3s transform;
    will-change: transform
}

#x .score,
#zero .score {
    font-family: 'IBMPlexMono', system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    font-size: 1.1rem;
    font-weight: 500;
    line-height: normal
}

#x.show {
    background-color: var(--turquoise)
}

#zero.show {
    background-color: var(--purple)
}

#x.show.winner,
#zero.show.winner {
    transform: translateY(0)
}

#x.show.winner .score,
#x.show.winner svg,
#zero.show.winner .score,
#zero.show.winner svg {
    transform: translateY(0)
}

/* The panel container, which contains all 9 squares on a 3x3 grid.

The panel and its squares all have a transparent background, allowing the ::before rotating gradient animation to be
seen by the user.

*/

.panel-container {
    overflow: hidden;
    grid-column: 1 / 3;
    position: relative;
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    border-bottom-left-radius: .3rem;
    border-bottom-right-radius: .3rem;
    box-shadow: 0 6px 12px 0 var(--transparent-black);
    gap: 4px;
    padding: 4px;
    touch-action: none;
    will-change: transform;
}

.panel-container::before {
    content: "";
    z-index: -1;
    position: absolute;
    width: 150%;
    height: 150%;
    justify-self: center;
    align-self: center;
    background-image: linear-gradient(to right, var(--gradient-turquoise), var(--gradient-purple));
    animation: rotate 15s linear infinite;
}

@keyframes rotate {
    from {
        transform: rotate(0deg);
    }

    to {
        transform: rotate(360deg);
    }
}

.square {
    position: relative;
    font-size: 0;
    border: 1px solid #fffc;
    transition: .3s background-color;
    will-change: background-color
}

.square:nth-child(7) {
    border-bottom-left-radius: .2rem
}

.square:nth-child(9) {
    border-bottom-right-radius: .2rem
}

.square:empty:hover {
    cursor: pointer;
    background-color: #ffffff80
}

.square.winner,
.square.winner:hover {
    background-color: #ffffffe6
}

.square::before {
    content: "";
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    transform-origin: center
}

/* Depending on the value of the current player, each square receives either a .x or a .zero class on click. Each class
shows its respective SVG's using the background-image property. */

.square.x::before,
.square.zero::before {
    animation: mark .3s;
    animation-fill-mode: forwards
}

.square.x::before {
    background-image: url(svg/x.svg);
}

.square.zero::before {
    background-image: url(svg/circle.svg);
}

.square.x.winner::before {
    background-image: url(svg/x-winner.svg)
}

.square.zero.winner::before {
    background-image: url(svg/circle-winner.svg)
}

@keyframes mark {
    0% {
        transform: scale(0)
    }

    50% {
        transform: scale(1.2)
    }

    100% {
        transform: scale(1)
    }
}