mirror of
https://github.com/danbulant/slightlyComplicatedTicTacToe
synced 2026-09-18 05:44:17 +00:00
Dark mode #12
This commit is contained in:
parent
af3d0481ca
commit
75ba376f46
11 changed files with 181 additions and 44 deletions
9
client/src/lib/DarkmodeIcon.svelte
Normal file
9
client/src/lib/DarkmodeIcon.svelte
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<script>
|
||||
import { themeStore } from "./themeStore";
|
||||
</script>
|
||||
|
||||
{#if $themeStore == "dark"}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="white"><rect fill="none" height="24" width="24"/><path d="M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0 c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2 c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1 C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06 c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41 l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41 c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36 c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg>
|
||||
{:else}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36c-0.98,1.37-2.58,2.26-4.4,2.26 c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg>
|
||||
{/if}
|
||||
|
|
@ -168,7 +168,7 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<a href="/" on:click={check} class="arrow-back fixed top-0 left-0 w-4 h-4 m-4 p-2 transform transition-transform hover:-translate-x-1">
|
||||
<a href="/" on:click={check} class="text-black dark:text-white arrow-back fixed top-0 left-0 w-4 h-4 m-4 p-2 transform transition-transform hover:-translate-x-1">
|
||||
<svg width="16" height="16">
|
||||
<line y1="50%" x1="0" y2="50%" x2="100%" stroke="currentColor" stroke-width="2" />
|
||||
<line y1="50%" x1="0" y2="100%" x2="50%" stroke="currentColor" stroke-width="2" />
|
||||
|
|
@ -177,7 +177,7 @@
|
|||
</a>
|
||||
|
||||
{#if !twoPlayer}
|
||||
<div on:click={reset} class="reload fixed top-0 left-10 w-4 h-4 m-4 p-2 transform transition-transform rotate-180 hover:rotate-360 active:rotate-540">
|
||||
<div on:click={reset} on:keydown={reset} class="reload fixed top-0 left-10 w-4 h-4 m-4 p-2 transform transition-transform rotate-180 hover:rotate-360 active:rotate-540">
|
||||
<svg fill="currentColor" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 489.645 489.645" xml:space="preserve" class="w-full h-full">
|
||||
<g>
|
||||
|
|
@ -196,8 +196,23 @@
|
|||
{#each classes as className, i}
|
||||
<div class:hover={hoveredPiece?.i == i} class:disabled={containerStates[i]} class:current={currentContainer === i} class:highlighted={highlightedContainer === i} class="squares-container {className}">
|
||||
{#each (new Array(9)) as _, j}
|
||||
{@const move = moves.find(move => move.i == i && move.j == j)}
|
||||
<div on:click={() => addMove(i, j)} class:hover={hoveredPiece?.i == i && hoveredPiece.j == j} class="square" class:move class:preview={!move} class:cross={move && move.p==1} class:circle={move && move.p==2} on:mouseover={() => { if(currentContainer == i) hoveredPiece = { i, j } }} on:mouseleave={() => { if(hoveredPiece?.i == i && hoveredPiece.j == j) hoveredPiece = null; }}>
|
||||
{@const moveIndex = moves.findIndex(cmove => cmove.i == i && cmove.j == j)}
|
||||
{@const move = moves[moveIndex]}
|
||||
<div
|
||||
class:latest={moveIndex == moves.length - 1}
|
||||
on:click={() => addMove(i, j)}
|
||||
on:keydown={() => addMove(i, j)}
|
||||
class:hover={hoveredPiece?.i == i && hoveredPiece.j == j}
|
||||
class="square"
|
||||
class:move
|
||||
class:preview={!move}
|
||||
class:cross={move && move.p==1}
|
||||
class:circle={move && move.p==2}
|
||||
on:mouseover={() => { if(currentContainer == i) hoveredPiece = { i, j } }}
|
||||
on:focus={() => { if(currentContainer == i) hoveredPiece = { i, j }}}
|
||||
on:mouseleave={() => { if(hoveredPiece?.i == i && hoveredPiece.j == j) hoveredPiece = null; }}
|
||||
>
|
||||
|
||||
{#if move}
|
||||
{#if move.p == 1}
|
||||
<svg width="16" height="16">
|
||||
|
|
@ -273,18 +288,18 @@
|
|||
{/if}
|
||||
|
||||
{#key currentPlayer}
|
||||
<div class="absolute top-200 left-0 right-0 text-center" in:fly={{ delay: 300, duration: 300, easing: quadOut, opacity: 0, y: 30 }} out:fly={{ delay: 0, duration: 300, easing: quadOut, opacity: 0, y: -30 }}>
|
||||
{#if overallState == 1 || currentPlayer == 1}
|
||||
<svg width="16" height="16" class="text-red-500">
|
||||
<div class="absolute top-200 left-0 right-0 text-center flex items-center justify-center gap-2" in:fly={{ delay: 300, duration: 300, easing: quadOut, opacity: 0, y: 30 }} out:fly={{ delay: 0, duration: 300, easing: quadOut, opacity: 0, y: -30 }}>
|
||||
{#if overallState == 1 || !overallState && currentPlayer == 1}
|
||||
<svg width="16" height="16" class="mb-0.5 text-red-500">
|
||||
<line x1="0" y1="0" x2="100%" y2="100%" stroke="currentColor" stroke-width="2" />
|
||||
<line x1="100%" y1="0" x2="0" y2="100%" stroke="currentColor" stroke-width="2" />
|
||||
</svg>
|
||||
{:else if overallState == 2 || currentPlayer == 2}
|
||||
<svg width="16" height="16" class="text-blue-500">
|
||||
{:else if overallState == 2 || !overallState && currentPlayer == 2}
|
||||
<svg width="16" height="16" class="mb-0.5 text-blue-500">
|
||||
<circle cx="50%" cy="50%" r="45%" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
</svg>
|
||||
{:else}
|
||||
<svg width="16" height="16">
|
||||
<svg width="16" height="16" class="mb-0.5">
|
||||
<line x1="0" y1="0" x2="100%" y2="100%" stroke="currentColor" stroke-width="2" />
|
||||
<line x1="100%" y1="0" x2="0" y2="100%" stroke="currentColor" stroke-width="2" />
|
||||
<circle cx="50%" cy="50%" r="45%" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
|
|
@ -301,17 +316,17 @@
|
|||
{:else}
|
||||
is on turn.
|
||||
{#if twoPlayer && self == currentPlayer}
|
||||
<b>It is <span class:text-red-500={currentPlayer == 1} class:text-blue-500={currentPlayer == 2}>YOUR</span> {selfName ? "(" + selfName + ")" : ""} turn.</b>
|
||||
<span class="-ml-1"><b>It is <span class:text-red-500={currentPlayer == 1} class:text-blue-500={currentPlayer == 2}>YOUR</span> {selfName ? "(" + selfName + ")" : ""} turn.</b></span>
|
||||
{:else if twoPlayer && self != currentPlayer}
|
||||
Waiting for <b class:text-red-500={currentPlayer == 1} class:text-blue-500={currentPlayer == 2}>{opponentName || "opponent"}</b>...
|
||||
<span class="-ml-1">Waiting for <b class:text-red-500={currentPlayer == 1} class:text-blue-500={currentPlayer == 2}>{opponentName || "opponent"}</b>…</span>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/key}
|
||||
</div>
|
||||
|
||||
<div class="info min-w-38 px-4 h-100vh overflow-y-auto <md:w-full">
|
||||
<div class="moves">
|
||||
<div class="info min-w-38 px-4 h-full overflow-y-auto <md:w-full">
|
||||
<div class="moves h-full">
|
||||
{#if twoPlayer}
|
||||
<div class="move text-red-500">
|
||||
<svg width="16" height="16">
|
||||
|
|
@ -339,7 +354,7 @@
|
|||
|
||||
<style>
|
||||
.info .moves {
|
||||
columns: 9.5rem auto;
|
||||
@apply p-4 font-mono flex flex-col flex-wrap;
|
||||
}
|
||||
.move {
|
||||
@apply p-1 flex gap-2 p-1 items-center leading-none;
|
||||
|
|
@ -356,18 +371,19 @@
|
|||
.winner-1 {
|
||||
@apply text-red-500;
|
||||
}
|
||||
.moves {
|
||||
@apply p-4 font-mono;
|
||||
}
|
||||
.board {
|
||||
@apply grid grid-cols-3 grid-rows-3 gap-10 w-max h-max m-auto my-5;
|
||||
@apply grid grid-cols-3 grid-rows-3 gap-10 w-max h-max m-auto my-5 flex-shrink-0;
|
||||
}
|
||||
.squares-container {
|
||||
@apply grid grid-cols-3 grid-rows-3 gap-5 w-max h-max opacity-35 relative;
|
||||
}
|
||||
|
||||
.square {
|
||||
@apply border-black border-solid border w-6 h-6 p-4 cursor-pointer flex items-center justify-center;
|
||||
@apply border-black border-solid border w-6 h-6 p-4 cursor-pointer flex items-center justify-center transition-none;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
:global(.dark) .square {
|
||||
@apply border-white;
|
||||
}
|
||||
.squares-container:not(.current) .square:active {
|
||||
@apply bg-red-600/10;
|
||||
|
|
@ -385,15 +401,18 @@
|
|||
@apply cursor-not-allowed;
|
||||
}
|
||||
.square svg {
|
||||
@apply w-full h-full;
|
||||
@apply w-full h-full transition-none;
|
||||
}
|
||||
.square svg * {
|
||||
@apply transition-none;
|
||||
}
|
||||
.square:hover, .square.hover {
|
||||
@apply bg-black/5;
|
||||
}
|
||||
.square.hover.cross, .square:hover.cross {
|
||||
.square.hover.cross, .square:hover.cross, .square.latest.cross {
|
||||
@apply text-red-500;
|
||||
}
|
||||
.square.hover.circle, .square:hover.circle {
|
||||
.square.hover.circle, .square:hover.circle, .square.latest.circle {
|
||||
@apply text-blue-500;
|
||||
}
|
||||
.highlighted {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
</div>
|
||||
|
||||
<main class="flex flex-col w-100vw h-100vh">
|
||||
<div class="p-4 pl-16 flex justify-between border-b border-b-black border-b-solid">
|
||||
<div class="p-4 pl-16 flex justify-between border-b border-b-black dark:border-b-white border-b-solid">
|
||||
<h1 in:fly={{ delay: 0, duration, opacity: 0, y: 100, easing: quadOut }}>Rooms</h1>
|
||||
<div class="right">
|
||||
<button in:fly={{ delay: duration * 0.5, duration, opacity: 0, y: 100, easing: quadOut }} disabled>Quick match</button>
|
||||
|
|
@ -100,14 +100,35 @@
|
|||
@apply cursor-pointer border-b border-b-solid border-b-gray-300 p-4;
|
||||
}
|
||||
button {
|
||||
@apply w-64 h-10 px-2 border border-gray-300 bg-white mt-4 my-0;
|
||||
@apply w-64 h-10 px-2 border border-gray-300 bg-white mt-4 my-0 cursor-pointer;
|
||||
}
|
||||
button:disabled {
|
||||
@apply bg-gray-300 cursor-not-allowed;
|
||||
}
|
||||
:global(.dark) button {
|
||||
@apply bg-white/15 border-gray-700 text-white;
|
||||
}
|
||||
:global(.dark) button:hover {
|
||||
@apply bg-white/10;
|
||||
}
|
||||
:global(.dark) button:disabled {
|
||||
@apply bg-black;
|
||||
}
|
||||
:global(.dark) button:disabled:hover {
|
||||
@apply bg-gray-900;
|
||||
}
|
||||
dialog .header button {
|
||||
@apply w-12;
|
||||
}
|
||||
:global(.dark) dialog {
|
||||
@apply bg-black border-gray-700 text-white;
|
||||
}
|
||||
input {
|
||||
@apply w-64 h-10 px-2 border border-gray-300 rounded-l-lg mt-4 my-0;
|
||||
}
|
||||
:global(.dark) input {
|
||||
@apply border-gray-400 text-white bg-black;
|
||||
}
|
||||
button:first-child {
|
||||
@apply rounded-l-lg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
export var piece: number | "?";
|
||||
export var latest: boolean = false;
|
||||
</script>
|
||||
<div class="move select-none" class:latest on:mouseover on:mouseout>
|
||||
|
||||
<div class="move select-none" class:latest on:mouseover on:mouseout on:focus on:blur>
|
||||
<span class="player player-{player}">
|
||||
{#if player == 1}
|
||||
<svg width="16" height="16">
|
||||
|
|
@ -46,6 +47,9 @@
|
|||
.latest {
|
||||
@apply opacity-35;
|
||||
}
|
||||
:global(.dark) .latest {
|
||||
@apply opacity-50;
|
||||
}
|
||||
.player {
|
||||
@apply inline-block w-1em h-1em;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<a href="/" class="arrow-back fixed top-0 left-0 w-4 h-4 m-4 p-2 transform transition-transform hover:-translate-x-1">
|
||||
<a href="/" class="text-black dark:text-white arrow-back fixed top-0 left-0 w-4 h-4 m-4 p-2 transform transition-transform hover:-translate-x-1">
|
||||
<svg width="16" height="16">
|
||||
<line y1="50%" x1="0" y2="50%" x2="100%" stroke="currentColor" stroke-width="2" />
|
||||
<line y1="50%" x1="0" y2="100%" x2="50%" stroke="currentColor" stroke-width="2" />
|
||||
|
|
@ -43,9 +43,6 @@
|
|||
{/if}
|
||||
|
||||
<style>
|
||||
a {
|
||||
@apply text-black;
|
||||
}
|
||||
* {
|
||||
@apply box-border;
|
||||
}
|
||||
|
|
@ -61,8 +58,17 @@
|
|||
input {
|
||||
@apply w-64 h-10 px-2 border border-gray-300 rounded-l-lg mt-4 my-0;
|
||||
}
|
||||
:global(.dark) input {
|
||||
@apply border-gray-400 text-white bg-black;
|
||||
}
|
||||
button {
|
||||
@apply w-64 h-10 px-2 border border-gray-300 bg-white rounded-r-lg mt-4 my-0;
|
||||
@apply w-64 h-10 px-2 border border-gray-300 bg-white rounded-r-lg mt-4 my-0 cursor-pointer;
|
||||
}
|
||||
:global(.dark) button {
|
||||
@apply bg-white/5 border-gray-700 text-white;
|
||||
}
|
||||
:global(.dark) button:hover {
|
||||
@apply bg-white/10;
|
||||
}
|
||||
form {
|
||||
@apply h-50vh flex-grow-0;
|
||||
|
|
|
|||
22
client/src/lib/themeStore.ts
Normal file
22
client/src/lib/themeStore.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { writable } from 'svelte/store';
|
||||
|
||||
let theme = "light";
|
||||
if(typeof window !== 'undefined') {
|
||||
theme = localStorage.getItem('theme')!;
|
||||
if(!theme && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
theme = "dark"
|
||||
} else if(!theme) {
|
||||
theme = "light"
|
||||
}
|
||||
}
|
||||
|
||||
export const themeStore = writable(theme);
|
||||
|
||||
let firstRun = true;
|
||||
themeStore.subscribe(value => {
|
||||
if(firstRun) {
|
||||
firstRun = false;
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('theme', value);
|
||||
});
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
const duration = 400;
|
||||
</script>
|
||||
|
||||
<a on:click={() => { $connection?.leave() }} href="/multiplayer" class="arrow-back fixed top-0 left-0 w-4 h-4 m-4 p-2 transform transition-transform hover:-translate-x-1">
|
||||
<a on:click={() => { $connection?.leave() }} href="/multiplayer" class="text-black dark:text-white arrow-back fixed top-0 left-0 w-4 h-4 m-4 p-2 transform transition-transform hover:-translate-x-1">
|
||||
<svg width="16" height="16">
|
||||
<line y1="50%" x1="0" y2="50%" x2="100%" stroke="currentColor" stroke-width="2" />
|
||||
<line y1="50%" x1="0" y2="100%" x2="50%" stroke="currentColor" stroke-width="2" />
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<main>
|
||||
<h1 in:fly={{ delay: 0, duration, opacity: 0, y: 100, easing: quadOut }}>Waiting for an opponent...</h1>
|
||||
<p in:fly={{ delay: duration * 0.5, duration, opacity: 0, y: 100, easing: quadOut }}>Currently in room <code>{$room?.name}</code>.</p>
|
||||
<p in:fly={{ delay: duration * 0.5, duration, opacity: 0, y: 100, easing: quadOut }}>Currently in room <code class="text-dark dark:text-white">{$room?.name}</code>.</p>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
|
|
@ -26,10 +26,4 @@
|
|||
p {
|
||||
@apply text-gray-400;
|
||||
}
|
||||
a {
|
||||
@apply text-black;
|
||||
}
|
||||
code {
|
||||
@apply text-black;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,13 +1,21 @@
|
|||
<script lang="ts">
|
||||
import PageTransition from "$lib/pageTransition.svelte";
|
||||
import { themeStore } from "$lib/themeStore";
|
||||
import "uno.css";
|
||||
|
||||
import type { load } from "./+layout";
|
||||
export let data: Awaited<ReturnType<typeof load>>;
|
||||
|
||||
$: if(typeof window !== "undefined") {
|
||||
if($themeStore == "dark") {
|
||||
document.documentElement.classList.add("dark");
|
||||
} else {
|
||||
document.documentElement.classList.remove("dark");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="overflow-hidden w-100vw">
|
||||
<div class="overflow-hidden w-100vw h-100vh dark:bg-black dark:text-white">
|
||||
<PageTransition url={data.url}>
|
||||
<slot />
|
||||
</PageTransition>
|
||||
|
|
@ -17,4 +25,7 @@
|
|||
:global(:root), :global(body) {
|
||||
@apply overflow-hidden w-100vw;
|
||||
}
|
||||
:global(*) {
|
||||
@apply transition-colors;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import DarkmodeIcon from "$lib/DarkmodeIcon.svelte";
|
||||
import { themeStore } from "$lib/themeStore";
|
||||
import { onMount } from "svelte";
|
||||
import { quadOut } from "svelte/easing";
|
||||
import { fly } from "svelte/transition";
|
||||
|
||||
|
|
@ -10,6 +12,14 @@
|
|||
onMount(() => {
|
||||
shown = true;
|
||||
});
|
||||
|
||||
function toggleDarkmode() {
|
||||
if($themeStore == "dark") {
|
||||
$themeStore = "light";
|
||||
} else {
|
||||
$themeStore = "dark";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -22,19 +32,19 @@
|
|||
<a href="/localplay" class="single" in:fly={{ delay: 0, duration, opacity: 0, y: 100, easing: quadOut }}>
|
||||
<h1>Local multiplayer</h1>
|
||||
|
||||
<img src="/computer.svg" alt="">
|
||||
<div class="computer"></div>
|
||||
|
||||
<p>A game for two on a single device</p>
|
||||
</a>
|
||||
<a href="/multiplayer" class="multi" in:fly={{ delay: duration * 0.5, duration, opacity: 0, y: 100, easing: quadOut }}>
|
||||
<h1>Online multiplayer</h1>
|
||||
|
||||
<img src="/network.svg" alt="">
|
||||
<div class="multiplayer"></div>
|
||||
|
||||
<p>Play with 2 devices, even across the ocean.</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="rules" in:fly={{ delay: 0, duration, opacity: 0, y: 100, easing: quadOut }}>
|
||||
<div class="rules" in:fly={{ delay: duration, duration, opacity: 0, y: 100, easing: quadOut }}>
|
||||
<div class="icon">
|
||||
<svg fill="currentColor" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="800px" height="800px" viewBox="0 0 973.1 973.1" xml:space="preserve"
|
||||
|
|
@ -56,10 +66,43 @@
|
|||
<p>How do I play the game?</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="darkmode">
|
||||
<button on:click={toggleDarkmode} in:fly={{ delay: duration * 1.5, duration, opacity: 0, y: 100, easing: quadOut }}>
|
||||
<DarkmodeIcon />
|
||||
Toggle dark mode
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.computer {
|
||||
@apply w-full bg-black;
|
||||
aspect-ratio: 1/1;
|
||||
mask: url('/computer.svg') no-repeat center;
|
||||
-webkit-mask: url('/computer.svg') no-repeat center;
|
||||
}
|
||||
.multiplayer {
|
||||
@apply w-full bg-black;
|
||||
aspect-ratio: 1/1;
|
||||
mask: url('/network.svg') no-repeat center;
|
||||
-webkit-mask: url('/network.svg') no-repeat center;
|
||||
}
|
||||
:global(.dark) .computer, :global(.dark) .multiplayer {
|
||||
@apply bg-white;
|
||||
}
|
||||
button {
|
||||
@apply p-4 rounded-lg bg-transparent border-none cursor-pointer flex items-center justify-center gap-4;
|
||||
}
|
||||
button:hover {
|
||||
@apply bg-black/10;
|
||||
}
|
||||
:global(.dark) button {
|
||||
@apply text-white;
|
||||
}
|
||||
:global(.dark) button:hover {
|
||||
@apply bg-white/10;
|
||||
}
|
||||
main {
|
||||
@apply my-4 p-4 w-max m-auto h-100vh;
|
||||
}
|
||||
|
|
@ -69,9 +112,15 @@
|
|||
.chooser > a {
|
||||
@apply text-black no-underline cursor-pointer w-full p-8 border rounded-lg border-gray-400 border-solid;
|
||||
}
|
||||
:global(.dark) .chooser > a {
|
||||
@apply text-white;
|
||||
}
|
||||
.chooser > a:hover {
|
||||
@apply bg-black/10;
|
||||
}
|
||||
:global(.dark) .chooser > a:hover {
|
||||
@apply bg-white/10;
|
||||
}
|
||||
.rules {
|
||||
@apply cursor-not-allowed text-gray-500 flex justify-center items-center w-full my-8 p-4 border rounded-lg border-gray-400 border-solid;
|
||||
}
|
||||
|
|
|
|||
1
client/static/darkmode.svg
Normal file
1
client/static/darkmode.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36c-0.98,1.37-2.58,2.26-4.4,2.26 c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg>
|
||||
|
After Width: | Height: | Size: 380 B |
1
client/static/lightmode.svg
Normal file
1
client/static/lightmode.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0 c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2 c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1 C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06 c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41 l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41 c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36 c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in a new issue