finished?
diff --git a/src/commands/server/buttons.ts b/src/commands/server/buttons.ts
new file mode 100644
index 0000000..4a299b2
--- /dev/null
+++ b/src/commands/server/buttons.ts
@@ -0,0 +1,252 @@
+import { ActionRowBuilder, APIMessageComponentEmoji, ButtonBuilder, ButtonStyle, ChannelSelectMenuBuilder, ChannelType, CommandInteraction, MessageCreateOptions, ModalBuilder, SlashCommandSubcommandBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, TextInputBuilder, TextInputStyle } from "discord.js";
+import type Discord from "discord.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import lodash from "lodash";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+import { modalInteractionCollector } from "../../utils/dualCollector.js";
+
+export const command = new SlashCommandSubcommandBuilder()
+    .setName("buttons")
+    .setDescription("Create clickable buttons for verifying, role menus etc.");
+
+interface Data {
+    buttons: string[],
+    title: string | null,
+    description: string | null,
+    color: number,
+    channel: string | null
+}
+
+const colors: Record<string, number> =  {
+    RED: 0xF27878,
+    ORANGE: 0xE5AB71,
+    YELLOW: 0xF2D478,
+    GREEN: 0x65CC76,
+    BLUE: 0x72AEF5,
+    PURPLE: 0xA358B2,
+    PINK: 0xD46899,
+    GRAY: 0x999999,
+}
+
+const buttonNames: Record<string, string> = {
+    verifybutton: "Verify",
+    rolemenu: "Role Menu",
+    createticket: "Ticket"
+}
+
+export const callback = async (interaction: CommandInteraction): Promise<void> => {
+
+    const m = await interaction.reply({
+        embeds: LoadingEmbed,
+        fetchReply: true,
+        ephemeral: true
+    });
+
+    let closed = false;
+    let data: Data = {
+        buttons: [],
+        title: null,
+        description: null,
+        color: colors["RED"]!,
+        channel: interaction.channelId
+    }
+    do {
+
+        const buttons = new ActionRowBuilder<ButtonBuilder>()
+            .addComponents(
+                new ButtonBuilder()
+                    .setCustomId("edit")
+                    .setLabel("Edit Embed")
+                    .setStyle(ButtonStyle.Secondary),
+                new ButtonBuilder()
+                    .setCustomId("send")
+                    .setLabel("Send")
+                    .setStyle(ButtonStyle.Primary)
+                    .setDisabled(!data.channel)
+            );
+
+        const colorSelect = new ActionRowBuilder<StringSelectMenuBuilder>()
+            .addComponents(
+                new StringSelectMenuBuilder()
+                    .setCustomId("color")
+                    .setPlaceholder("Select a color")
+                    .setMinValues(1)
+                    .addOptions(
+                        Object.keys(colors).map((color: string) => {
+                            return new StringSelectMenuOptionBuilder()
+                                .setLabel(lodash.capitalize(color))
+                                .setValue(color)
+                                .setEmoji(getEmojiByName("COLORS." + color, "id") as APIMessageComponentEmoji)
+                                .setDefault(data.color === colors[color])
+                            }
+                        )
+                    )
+            );
+
+        const buttonSelect = new ActionRowBuilder<StringSelectMenuBuilder>()
+            .addComponents(
+                new StringSelectMenuBuilder()
+                    .setCustomId("button")
+                    .setPlaceholder("Select buttons to add")
+                    .setMinValues(1)
+                    .setMaxValues(3)
+                    .addOptions(
+                        new StringSelectMenuOptionBuilder()
+                            .setLabel("Verify")
+                            .setValue("verifybutton")
+                            .setDescription("Click to get verified in the server")
+                            .setDefault(data.buttons.includes("verifybutton")),
+                        new StringSelectMenuOptionBuilder()
+                            .setLabel("Role Menu")
+                            .setValue("rolemenu")
+                            .setDescription("Click to customize your roles")
+                            .setDefault(data.buttons.includes("rolemenu")),
+                        new StringSelectMenuOptionBuilder()
+                            .setLabel("Ticket")
+                            .setValue("createticket")
+                            .setDescription("Click to create a support ticket")
+                            .setDefault(data.buttons.includes("createticket"))
+                    )
+            )
+
+        const channelMenu = new ActionRowBuilder<ChannelSelectMenuBuilder>()
+            .addComponents(
+                new ChannelSelectMenuBuilder()
+                    .setCustomId("channel")
+                    .setPlaceholder("Select a channel")
+                    .setChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement, ChannelType.PublicThread, ChannelType.AnnouncementThread)
+            )
+        let channelName = interaction.guild!.channels.cache.get(data.channel!)?.name;
+        if (data.channel === interaction.channelId) channelName = "this channel";
+        const embed = new EmojiEmbed()
+            .setTitle(data.title ?? "No title set")
+            .setDescription(data.description ?? "*No description set*")
+            .setColor(data.color)
+            .setFooter({text: `Click the button below to edit the embed | The embed will be sent in ${channelName}`});
+
+
+        await interaction.editReply({
+            embeds: [embed],
+            components: [colorSelect, buttonSelect, channelMenu, buttons]
+        });
+
+        let i: Discord.ButtonInteraction | Discord.ChannelSelectMenuInteraction | Discord.StringSelectMenuInteraction;
+        try {
+            i = await interaction.channel!.awaitMessageComponent({
+                filter: (i) => i.user.id === interaction.user.id,
+                time: 300000
+            }) as Discord.ButtonInteraction | Discord.ChannelSelectMenuInteraction | Discord.StringSelectMenuInteraction;
+        } catch (e) {
+            closed = true;
+            break;
+        }
+        if(i.isButton()) {
+            switch(i.customId) {
+                case "edit": {
+                    await i.showModal(
+                        new ModalBuilder()
+                            .setCustomId("modal")
+                            .setTitle(`Options for ${i.customId}`)
+                            .addComponents(
+                                new ActionRowBuilder<TextInputBuilder>().addComponents(
+                                    new TextInputBuilder()
+                                        .setCustomId("title")
+                                        .setLabel("Title")
+                                        .setMaxLength(256)
+                                        .setRequired(false)
+                                        .setStyle(TextInputStyle.Short)
+                                        .setValue(data.title ?? "")
+                                ),
+                                new ActionRowBuilder<TextInputBuilder>().addComponents(
+                                    new TextInputBuilder()
+                                        .setCustomId("description")
+                                        .setLabel("The text to display below the title")
+                                        .setMaxLength(4000)
+                                        .setRequired(false)
+                                        .setStyle(TextInputStyle.Paragraph)
+                                        .setValue(data.description ?? "")
+                                )
+                            )
+                    );
+                    await interaction.editReply({
+                        embeds: [
+                            new EmojiEmbed()
+                                .setTitle("Button Editor")
+                                .setDescription("Modal opened. If you can't see it, click back and try again.")
+                                .setStatus("Success")
+                                .setEmoji("GUILD.TICKET.OPEN")
+                        ],
+                        components: [
+                            new ActionRowBuilder<ButtonBuilder>().addComponents([
+                                new ButtonBuilder()
+                                    .setLabel("Back")
+                                    .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+                                    .setStyle(ButtonStyle.Primary)
+                                    .setCustomId("back")
+                            ])
+                        ]
+                    });
+                    let out: Discord.ModalSubmitInteraction | null;
+                    try {
+                        out = await modalInteractionCollector(m, interaction.user) as Discord.ModalSubmitInteraction | null;
+                    } catch (e) {
+                        closed = true;
+                        continue;
+                    }
+                    if (!out || out.isButton()) continue
+                    data.title = out.fields.getTextInputValue("title");
+                    data.description = out.fields.getTextInputValue("description");
+                    break;
+                }
+                case "send": {
+                    await i.deferUpdate();
+                    let channel = interaction.guild!.channels.cache.get(data.channel!) as Discord.TextChannel;
+                    let components = new ActionRowBuilder<ButtonBuilder>();
+                    for(let button of data.buttons) {
+                        components.addComponents(
+                            new ButtonBuilder()
+                            .setCustomId(button)
+                            .setLabel(buttonNames[button]!)
+                            .setStyle(ButtonStyle.Primary)
+                            );
+                        }
+                    let messageData: MessageCreateOptions = {components: [components]}
+                    if (data.title || data.description) {
+                        let e = new EmojiEmbed()
+                        if(data.title) e.setTitle(data.title);
+                        if(data.description) e.setDescription(data.description);
+                        if(data.color) e.setColor(data.color);
+                        messageData.embeds = [e];
+                    }
+                    await channel.send(messageData);
+                    break;
+                }
+            }
+        } else if(i.isStringSelectMenu()) {
+            await i.deferUpdate();
+            switch(i.customId) {
+                case "color": {
+                    data.color = colors[i.values[0]!]!;
+                    break;
+                }
+                case "button": {
+                    data.buttons = i.values;
+                    break;
+                }
+            }
+        } else {
+            await i.deferUpdate();
+            data.channel = i.values[0]!;
+        }
+
+    } while (!closed);
+    await interaction.deleteReply();
+}
+
+export const check = (interaction: CommandInteraction, _partial: boolean = false) => {
+    const member = interaction.member as Discord.GuildMember;
+    if (!member.permissions.has("ManageMessages"))
+        return "You must have the *Manage Messages* permission to use this command";
+    return true;
+};
diff --git a/src/config/emojis.json b/src/config/emojis.json
index e4afdfb..35743e1 100644
--- a/src/config/emojis.json
+++ b/src/config/emojis.json
@@ -349,7 +349,7 @@
             "TOP": {
                 "ACTIVE": "963122664648630293",
                 "INACTIVE": "963122659862917140",
-                "GREY": {
+                "GRAY": {
                     "ACTIVE": "963123505052934144",
                     "INACTIVE": "963123495221469194"
                 }
@@ -357,7 +357,7 @@
             "MIDDLE": {
                 "ACTIVE": "963122679332880384",
                 "INACTIVE": "963122673246937199",
-                "GREY": {
+                "GRAY": {
                     "ACTIVE": "963123517702955018",
                     "INACTIVE": "963123511927390329"
                 }
@@ -365,7 +365,7 @@
             "BOTTOM": {
                 "ACTIVE": "963122691752218624",
                 "INACTIVE": "963122685691453552",
-                "GREY": {
+                "GRAY": {
                     "ACTIVE": "963123529988059187",
                     "INACTIVE": "963123523742748742"
                 }
@@ -374,10 +374,20 @@
         "SINGLE": {
             "ACTIVE": "963361162215424060",
             "INACTIVE": "963361431758176316",
-            "GREY": {
+            "GRAY": {
                 "ACTIVE": "963361204695334943",
                 "INACTIVE": "963361200828198952"
             }
         }
+    },
+    "COLORS": {
+        "RED": "875822912802803754",
+        "ORANGE": "875822913104785418",
+        "YELLOW": "875822913079611402",
+        "GREEN": "875822913213841418",
+        "BLUE": "875822912777637889",
+        "PURPLE": "875822913213841419",
+        "PINK": "875822913088020541",
+        "GRAY": "875822913117368340"
     }
 }
diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts
index a22045b..80c2c1b 100644
--- a/src/events/interactionCreate.ts
+++ b/src/events/interactionCreate.ts
@@ -31,14 +31,14 @@
     await message.fetch();
     if (message.embeds.length === 0) return;
     const embed = message.embeds[0];
-    const newColour = accept ? "Success" : "Danger";
+    const newcolor = accept ? "Success" : "Danger";
     const footer = {text: `Suggestion ${accept ? "accepted" : "denied"} by ${interaction.user.tag}`, iconURL: interaction.user.displayAvatarURL()};
 
     const newEmbed = new EmojiEmbed()
         .setTitle(embed!.title!)
         .setDescription(embed!.description!)
         .setFooter(footer)
-        .setStatus(newColour);
+        .setStatus(newcolor);
 
     await interaction.update({embeds: [newEmbed], components: []});
 }
diff --git a/src/utils/commandRegistration/register.ts b/src/utils/commandRegistration/register.ts
index 6805019..0ff04b3 100644
--- a/src/utils/commandRegistration/register.ts
+++ b/src/utils/commandRegistration/register.ts
@@ -6,7 +6,7 @@
 import EmojiEmbed from '../generateEmojiEmbed.js';
 import getEmojiByName from '../getEmojiByName.js';
 
-const colours = {
+const colors = {
     red: "\x1b[31m",
     green: "\x1b[32m",
     yellow: "\x1b[33m",
@@ -26,11 +26,11 @@
     for (const file of files) {
         const last = i === files.length - 1 ? "└" : "├";
         if (file.isDirectory()) {
-            console.log(`${last}─ ${colours.yellow}Loading subcommands of ${file.name}${colours.none}`)
+            console.log(`${last}─ ${colors.yellow}Loading subcommands of ${file.name}${colors.none}`)
             const fetched = (await import(`../../../${config.commandsFolder}/${file.name}/_meta.js`));
             commands.push(fetched.command);
         } else if (file.name.endsWith(".js")) {
-            console.log(`${last}─ ${colours.yellow}Loading command ${file.name}${colours.none}`)
+            console.log(`${last}─ ${colors.yellow}Loading command ${file.name}${colors.none}`)
             const fetched = (await import(`../../../${config.commandsFolder}/${file.name}`));
             fetched.command.setDMPermission(fetched.allowedInDMs ?? false)
             fetched.command.setNameLocalizations(fetched.nameLocalizations ?? {})
@@ -43,9 +43,9 @@
             ];
         }
         i++;
-        console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colours.green}Loaded ${file.name} [${i} / ${files.length}]${colours.none}`)
+        console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colors.green}Loaded ${file.name} [${i} / ${files.length}]${colors.none}`)
     }
-    console.log(`${colours.yellow}Loaded ${commands.length} commands, processing...`)
+    console.log(`${colors.yellow}Loaded ${commands.length} commands, processing...`)
     const processed = []
 
     for (const subcommand of commands) {
@@ -56,7 +56,7 @@
         }
     }
 
-    console.log(`${colours.green}Processed ${processed.length} commands${colours.none}`)
+    console.log(`${colors.green}Processed ${processed.length} commands${colors.none}`)
     return processed;
 
 };
@@ -73,15 +73,15 @@
         const last = i === files.length - 1 ? "└" : "├";
         i++;
         try {
-            console.log(`${last}─ ${colours.yellow}Loading event ${file.name}${colours.none}`)
+            console.log(`${last}─ ${colors.yellow}Loading event ${file.name}${colors.none}`)
             const event = (await import(`../../../${config.eventsFolder}/${file.name}`));
 
             client.on(event.event, event.callback.bind(null, client));
 
-            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colours.green}Loaded ${file.name} [${i} / ${files.length}]${colours.none}`)
+            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colors.green}Loaded ${file.name} [${i} / ${files.length}]${colors.none}`)
         } catch (e) {
             errors++;
-            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colours.red}Failed to load ${file.name} [${i} / ${files.length}]${colours.none}`)
+            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colors.red}Failed to load ${file.name} [${i} / ${files.length}]${colors.none}`)
         }
     }
     console.log(`Loaded ${files.length - errors} events (${errors} failed)`)
