diff --git a/website/agb/src/app/colour/colour.tsx b/website/agb/src/app/colour/colour.tsx
new file mode 100644
index 00000000..77d11789
--- /dev/null
+++ b/website/agb/src/app/colour/colour.tsx
@@ -0,0 +1,133 @@
+"use client";
+
+import { ContentBlock } from "../contentBlock";
+import { useState } from "react";
+import { styled } from "styled-components";
+
+interface Colour {
+ r: number;
+ g: number;
+ b: number;
+}
+
+function fromHex(hex: string): Colour {
+ if (hex.startsWith("#")) {
+ hex = hex.slice(1);
+ }
+
+ const c = parseInt(hex, 16);
+
+ return {
+ r: c & 255,
+ g: (c >> 8) & 255,
+ b: (c >> 16) & 255,
+ };
+}
+
+function toHex(colour: Colour): string {
+ const hex = (colour.r | (colour.g << 8) | (colour.b << 16))
+ .toString(16)
+ .padStart(6, "0");
+
+ return `#${hex}`;
+}
+
+function fromRgb15(colour: number): Colour {
+ const r = colour & 31;
+ const g = (colour >> 5) & 31;
+ const b = (colour >> 10) & 31;
+
+ function upScale(a: number) {
+ return a << 3;
+ }
+ return {
+ r: upScale(r),
+ g: upScale(g),
+ b: upScale(b),
+ };
+}
+
+function toRgb15(colour: Colour): number {
+ const { r, g, b } = colour;
+ return ((r >> 3) & 31) | (((g >> 3) & 31) << 5) | (((b >> 3) & 31) << 10);
+}
+
+export default function ColourPicker() {
+ const [colour, setColour] = useState(fromHex("#FFFFFF"));
+ const gbaColour = fromRgb15(toRgb15(colour));
+
+ const hexColour = toHex(colour);
+ const gbaHexColour = toHex(gbaColour);
+ const gbaU16 = `0x${toRgb15(colour).toString(16)}`;
+
+ function setHexColour(colour: string) {
+ setColour(fromHex(colour));
+ }
+
+ function setGbaHexColour(colour: string) {
+ setColour(fromRgb15(toRgb15(fromHex(colour))));
+ }
+
+ return (
+
+ agbrs colour converter
+
+
+ Regular RGB8
+ setHexColour(evt.target.value)}
+ />
+ setHexColour(evt.target.value)}
+ />
+
+
+ GBA RGB5
+ setGbaHexColour(evt.target.value)}
+ />
+ setGbaHexColour(evt.target.value)}
+ />
+
+ setColour(fromRgb15(parseInt(evt.target.value, 16)))
+ }
+ />
+
+
+
+ );
+}
+
+const PickerColumn = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ min-width: 40%;
+`;
+
+const PickerWrapper = styled.div`
+ display: flex;
+ justify-content: space-around;
+`;
+
+const Input = styled.input`
+ width: 100%;
+`;
+
+const ColourInput = styled(Input)`
+ height: 100px;
+ color: #33a012;
+`;
diff --git a/website/agb/src/app/colour/page.tsx b/website/agb/src/app/colour/page.tsx
new file mode 100644
index 00000000..6d760631
--- /dev/null
+++ b/website/agb/src/app/colour/page.tsx
@@ -0,0 +1,10 @@
+import { Metadata } from "next";
+import ColourPicker from "./colour";
+
+export const metadata: Metadata = {
+ title: "Colour Converter",
+};
+
+export default function ColourPickerPage() {
+ return ;
+}