diff --git a/index.html b/index.html index 4c5e4f6..5312e4b 100644 --- a/index.html +++ b/index.html @@ -11,13 +11,7 @@ /> <title>Tic Tac Toe</title> - <style> - @import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap"); - - @tailwind base; - @tailwind components; - @tailwind utilities; - </style> + <link rel="stylesheet" href="styles.css" /> </head> <body> <div id="root"></div> diff --git a/src/app.jsx b/src/app.jsx index cf51cc4..49e6232 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -8,7 +8,7 @@ export default () => { const players = useStore((state) => state.players); return ( - <main className="flex min-h-screen items-center justify-center bg-navy-700"> + <main className="center min-h-screen bg-navy-700"> {isGameRunning ? <Game players={players} key={gameKey} /> : <MainMenu />} </main> ); diff --git a/src/game.jsx b/src/game.jsx index 7069fde..2a3bc57 100644 --- a/src/game.jsx +++ b/src/game.jsx @@ -103,13 +103,13 @@ export default ({ players }) => { const boxBackground = (index) => { if (winner && winningCombo.includes(index)) { if (winner == "X") { - return "bg-blue-400 inner-shadow-2-blue-900"; + return "bg-blue-400 inner-shadow-2-blue"; } else { - return "bg-yellow-400 inner-shadow-2-yellow-900"; + return "bg-yellow-400 inner-shadow-2-yellow"; } } - return "bg-navy-400 inner-shadow-2-navy-900"; + return "bg-navy-400 inner-shadow-2-navy"; }; return ( @@ -119,7 +119,7 @@ export default ({ players }) => { <div className="flex-1"> <img src={logo} alt="logo" /> </div> - <div className="h-14 w-36 rounded-xl bg-navy-400 px-8 py-4 inner-shadow-1-navy-900"> + <div className="inner-shadow-1-navy h-14 w-36 rounded-xl bg-navy-400 px-8 py-4"> <div className="flex items-center justify-between text-silver-700"> <TurnIndicator className="size-5" /> <p className="text-h-xs uppercase">Turn</p> @@ -128,7 +128,7 @@ export default ({ players }) => { <div className="flex-1"> <button onClick={() => setRestartModal(true)} - className="ml-auto flex size-14 items-center justify-center rounded-xl bg-silver-700 inner-shadow-1-silver-900 hover:bg-silver-400" + className="center inner-shadow-1-silver ml-auto size-14 rounded-xl bg-silver-700 hover:bg-silver-400" > <img src={restart} alt="restart" /> </button> @@ -140,7 +140,7 @@ export default ({ players }) => { <button key={index} disabled={symbol != "" || winner || cpuTurn} - className={`group flex size-36 items-center justify-center rounded-2xl ${boxBackground(index)}`} + className={`center group size-36 rounded-2xl ${boxBackground(index)}`} onClick={() => { updateGrid((grid) => { grid[index] = turn; @@ -152,16 +152,16 @@ export default ({ players }) => { ))} </main> - <footer className="flex items-center justify-between text-navy-700"> - <div className="flex h-20 w-36 flex-col items-center justify-center rounded-2xl bg-blue-700"> + <footer className="center flex-row justify-between text-navy-700"> + <div className="center h-20 w-36 rounded-2xl bg-blue-700"> <p className="text-base uppercase">X ({players.X})</p> <p className="text-h-m uppercase">{score.X}</p> </div> - <div className="flex h-20 w-36 flex-col items-center justify-center rounded-2xl bg-silver-700"> + <div className="center h-20 w-36 rounded-2xl bg-silver-700"> <p className="text-base uppercase">Ties</p> <p className="text-h-m uppercase">{score.ties}</p> </div> - <div className="flex h-20 w-36 flex-col items-center justify-center rounded-2xl bg-yellow-700"> + <div className="center h-20 w-36 rounded-2xl bg-yellow-700"> <p className="text-base uppercase">O ({players.O})</p> <p className="text-h-m uppercase">{score.O}</p> </div> @@ -176,15 +176,15 @@ export default ({ players }) => { > <h2 className="text-h-l uppercase text-silver-700">Restart game?</h2> <form - className="flex items-center justify-around text-navy-700" + className="center flex-row justify-around text-navy-700" method="dialog" > - <button className="rounded-xl bg-silver-700 px-5 py-4 inner-shadow-1-silver-900 hover:bg-silver-400"> + <button className="inner-shadow-1-silver rounded-xl bg-silver-700 px-5 py-4 hover:bg-silver-400"> <p className="text-h-xs uppercase">No, cancel</p> </button> <button onClick={restartGame} - className="rounded-xl bg-yellow-700 px-5 py-4 inner-shadow-1-yellow-900 hover:bg-yellow-400" + className="inner-shadow-1-yellow rounded-xl bg-yellow-700 px-5 py-4 hover:bg-yellow-400" > <p className="text-h-xs uppercase">Yes, restart</p> </button> diff --git a/src/mainMenu.jsx b/src/mainMenu.jsx index f633e18..e150b34 100644 --- a/src/mainMenu.jsx +++ b/src/mainMenu.jsx @@ -21,9 +21,9 @@ export default () => { }; return ( - <div className="m-6 flex w-full max-w-lg flex-col items-center space-y-10"> + <div className="center m-6 w-full max-w-lg space-y-10"> <img src={logo} alt="logo" /> - <div className="flex w-full flex-col items-center justify-center rounded-2xl bg-navy-400 p-6 inner-shadow-2-navy-900"> + <div className="center inner-shadow-2-navy w-full rounded-2xl bg-navy-400 p-6"> <h2 className="mb-6 text-h-xs uppercase text-silver-700"> Pick player 1's mark </h2> @@ -57,13 +57,13 @@ export default () => { <div className="w-full space-y-5"> <button onClick={() => startGame("CPU")} - className="flex w-full items-center justify-center rounded-2xl bg-yellow-700 p-4 inner-shadow-2-yellow-900 hover:bg-yellow-400" + className="center inner-shadow-2-yellow w-full rounded-2xl bg-yellow-700 p-4 hover:bg-yellow-400" > <p className="text-h-s uppercase text-navy-700">New game (vs cpu)</p> </button> <button onClick={() => startGame("P2")} - className="flex w-full items-center justify-center rounded-2xl bg-blue-700 p-4 inner-shadow-2-blue-900 hover:bg-blue-400" + className="center inner-shadow-2-blue w-full rounded-2xl bg-blue-700 p-4 hover:bg-blue-400" > <p className="text-h-s uppercase text-navy-700"> New game (vs player) diff --git a/src/modal.jsx b/src/modal.jsx index 02c1935..62857d9 100644 --- a/src/modal.jsx +++ b/src/modal.jsx @@ -20,7 +20,7 @@ export default ({ isOpen, children, className, onClose }) => { className="h-64 w-screen max-w-[100vw] bg-navy-700 backdrop:bg-black/50" ref={ref} > - <div className="flex h-full w-full items-center justify-center"> + <div className="center h-full w-full"> <div className={className}>{children}</div> </div> </dialog> diff --git a/src/store.jsx b/src/store.jsx index e0b51d2..11b791f 100644 --- a/src/store.jsx +++ b/src/store.jsx @@ -1,4 +1,3 @@ -import { produce } from "immer"; import { create } from "zustand"; export const useStore = create((set) => ({ diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..dc25497 --- /dev/null +++ b/styles.css @@ -0,0 +1,14 @@ +@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap"); + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer components { + .center { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } +} diff --git a/tailwind.config.js b/tailwind.config.js index c97370f..aff0558 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,31 +1,29 @@ import plugin from "tailwindcss/plugin"; const innerShadowPlugin = plugin(function ({ addUtilities, theme, e }) { - const colors = Object.keys(theme("colors")) - .filter((key) => key.endsWith("-900")) - .reduce((obj, key) => { - obj[key] = theme("colors")[key]; - return obj; - }, {}); - const spacing = { 1: "0.25rem", 2: "0.5rem", }; - const utilities = Object.keys(colors).flatMap((colorKey) => { + const utilities = {}; + + const colors = theme("colors"); + for (const colorKey in colors) { + if (typeof colors[colorKey] != "object") { + continue; + } + const colorValue = colors[colorKey]; + const color = colorValue["900"]; - return Object.keys(spacing).map((spacingKey) => { + for (const spacingKey in spacing) { const spacingValue = spacing[spacingKey]; - - return { - [`.${e(`inner-shadow-${spacingKey}-${colorKey}`)}`]: { - "box-shadow": `inset 0 -${spacingValue} ${colorValue}`, - }, + utilities[`.${e(`inner-shadow-${spacingKey}-${colorKey}`)}`] = { + "box-shadow": `inset 0 -${spacingValue} ${color}`, }; - }); - }); + } + } addUtilities(utilities); }); @@ -34,19 +32,27 @@ export default { content: ["./index.html", "./src/**/*.jsx"], theme: { colors: { - "navy-900": "#10212A", - "navy-700": "#1A2A33", - "navy-400": "#1F3641", - "silver-900": "#6B8997", - "silver-700": "#A8BFC9", - "silver-400": "#DBE8ED", - "blue-900": "#118C87", - "blue-700": "#31C3BD", - "blue-400": "#65E9E4", - "yellow-900": "#CC8B13", - "yellow-700": "#F2B137", - "yellow-400": "#FFC860", black: "#000", + navy: { + 400: "#1F3641", + 700: "#1A2A33", + 900: "#10212A", + }, + silver: { + 400: "#DBE8ED", + 700: "#A8BFC9", + 900: "#6B8997", + }, + blue: { + 400: "#65E9E4", + 700: "#31C3BD", + 900: "#118C87", + }, + yellow: { + 400: "#FFC860", + 700: "#F2B137", + 900: "#CC8B13", + }, }, fontFamily: { sans: ["Outfit", "sans-serif"],