@@ -104,7 +104,7 @@
         const last = i === totalFiles - 1 ? "└" : "├";
         i++;
         try {
-            console.log(`${last}─ ${colours.yellow}Loading message context menu ${file.name}${colours.none}`)
+            console.log(`${last}─ ${colors.yellow}Loading message context menu ${file.name}${colors.none}`)
             const context = (await import(`../../../${config.messageContextFolder}/${file.name}`));
             context.command.setType(ApplicationCommandType.Message);
             context.command.setDMPermission(context.allowedInDMs ?? false)
@@ -113,27 +113,27 @@
 
             client.commands["contextCommands/message/" + context.command.name] = context;
 
-            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colours.green}Loaded ${file.name} [${i} / ${totalFiles}]${colours.none}`)
+            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colors.green}Loaded ${file.name} [${i} / ${totalFiles}]${colors.none}`)
         } catch (e) {
             errors++;
-            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colours.red}Failed to load ${file.name} [${i} / ${totalFiles}] | ${e}${colours.none}`)
+            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colors.red}Failed to load ${file.name} [${i} / ${totalFiles}] | ${e}${colors.none}`)
         }
     }
     for (const file of userFiles) {
         const last = i === totalFiles - 1 ? "└" : "├";
         i++;
         try {
-            console.log(`${last}─ ${colours.yellow}Loading user context menu ${file.name}${colours.none}`)
+            console.log(`${last}─ ${colors.yellow}Loading user context menu ${file.name}${colors.none}`)
             const context = (await import(`../../../${config.userContextFolder}/${file.name}`));
             context.command.setType(ApplicationCommandType.User);
             commands.push(context.command);
 
             client.commands["contextCommands/user/" + context.command.name] = context;
 
-            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colours.green}Loaded ${file.name} [${i} / ${totalFiles}]${colours.none}`)
+            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colors.green}Loaded ${file.name} [${i} / ${totalFiles}]${colors.none}`)
         } catch (e) {
             errors++;
-            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colours.red}Failed to load ${file.name} [${i} / ${totalFiles}]${colours.none}`)
+            console.log(`${last.replace("└", " ").replace("├", "│")}  └─ ${colors.red}Failed to load ${file.name} [${i} / ${totalFiles}]${colors.none}`)
         }
     }
 
@@ -210,18 +210,18 @@
     if (process.argv.includes("--update-commands")) {
         if (config.enableDevelopment) {
             const guild = await client.guilds.fetch(config.developmentGuildID);
-            console.log(`${colours.purple}Registering commands in ${guild!.name}${colours.none}`)
+            console.log(`${colors.purple}Registering commands in ${guild!.name}${colors.none}`)
             await guild.commands.set(commandList);
         } else {
-            console.log(`${colours.blue}Registering commands in production mode${colours.none}`)
+            console.log(`${colors.blue}Registering commands in production mode${colors.none}`)
             await client.application?.commands.set(commandList);
         }
     }
     await registerCommandHandler();
     await registerEvents();
-    console.log(`${colours.green}Registered commands, events and context menus${colours.none}`)
+    console.log(`${colors.green}Registered commands, events and context menus${colors.none}`)
     console.log(
-        (config.enableDevelopment ? `${colours.purple}Bot started in Development mode` :
-        `${colours.blue}Bot started in Production mode`) + colours.none)
+        (config.enableDevelopment ? `${colors.purple}Bot started in Development mode` :
+        `${colors.blue}Bot started in Production mode`) + colors.none)
     // console.log(client.commands)
 };
diff --git a/src/utils/commandRegistration/slashCommandBuilder.ts b/src/utils/commandRegistration/slashCommandBuilder.ts
index ef45875..9a72605 100644
--- a/src/utils/commandRegistration/slashCommandBuilder.ts
+++ b/src/utils/commandRegistration/slashCommandBuilder.ts
@@ -6,7 +6,7 @@
 import Discord from "discord.js";
 
 
-const colours = {
+const colors = {
     red: "\x1b[31m",
     green: "\x1b[32m",
     none: "\x1b[0m"
@@ -23,7 +23,7 @@
     // If the name of the command does not match the path (e.g. attachment.ts has /attachments), use commandString
     console.log(`│  ├─ Loading group ${name}`)
     const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path, "│  ")
-    console.log(`│  │  └─ ${fetched.errors ? colours.red : colours.green}Loaded ${fetched.subcommands.length} subcommands for ${name} (${fetched.errors} failed)${colours.none}`)
+    console.log(`│  │  └─ ${fetched.errors ? colors.red : colors.green}Loaded ${fetched.subcommands.length} subcommands for ${name} (${fetched.errors} failed)${colors.none}`)
     return (subcommandGroup: SlashCommandSubcommandGroupBuilder) => {
         subcommandGroup
             .setName(name)
@@ -54,7 +54,7 @@
     // If the name of the command does not match the path (e.g. attachment.ts has /attachments), use commandString
     commandString = "commands/" + (commandString ?? path);
     const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path);
-    console.log(`│  ├─ ${fetched.errors ? colours.red : colours.green}Loaded ${fetched.subcommands.length} subcommands and ${fetched.subcommandGroups.length} subcommand groups for ${name} (${fetched.errors} failed)${colours.none}`)
+    console.log(`│  ├─ ${fetched.errors ? colors.red : colors.green}Loaded ${fetched.subcommands.length} subcommands and ${fetched.subcommandGroups.length} subcommand groups for ${name} (${fetched.errors} failed)${colors.none}`)
     // console.log({name: name, description: description})
     client.commands[commandString!] = [undefined, { name: name, description: description }]
     return (command: SlashCommandBuilder) => {
diff --git a/src/utils/createPageIndicator.ts b/src/utils/createPageIndicator.ts
index 29ea83b..6bc86a4 100644
--- a/src/utils/createPageIndicator.ts
+++ b/src/utils/createPageIndicator.ts
@@ -2,7 +2,7 @@
 
 function pageIndicator(amount: number, selected: number, showDetails?: boolean, disabled?: boolean | string) {
     let out = "";
-    disabled = disabled ? "GREY." : ""
+    disabled = disabled ? "GRAY." : ""
     if (amount === 1) {
         out += getEmojiByName("TRACKS.SINGLE." + (disabled) + (selected === 0 ? "ACTIVE" : "INACTIVE"));
     } else {
@@ -23,7 +23,7 @@
 
 export const verticalTrackIndicator = (position: number, active: string | boolean, size: number, disabled: string | boolean) => {
     active = active ? "ACTIVE" : "INACTIVE";
-    disabled = disabled ? "GREY." : "";
+    disabled = disabled ? "GRAY." : "";
     if (position === 0 && size === 1) return "TRACKS.SINGLE." + disabled + active;
     if (position === size - 1) return "TRACKS.VERTICAL.BOTTOM." + disabled + active;
     if (position === 0) return "TRACKS.VERTICAL.TOP." + disabled + active;