diff --git a/src/lib/config.js b/src/lib/config.js
index 006b120..2089f8d 100644
--- a/src/lib/config.js
+++ b/src/lib/config.js
@@ -59,20 +59,28 @@ export let AnswersSymbolAndColorScheme = [
export let DefaultQuestions = [
{
- name: "What should you do when you're free?",
- answers: ["Do something in real life!", "Play video games", "Code!", "Touch grass!"],
- correctAnswer: 2,
- timeLimit: 30,
+ questionText: "What should you do when you're free?",
+ timeLimit: 15,
+ type: "SingleAnswer",
+ options: ["Do something in real life!", "Play video games", "Code!", "Touch grass!"],
+ CorrectOption: { SingleAnswer: 2 },
+ hasMedia: false,
+ mediaURL: null,
},
{
- name: "Is RezHackXYZ the best programmer in the world?",
- answers: ["Yes :)", "No :("],
- correctAnswer: 0,
+ questionText: "Is RezHackXYZ the best programmer in the world?",
timeLimit: 5,
+ type: "SingleAnswer",
+ options: ["Yes :)", "No :("],
+ CorrectOption: { SingleAnswer: 0 },
+ hasMedia: true,
+ mediaURL: "https://github.com/RezHackXYZ.png",
},
{
- name: "Best place in the world?",
- answers: [
+ questionText: "Best place in the world?",
+ timeLimit: 5,
+ type: "SingleAnswer",
+ options: [
"Google",
"Microsoft",
"Apple",
@@ -82,55 +90,8 @@ export let DefaultQuestions = [
"Facebook",
"Twitter",
],
- correctAnswer: 4,
- timeLimit: 120,
+ CorrectOption: { SingleAnswer: 4 },
+ hasMedia: false,
+ mediaURL: null,
},
];
-
-export let AiPrompts = {
- GenerateQuestionsUsingAI: `
-You are the AI of a quiz game.
-Generate a list of quiz questions with possible answers and the correct answer index.
-Each question must have:
-- A "name" (question text)
-- An "answers" array (minimum 2, maximum 8 options)
-- A "correctAnswer" (index starting from 0)
-Ensure the questions are diverse.
-Example format:
-{
-"name": "What is the capital of France?",
-"answers": [
- "Paris",
- "London",
- "Berlin",
- "Madrid"
-],
-"correctAnswer": 0
-}
-JUST PROVIDE THE JSON AND NOTHING ELSE.
-
-The user's topic of interest is:
-[topic]`,
- GenerateOptionsUsingAI: `
-You are the AI of a quiz game.
-Generate a list of answers relevant to the Question the correct answer index.
-generate 2 things for the question:
-- An "answers" array (minimum 2, maximum 8 options)
-- A "correctAnswer" (index starting from 0)
-Ensure the questions are diverse.
-Example format if the question is "What is the capital of France?":
-{
-"answers": [
- "Paris",
- "London",
- "Berlin",
- "Madrid"
-],
-"correctAnswer": 0
-}
-JUST PROVIDE THE JSON AND NOTHING ELSE.
-
-The user's Question that they want to generate options for is:
-[question]
-`,
-};
diff --git a/src/lib/showAlert.js b/src/lib/showAlert.js
deleted file mode 100644
index 957e3d4..0000000
--- a/src/lib/showAlert.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import JSConfetti from "js-confetti";
-const jsConfetti = new JSConfetti();
diff --git a/src/routes/kahootclone/create/+page.svelte b/src/routes/kahootclone/create/+page.svelte
index 06798db..d932189 100644
--- a/src/routes/kahootclone/create/+page.svelte
+++ b/src/routes/kahootclone/create/+page.svelte
@@ -1,28 +1,12 @@
-
-
-
- {#each questions.v as question, index}
-
- {/each}
-
-
- {#if Wait.v == false}
-
- {:else}
-
- {/if}
-
-
-
+
\ No newline at end of file
diff --git a/src/routes/kahootclone/create/Buttons.svelte b/src/routes/kahootclone/create/Buttons.svelte
new file mode 100644
index 0000000..bd66d33
--- /dev/null
+++ b/src/routes/kahootclone/create/Buttons.svelte
@@ -0,0 +1,99 @@
+
+
+
+ (QuestionsData.v = DefaultQuestions)}>
+ Use Demo Questions
+
+ GenerateQuestionsUsingAI()}>
+ Generate Questions Using AI
+
+ {#if wait.v == true}
+
+ Creating Game
+
+ {:else}
+ createGame()}>
+ Start Game
+
+ {/if}
+
diff --git a/src/routes/kahootclone/create/HowTheQuestionWillLook.svelte b/src/routes/kahootclone/create/HowTheQuestionWillLook.svelte
new file mode 100644
index 0000000..46907c7
--- /dev/null
+++ b/src/routes/kahootclone/create/HowTheQuestionWillLook.svelte
@@ -0,0 +1,57 @@
+
+
+
+
How Question number {selectedQuestionIndex.v + 1} will look
+
+
+
+
+ {selectedQuestionIndex.v + 1}.
+ {QuestionsData.v[selectedQuestionIndex.v].questionText}
+
+ {#if QuestionsData.v[selectedQuestionIndex.v].mediaURL && QuestionsData.v[selectedQuestionIndex.v].hasMedia}
+
+
+ {#if QuestionsData.v[selectedQuestionIndex.v].mediaURL.match(/\.(mp4|webm|ogg|mov|avi|mkv)$/i)}
+
+
+ {:else}
+
{/if}
+
+
+ {/if}
+
+ {#each QuestionsData.v[selectedQuestionIndex.v].options as question, questionIndex}
+
+
+
+ {question}
+
+
+ {/each}
+
+
+
+
diff --git a/src/routes/kahootclone/create/QuestionOptions.svelte b/src/routes/kahootclone/create/QuestionOptions.svelte
new file mode 100644
index 0000000..046c07e
--- /dev/null
+++ b/src/routes/kahootclone/create/QuestionOptions.svelte
@@ -0,0 +1,183 @@
+
+
+
+
+
Options
+
+
+ What the Question?
+
+
+
+
+ Time limit?
+
+ infinite
+ 5 sec
+ 10 sec
+ 15 sec
+ 30 sec
+ 1 min
+ 2 min
+ 5 min
+
+
+
+
+ Question type?
+
+ Single Answer
+
+
+
+
+ Add Some Media?
+
+
+ {#if QuestionsData.v[selectedQuestionIndex.v].hasMedia}
+ {
+ QuestionsData.v[selectedQuestionIndex.v].mediaURL = await UpLoadFiles(files[0]);
+ }}
+ accept="image/*,video/*"
+ />
+
+ {QuestionsData.v[selectedQuestionIndex.v].mediaURL
+ ? "choose different file"
+ : "upload files"}
+
+ {
+ QuestionsData.v[selectedQuestionIndex.v].mediaURL = await UpLoadFiles(files[0]);
+ }}
+ accept="image/*,video/*"
+ />
+ {/if}
+
+
+
+ {#if "SingleAnswer" === "SingleAnswer"}
+
Options
+ {#each QuestionsData.v[selectedQuestionIndex.v].options as Option, index}
+
+ {/each}
+
+ {
+ if (QuestionsData.v[selectedQuestionIndex.v].options.length >= 8) {
+ toast.error("You can only have a max of 8 options");
+ } else {
+ QuestionsData.v[selectedQuestionIndex.v].options.push("");
+ }
+ }}>Add Option
+
+ {/if}
+
+
+
+
+ Danger
+ {
+ if (QuestionsData.v.length <= 1) {
+ toast.error("You need to have at least 1 question");
+ } else if (confirm("Are you sure you want to delete this question?")) {
+ QuestionsData.v.splice(selectedQuestionIndex.v, 1);
+ selectedQuestionIndex.v = Math.max(0, selectedQuestionIndex.v - 1);
+ toast.success("Question deleted successfully");
+ }
+ }}>delete this question
+
+
+
diff --git a/src/routes/kahootclone/create/QuestionsList.svelte b/src/routes/kahootclone/create/QuestionsList.svelte
new file mode 100644
index 0000000..5a9102b
--- /dev/null
+++ b/src/routes/kahootclone/create/QuestionsList.svelte
@@ -0,0 +1,31 @@
+
+
+
+
Questions
+ {#each QuestionsData.v as question, questionIndex}
+
(selectedQuestionIndex.v = questionIndex)}
+ >
+ {questionIndex + 1}. {question.questionText}
+
+ {/each}
+
+ {
+ QuestionsData.v.push({
+ questionText: "",
+ timeLimit: 15,
+ type: "SingleAnswer",
+ options: ["", "", "", ""],
+ CorrectOption: { SingleAnswer:null},
+ hasMedia: false,
+ mediaURL: null,
+ });
+ }}> New Question
+
+
diff --git a/src/routes/kahootclone/create/components/Questions/answers.svelte b/src/routes/kahootclone/create/components/Questions/answers.svelte
deleted file mode 100644
index dd8002e..0000000
--- a/src/routes/kahootclone/create/components/Questions/answers.svelte
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/routes/kahootclone/create/components/Questions/question.svelte b/src/routes/kahootclone/create/components/Questions/question.svelte
deleted file mode 100644
index e739168..0000000
--- a/src/routes/kahootclone/create/components/Questions/question.svelte
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
-
Q{index + 1}.
-
- {
- const newLength = questions.v[index].answers.length;
- const currentAnswers = questions.v[index].answers;
-
- if (newLength > currentAnswers.length) {
- // Add more answers
- while (questions.v[index].answers.length < newLength) {
- questions.v[index].answers.push("");
- }
- } else if (newLength < currentAnswers.length) {
- // Remove excess answers
- questions.v[index].answers = currentAnswers.slice(0, newLength);
- }
- }}
- class="h-fit rounded-xl bg-gray-800 p-1 text-center text-white"
- >
- Options
- {#each Array(7) as _, i}
- {i + 2}
- {/each}
-
-
- Time Limit
- infinite
- 5 sec
- 10 sec
- 15 sec
- 30 sec
- 1 min
- 2 min
- 5 min
-
-
-
-
-
- {#each questions.v[index].answers as _, answersIndex}
-
- {/each}
-
-
-
{
- questions.v[index].media = await UpLoadFiles(files[0]);
- }}
- bind:files
- accept="image/*,video/*"
- />
-
-
diff --git a/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte b/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte
deleted file mode 100644
index 7057ea9..0000000
--- a/src/routes/kahootclone/create/components/buttons/DeleteQuestion.svelte
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- DeleteQuestion(props.index)}
- class="flex h-fit cursor-pointer items-center justify-center rounded-xl bg-red-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
- > Delete question
diff --git a/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte b/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte
deleted file mode 100644
index b657a8c..0000000
--- a/src/routes/kahootclone/create/components/buttons/GenerateOptionsUsingAI.svelte
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-{#if questions.v[index].answers.every((answer) => answer === "")}
- {
- GenerateOptionsUsingAI(index);
- }}
- class="mt-1 mb-1 flex h-fit cursor-pointer items-center justify-center gap-2 rounded-xl bg-blue-700 p-2 transition-all hover:scale-110 hover:-rotate-5"
- >
-
- Generate Options using AI
-
-{/if}
diff --git a/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte b/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte
deleted file mode 100644
index 8932152..0000000
--- a/src/routes/kahootclone/create/components/buttons/GenerateQuetionsUsingAI.svelte
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-{#if questions.v.length === 0 || (questions.v.length === 1 && questions.v[0].name === "" && questions.v[0].answers.every((answer) => answer === "") && questions.v[0].correctAnswer === undefined)}
-
-
- Generate questions using AI
-
-{/if}
diff --git a/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte b/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte
deleted file mode 100644
index 63cc2d6..0000000
--- a/src/routes/kahootclone/create/components/buttons/NewQuestion.svelte
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- AddQuestion()}
- class="flex h-fit cursor-pointer items-center justify-center rounded-xl bg-green-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
- > New question
diff --git a/src/routes/kahootclone/create/components/buttons/StartGame.svelte b/src/routes/kahootclone/create/components/buttons/StartGame.svelte
deleted file mode 100644
index 10f8d3a..0000000
--- a/src/routes/kahootclone/create/components/buttons/StartGame.svelte
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Start Quiz
diff --git a/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte b/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte
deleted file mode 100644
index ead81cd..0000000
--- a/src/routes/kahootclone/create/components/buttons/UseDemoQuestions.svelte
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- SetQuestionsToDemoQuestions()}
- class="-mt-5 mb-3 flex h-fit cursor-pointer items-center justify-center rounded-xl bg-green-700 p-2 transition-all hover:scale-110 hover:-rotate-10"
- > Use demo questions
diff --git a/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte b/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte
deleted file mode 100644
index 0102b86..0000000
--- a/src/routes/kahootclone/create/components/buttons/WaitStartGame.svelte
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- Wait for game to be created
diff --git a/src/routes/kahootclone/create/create.svelte.js b/src/routes/kahootclone/create/create.svelte.js
new file mode 100644
index 0000000..53eed4a
--- /dev/null
+++ b/src/routes/kahootclone/create/create.svelte.js
@@ -0,0 +1,15 @@
+export let selectedQuestionIndex = $state({ v: 0 });
+export let QuestionsData = $state({
+ v: [
+ {
+ questionText: "",
+ timeLimit: 15,
+ type: "SingleAnswer",
+ options: ["", "", "", ""],
+ CorrectOption: { SingleAnswer: null },
+ hasMedia: false,
+ mediaURL: null
+ },
+ ],
+});
+export let wait = $state({ v: false });
\ No newline at end of file
diff --git a/src/routes/kahootclone/create/logic/InsertGameInDB.js b/src/routes/kahootclone/create/createGame.js
similarity index 72%
rename from src/routes/kahootclone/create/logic/InsertGameInDB.js
rename to src/routes/kahootclone/create/createGame.js
index 8d4e525..38a466c 100644
--- a/src/routes/kahootclone/create/logic/InsertGameInDB.js
+++ b/src/routes/kahootclone/create/createGame.js
@@ -1,9 +1,24 @@
-import { supabase } from "$lib/supabase";
+import { supabase } from "$lib/supabase.js";
+import { QuestionsData, wait } from "./create.svelte.js";
import toast from "svelte-5-french-toast";
-import { Wait } from "./GameCreateData.svelte.js";
-export async function createGame(questions, gamePin) {
- // Insert game
+export async function createGame() {
+ if (wait.v) {
+ return;
+ }
+ wait.v = true;
+ const gamePin = Math.floor(Math.random() * 1000000)
+ .toString()
+ .padStart(6, "0");
+
+ const questionsData = QuestionsData.v.map((q) => ({
+ gameid: gamePin,
+ questionstext: q.questionText,
+ correctanswer: q.CorrectOption.SingleAnswer,
+ timeLimit: q.timelimit,
+ media: q.hasMedia ? q.mediaURL : null,
+ }));
+
const insertGamePromise = supabase.from("games").insert({
creator: "anonymous",
creationdate: new Date().toISOString(),
@@ -19,19 +34,10 @@ export async function createGame(questions, gamePin) {
});
if (gameError) {
- Wait.v = false;
+ wait.v = false;
return;
}
- // Prepare questions and answers for batch insertion
- const questionsData = questions.map((q) => ({
- gameid: gamePin,
- questionstext: q.name,
- correctanswer: q.correctAnswer,
- timelimit: q.timeLimit,
- media: q.media || null,
- }));
-
const insertQuestionsPromise = supabase.from("questions").insert(questionsData).select("id");
const { data: questionsResult, error: questionsError } = await toast.promise(
@@ -47,14 +53,13 @@ export async function createGame(questions, gamePin) {
);
if (questionsError) {
- Wait.v = false;
-
+ wait.v = false;
return;
}
const answersData = [];
questionsResult.forEach((question, index) => {
- questions[index].answers.forEach((answer) => {
+ QuestionsData.v[index].options.forEach((answer) => {
answersData.push({
questionid: question.id,
content: answer,
@@ -72,9 +77,10 @@ export async function createGame(questions, gamePin) {
});
if (answersError) {
- Wait.v = false
+ wait.v = false;
return;
}
window.location.href = `/kahootclone/host?gamepin=${gamePin}`;
+ wait.v = false;
}
diff --git a/src/routes/kahootclone/create/logic/GameCreateData.svelte.js b/src/routes/kahootclone/create/logic/GameCreateData.svelte.js
deleted file mode 100644
index 33a6316..0000000
--- a/src/routes/kahootclone/create/logic/GameCreateData.svelte.js
+++ /dev/null
@@ -1,38 +0,0 @@
-
-import { DefaultQuestions } from "$lib/config.js";
-import toast from "svelte-5-french-toast";
-
-export let Wait = $state({ v: false });
-export let questions = $state({
- v: [
- {
- name: "",
- answers: ["", "", "", ""],
- correctAnswer: undefined,
- timeLimit: 30,
- },
- ],
-});
-
-export function SetQuestionsToDemoQuestions() {
- questions.v = DefaultQuestions;
-}
-
-export function AddQuestion() {
- questions.v.push({
- name: "",
- answers: ["", "", "", ""],
- correctAnswer: undefined,
- timeLimit: 30,
- });
-}
-
-export function DeleteQuestion(index) {
- if (questions.v.length > 1) {
- if (confirm("Are you sure you want to delete this question? You cant undo this.")) {
- questions.v.splice(index, 1);
- }
- } else {
- toast.error("You need at least one question.");
- }
-}
diff --git a/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js b/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js
deleted file mode 100644
index 175c8d3..0000000
--- a/src/routes/kahootclone/create/logic/GenerateOptionsUsingAI.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import { questions } from "./GameCreateData.svelte.js";
-import { AiPrompts } from "$lib/config.js";
-import toast from "svelte-5-french-toast";
-
-export function GenerateOptionsUsingAI(index) {
- if (!questions.v[index].name) {
- toast.error("Please enter a question to generate options.");
- return;
- }
-
- const fetchOptions = async () => {
- const response = await fetch("https://ai.hackclub.com/chat/completions", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- messages: [
- {
- role: "user",
- content: AiPrompts.GenerateOptionsUsingAI.replace(
- "[question]",
- questions.v[index].name,
- ),
- },
- ],
- }),
- });
- const data = await response.json();
- let question = questions.v[index].name;
- questions.v[index] = JSON.parse(data.choices[0].message.content);
- questions.v[index].name = question;
- };
-
- toast.promise(
- fetchOptions(),
- {
- loading: "Generating options...",
- success: "Options generated!",
- error: (err) => "Error: " + (err?.message || err),
- }
- );
-}
diff --git a/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js b/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js
deleted file mode 100644
index 7c369f9..0000000
--- a/src/routes/kahootclone/create/logic/GenerateQuestionsUsingAI.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { questions } from "./GameCreateData.svelte.js";
-import { AiPrompts } from "$lib/config.js";
-import toast from "svelte-5-french-toast";
-
-export function GenerateQuestionsUsingAI() {
- let topic = window.prompt(
- "What is the topic of the questions?\nand the number of questions in the topic?",
- );
-
- if (!topic) {
- return;
- }
-
- const fetchQuestions = async () => {
- const response = await fetch("https://ai.hackclub.com/chat/completions", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- messages: [
- {
- role: "user",
- content: AiPrompts.GenerateQuestionsUsingAI.replace("[topic]", topic),
- },
- ],
- }),
- });
- const data = await response.json();
- questions.v = JSON.parse(data.choices[0].message.content);
- };
-
- toast.promise(
- fetchQuestions(),
- {
- loading: "Generating questions...",
- success: "Questions added!",
- error: (err) => "Error: " + err.message || err,
- }
- );
-}
\ No newline at end of file
diff --git a/src/routes/kahootclone/create/logic/StartGame.js b/src/routes/kahootclone/create/logic/StartGame.js
deleted file mode 100644
index 6060fac..0000000
--- a/src/routes/kahootclone/create/logic/StartGame.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { createGame } from "./InsertGameInDB.js";
-import { questions,Wait } from "./GameCreateData.svelte.js";
-import toast from "svelte-5-french-toast";
-
-export async function startGame() {
- if (questions.v.some((q) => q.name === "")) return toast.error("Please fill all questions");
- if (questions.v.some((q) => q.answers.some((a) => a === ""))) return toast.error("Fill all options");
- if (questions.v.some((q) => q.correctAnswer === undefined))
- return toast.error("Select correct answers");
-
- const gamePin = Math.floor(Math.random() * 1000000)
- .toString()
- .padStart(6, "0");
-
- Wait.v = true;
-
- await createGame(questions.v, gamePin);}
diff --git a/src/routes/kahootclone/create/logic/UpLoadFiles.js b/src/routes/kahootclone/create/logic/UpLoadFiles.js
deleted file mode 100644
index 254d180..0000000
--- a/src/routes/kahootclone/create/logic/UpLoadFiles.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import toast from "svelte-5-french-toast";
-import { supabase } from "$lib/supabase.js";
-
-export async function UpLoadFiles(file) {
- if (!file) {
- toast.error("Please select a file to upload first.");
- return;
- }
-
- const fileExt = file.name.split(".").pop();
- const fileName = `${Date.now()}.${fileExt}`;
- const filePath = `${fileName}`;
-
- const uploadPromise = supabase.storage.from("useruploadedcontent").upload(filePath, file);
-
- const result = await toast.promise(uploadPromise, {
- loading: "Uploading...",
- success: "Upload successful!",
- error: (error) => `Upload failed. ${error.message} Please try again.`,
- });
-
- if (result.error) {
- toast.error("Upload error:"+ result.error.message);
- return;
- }
-
- // Retrieve public URL
- const { data: publicData } = supabase.storage.from("useruploadedcontent").getPublicUrl(filePath);
-
- return publicData.publicUrl;
-}
diff --git a/src/routes/tailwind.css b/src/routes/tailwind.css
index f745326..3192c45 100644
--- a/src/routes/tailwind.css
+++ b/src/routes/tailwind.css
@@ -1,34 +1,39 @@
@import "https://www.nerdfonts.com/assets/css/webfont.css";
@import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@300..700&family=JetBrains+Mono:wght@200&family=Sour+Gummy:wght@300&display=swap");
+@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300&display=swap");
@import "tailwindcss";
:root {
- @apply bg-gray-950 font-[Sour_Gummy] text-white;
+ @apply bg-gray-950 font-[Space_Grotesk] text-white;
}
.btn {
- @apply flex cursor-pointer items-center gap-1 rounded border-2 border-white bg-gray-600 px-4 py-2 font-bold text-white transition-all hover:scale-105 hover:bg-gray-500 hover:shadow-lg;
-
- &.compact {
- @apply px-1 py-0.5;
- }
-
- &.circular {
- @apply rounded-full;
- &.compact {
- @apply px-0.75 py-0.75;
- }
- }
+ @apply flex cursor-pointer items-center gap-1 rounded border-2 border-white bg-gray-700 px-4 py-2 font-bold text-white transition-all hover:scale-105 hover:bg-gray-500 hover:shadow-lg;
&.dull {
@apply border-gray-700 bg-transparent text-gray-700 hover:bg-gray-700 hover:text-white;
}
+ &.slim {
+ @apply px-1 py-3;
+ }
+
&.green {
@apply bg-green-600 hover:bg-green-500;
}
+ &.red {
+ @apply bg-red-600 hover:bg-red-500;
+ }
}
.card {
@apply cursor-pointer rounded border-2 border-gray-700 bg-gray-800 p-4 shadow-[4px_4px_0px_0px_white] transition-all hover:-translate-0.5 hover:shadow-[6px_6px_0px_0px_white] active:translate-0.5 active:shadow-[2px_2px_0px_0px_white];
}
+
+.input {
+ @apply w-full rounded border-2 border-gray-700 bg-gray-800 px-4 py-2 text-white transition-all placeholder:text-gray-500 focus:border-white focus:outline-none;
+}
+
+.ratio {
+ @apply h-6 w-6;
+}