diff --git a/.gitignore b/.gitignore
index 0a2dd09968370e07cc533053b466ec4f7345e420..f588112edcfa041a031a0d4a39ca931911ba575d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,6 @@ Thumbs.db
 # Vite
 vite.config.js.timestamp-*
 vite.config.ts.timestamp-*
+
+# Storybook
+storybook-static/
\ No newline at end of file
diff --git a/.storybook/main.ts b/.storybook/main.ts
index b55c2e918620c1a8a5b60c5f2c271fae47d7bb91..2998fb18a61a3d5aee34b9f4084587ff8b80b95b 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -2,12 +2,7 @@ import type { StorybookConfig } from '@storybook/sveltekit';
 
 const config: StorybookConfig = {
 	stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|ts|svelte)'],
-	addons: [
-		'@storybook/addon-svelte-csf',
-		'@storybook/addon-essentials',
-		'@chromatic-com/storybook',
-		'@storybook/addon-interactions'
-	],
+	addons: ['@storybook/addon-svelte-csf', '@storybook/addon-essentials'],
 	framework: {
 		name: '@storybook/sveltekit',
 		options: {}
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index dbd1c7ac230a22cec028535e7fc084e94c432e6d..6d349b43ddeb792c3f5fab238cd24a7132ac8f34 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -3,6 +3,7 @@ import type { Preview } from '@storybook/svelte';
 const preview: Preview = {
 	parameters: {
 		controls: {
+			disableSaveFromUI: false,
 			matchers: {
 				color: /(background|color)$/i,
 				date: /Date$/i
diff --git a/package.json b/package.json
index e70aa0acd82e7394f92c06fd92ba28b56f6f80e2..5cffefd6648285211575ad78e7306da31dbefed1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,9 @@
 {
 	"name": "barbi",
 	"version": "0.0.1",
+	"publishConfig": {
+		"registry": "https://npm.weirdboi.dev"
+	},
 	"scripts": {
 		"dev": "vite dev",
 		"build": "vite build && npm run prepack",
@@ -51,10 +54,8 @@
 		"svelte": "^5.0.0"
 	},
 	"devDependencies": {
-		"@chromatic-com/storybook": "^3.2.4",
 		"@playwright/test": "^1.49.1",
 		"@storybook/addon-essentials": "^8.5.3",
-		"@storybook/addon-interactions": "^8.5.3",
 		"@storybook/addon-svelte-csf": "^5.0.0-next.23",
 		"@storybook/blocks": "^8.5.3",
 		"@storybook/svelte": "^8.5.3",
diff --git a/src/lib/atoms/Button.svelte b/src/lib/atoms/Button.svelte
index 8fccc59219b65579617d3fad38d82fc5a59da8c5..4a0ee56ab56201562b1f681f7768d9a3d3031e73 100644
--- a/src/lib/atoms/Button.svelte
+++ b/src/lib/atoms/Button.svelte
@@ -21,8 +21,7 @@
 	{...props}
 	{tag}
 	hover
-	active
->
+	active>
 	{@render children?.()}
 </Panel>
 
diff --git a/src/lib/atoms/Input.stories.svelte b/src/lib/atoms/Input.stories.svelte
new file mode 100644
index 0000000000000000000000000000000000000000..9578d853e32eff52ef08dd66613f8da48d9ae130
--- /dev/null
+++ b/src/lib/atoms/Input.stories.svelte
@@ -0,0 +1,24 @@
+<script module>
+	import { BarbiTheme, Input } from '$lib';
+	import { defineMeta } from '@storybook/addon-svelte-csf';
+
+	const { Story } = defineMeta({
+		title: 'Components/Atoms/Input',
+		component: Input
+	});
+</script>
+
+<BarbiTheme />
+<div>
+	<style>
+		.sb-show-main {
+			padding: var(--spacing-md) !important;
+		}
+	</style>
+</div>
+
+<Story name="Simple Text Input" args={{ placeholder: 'Simple Text Input' }} />
+<Story name="Disabled Input" args={{ placeholder: 'Cant edit this', disabled: true }} />
+<Story name="Number Input" args={{ value: 0, type: 'number' }} />
+<Story name="Range Input" args={{ value: 0, type: 'range', min: 0, max: 100, step: 10 }} />
+<Story name="Checkbox Input" args={{ type: 'checkbox' }} />
diff --git a/src/lib/atoms/Input.svelte b/src/lib/atoms/Input.svelte
new file mode 100644
index 0000000000000000000000000000000000000000..8a542803495b77035988c00695c4b9995d0d8ea6
--- /dev/null
+++ b/src/lib/atoms/Input.svelte
@@ -0,0 +1,140 @@
+<script lang="ts" module>
+	export type TextInputProps = {
+		value?: string;
+		autocomplete?: 'on' | 'off';
+	};
+	export type NumberInputProps = {
+		value?: number;
+		min?: number;
+		max?: number;
+		step?: number;
+	};
+
+	export type BaseInputProps<inputType, additonal> = {
+		type: inputType;
+		id?: string;
+		name?: string;
+		disabled?: boolean;
+		required?: boolean;
+		placeholder?: string;
+	} & additonal;
+
+	export type Props =
+		| BaseInputProps<'text' | undefined, TextInputProps>
+		| BaseInputProps<'number', NumberInputProps>;
+</script>
+
+<script lang="ts">
+	let { value = $bindable(undefined), class: className = '', ...props }: Props = $props();
+</script>
+
+<input bind:value class={['input', className]} {...props} />
+
+<style>
+	.input {
+		--component-background: var(--colour-white);
+		--component-colour: var(--colour-text);
+		--component-placeholder: var(--colour-steel);
+
+		--border-colour: var(--colour-steel);
+
+		color: var(--component-colour);
+		background-color: var(--component-background);
+
+		font-family: var(--font-family-body);
+		font-size: var(--font-size-base);
+
+		border: var(--border-width) var(--border-style) var(--border-colour);
+		padding: var(--spacing-sm) var(--spacing-md);
+		transition: all var(--transition-fast);
+
+		box-shadow: var(--shadow-md);
+		outline: none;
+	}
+
+	.input:hover {
+		--component-background: var(--colour-background);
+		--border-colour: var(--colour-steel);
+	}
+
+	.input:focus {
+		--border-colour: var(--colour-primary);
+	}
+
+	.input:disabled {
+		--component-background: var(--colour-concrete);
+		opacity: 0.9;
+		cursor: not-allowed;
+	}
+
+	/* Placeholder styles */
+	.input::placeholder {
+		color: var(--component-placeholder);
+	}
+
+	/* Specific styles for different .input types */
+	.input[type='checkbox'],
+	.input[type='radio'] {
+		width: var(--spacing-md);
+		height: var(--spacing-md);
+		margin-right: var(--spacing-sm);
+	}
+
+	.input[type='color'] {
+		padding: var(--spacing-xs);
+		height: calc(var(--font-size-base) * 2);
+	}
+
+	.input[type='range'] {
+		--component-background: transparent;
+		-webkit-appearance: none;
+		border: none;
+		box-shadow: none;
+		padding: 0;
+		appearance: none;
+		cursor: pointer;
+	}
+
+	.input[type='range']::-webkit-slider-runnable-track,
+	.input[type='range']::-moz-range-track {
+		--border-colour: var(--colour-contrast);
+		background: var(--colour-white);
+		height: var(--spacing-sm);
+		border: var(--border-width) var(--border-style) var(--border-colour);
+        transition: border-color var(--transition-fast);
+    }
+
+	.input[type='range']::-webkit-slider-container,
+	.input[type='range']::-moz-range-progress {
+		--border-colour: var(--colour-contrast);
+		background: var(--colour-primary);
+		height: var(--spacing-sm);
+		border: var(--border-width) var(--border-style) var(--border-colour);
+		transition: border-color var(--transition-fast);
+    }
+	.input[type='range']:focus::-webkit-slider-container,
+	.input[type='range']:focus::-moz-range-progress {
+		--border-colour: var(--colour-primary);
+    }
+
+	.input[type='range']:focus {
+		outline: none;
+	}
+
+	.input[type='range']:focus::-webkit-slider-runnable-track,
+	.input[type='range']:focus::-moz-range-track {
+		--border-colour: var(--colour-primary);
+	}
+
+	.input[type='range']::-webkit-slider-thumb,
+	.input[type='range']::-moz-range-thumb {
+		--border-colour: var(--colour-contrast);
+		-webkit-appearance: none;
+        appearance: none;
+		border-radius: 0;
+		border: var(--border-width) var(--border-style) var(--border-colour);
+		width: var(--spacing-sm);
+		height: var(--spacing-md);
+		background: var(--colour-background);
+	}
+</style>
diff --git a/src/lib/atoms/Panel.svelte b/src/lib/atoms/Panel.svelte
index 2483a0e762b1dc71cc3eff872dbfd89eecb2d448..657cc09df4589e7896af24b038207c403943d176 100644
--- a/src/lib/atoms/Panel.svelte
+++ b/src/lib/atoms/Panel.svelte
@@ -11,7 +11,7 @@
 		disabled?: boolean;
 		flat?: boolean;
 		full?: boolean;
-	} & HTMLElement;
+	} & IntrinsicElements[Tag];
 
 	const {
 		// @ts-ignore
@@ -55,8 +55,7 @@
 		variant
 	]}
 	{disabled}
-	{...rest}
->
+	{...rest}>
 	{@render children?.()}
 </svelte:element>
 
diff --git a/src/lib/atoms/popover/Popover.svelte b/src/lib/atoms/popover/Popover.svelte
index 156f8bb4bb04f25176d8bb14a646c41d08829ac9..57313a7b4bf45770b7bb3f27261e1b65c7cce082 100644
--- a/src/lib/atoms/popover/Popover.svelte
+++ b/src/lib/atoms/popover/Popover.svelte
@@ -78,8 +78,7 @@
 
 <div
 	class={['popover-wrapper', wrapperClass]}
-	style={`${style ? style : ''}; --component-gap-vertical: ${spaceVertical}; --component-gap-horizontal: ${spaceHorizontal};`}
->
+	style={`${style ? style : ''}; --component-gap-vertical: ${spaceVertical}; --component-gap-horizontal: ${spaceHorizontal};`}>
 	<div bind:this={triggerElement} onclick={openPopover}>
 		{@render children?.()}
 	</div>
diff --git a/src/lib/components/modal/CustomIcon.internal.svelte b/src/lib/components/modal/CustomIcon.internal.svelte
index ebe5de82666d85b875c77398e03c7ad86cd60c90..f91593592da9668b39d425d9c5dc3acf1af92820 100644
--- a/src/lib/components/modal/CustomIcon.internal.svelte
+++ b/src/lib/components/modal/CustomIcon.internal.svelte
@@ -2,7 +2,10 @@
 	const { class: className, ...props } = $props();
 </script>
 
-<svg viewBox="0 0 200 110" xmlns="http://www.w3.org/2000/svg"
-	 class={['icon', className]} {...props}>
-	<path d="m1.636 5.368 196.73 1.5-97.764 97.764-98.964-99.264z" fill="var(--colour-icon)"/>
+<svg
+	viewBox="0 0 200 110"
+	xmlns="http://www.w3.org/2000/svg"
+	class={['icon', className]}
+	{...props}>
+	<path d="m1.636 5.368 196.73 1.5-97.764 97.764-98.964-99.264z" fill="var(--colour-icon)" />
 </svg>
diff --git a/src/lib/components/modal/Dropdown.stories.svelte b/src/lib/components/modal/Dropdown.stories.svelte
index 81e21295459d625cc273fbcc83299d0250a78ba9..18d81ab5708683fc8e1265b4555a5779fe219124 100644
--- a/src/lib/components/modal/Dropdown.stories.svelte
+++ b/src/lib/components/modal/Dropdown.stories.svelte
@@ -9,11 +9,11 @@
 		argTypes: {
 			alternate: {
 				name: 'Alternate Style',
-				control: 'boolean',
+				control: 'boolean'
 			},
 			flat: {
 				name: 'Flat Style',
-				control: 'boolean',
+				control: 'boolean'
 			},
 			options: {
 				table: {
@@ -29,11 +29,16 @@
 	args={{
 		label: "I'm a dropdown",
 		options: [
-			{ value: '1', label: 'I log to the console', onClick() { console.log("First button") } },
-			{ value: '2', label: "I'm an external link", href: 'https://example.com' },
+			{
+				value: '1',
+				label: 'I log to the console',
+				onClick() {
+					console.log('First button');
+				}
+			},
+			{ value: '2', label: "I'm an external link", href: 'https://example.com' }
 		]
-	}}
->
+	}}>
 	{#snippet children(args)}
 		<BarbiTheme />
 		<div class="storybook-center">
@@ -48,11 +53,16 @@
 		label: "This dropdown uses variant='secondary'",
 		alternate: true,
 		options: [
-			{ value: '1', label: 'I log to the console', onClick() { console.log("First button") } },
-			{ value: '2', label: "I'm an external link", href: 'https://example.com' },
+			{
+				value: '1',
+				label: 'I log to the console',
+				onClick() {
+					console.log('First button');
+				}
+			},
+			{ value: '2', label: "I'm an external link", href: 'https://example.com' }
 		]
-	}}
->
+	}}>
 	{#snippet children(args)}
 		<BarbiTheme />
 		<div class="storybook-center">
@@ -67,11 +77,16 @@
 		label: "I'm Flat!",
 		flat: true,
 		options: [
-			{ value: '1', label: 'I log to the console', onClick() { console.log("First button") } },
-			{ value: '2', label: "I'm an external link", href: 'https://example.com' },
+			{
+				value: '1',
+				label: 'I log to the console',
+				onClick() {
+					console.log('First button');
+				}
+			},
+			{ value: '2', label: "I'm an external link", href: 'https://example.com' }
 		]
-	}}
->
+	}}>
 	{#snippet children(args)}
 		<BarbiTheme />
 		<div class="storybook-center">
@@ -83,13 +98,18 @@
 <Story
 	name="Only Icon"
 	args={{
-		label: "",
+		label: '',
 		options: [
-			{ value: '1', label: 'I log to the console', onClick() { console.log("First button") } },
-			{ value: '2', label: "I'm an external link", href: 'https://example.com' },
+			{
+				value: '1',
+				label: 'I log to the console',
+				onClick() {
+					console.log('First button');
+				}
+			},
+			{ value: '2', label: "I'm an external link", href: 'https://example.com' }
 		]
-	}}
->
+	}}>
 	{#snippet children(args)}
 		<BarbiTheme />
 		<div class="storybook-center">
@@ -105,16 +125,23 @@
 		label: "It won't spin",
 		icon: CustomIcon,
 		options: [
-			{ value: '1', label: 'I log to the console', onClick() { console.log("First button") } },
-			{ value: '2', label: "I'm an external link", href: 'https://example.com' },
+			{
+				value: '1',
+				label: 'I log to the console',
+				onClick() {
+					console.log('First button');
+				}
+			},
+			{ value: '2', label: "I'm an external link", href: 'https://example.com' }
 		]
-	}}
->
+	}}>
 	{#snippet children(args)}
 		<BarbiTheme />
 		<div class="storybook-center">
 			<Dropdown {...args} />
-			<span>Pass a component to the 'icon' prop that uses the global '.icon' class, and merges it with a 'class' property</span>
+			<span
+				>Pass a component to the 'icon' prop that uses the global '.icon' class, and merges
+				it with a 'class' property</span>
 		</div>
 	{/snippet}
 </Story>
diff --git a/src/lib/components/modal/Dropdown.svelte b/src/lib/components/modal/Dropdown.svelte
index 6ab9d745de6f4508846929b0b6601f04071784ca..ca810603a5fd7603251c9103759193fffedc3a24 100644
--- a/src/lib/components/modal/Dropdown.svelte
+++ b/src/lib/components/modal/Dropdown.svelte
@@ -4,9 +4,9 @@
 	export type Props = {
 		label?: string;
 		options?: DropdownOption[];
-		alternate?: boolean,
-		flat?: boolean,
-		icon?: Component<any>
+		alternate?: boolean;
+		flat?: boolean;
+		icon?: Component<any>;
 	};
 
 	export type DropdownOption = {
@@ -23,9 +23,15 @@
 	import Popover from '../../atoms/popover/Popover.svelte';
 	import AngleDownIcon from '../..//patterns/icons/AngleDownIcon.svelte';
 
-	const { label = '', options = [], alternate = false, flat = false, icon: Icon = AngleDownIcon }: Props = $props();
+	const {
+		label = '',
+		options = [],
+		alternate = false,
+		flat = false,
+		icon: Icon = AngleDownIcon
+	}: Props = $props();
 	let open = $state(false);
-	let shouldAnimate = $derived.by(() => Icon === AngleDownIcon)
+	let shouldAnimate = $derived.by(() => Icon === AngleDownIcon);
 
 	function wrapOnClick(option: DropdownOption) {
 		if (option.onClick) {
@@ -43,15 +49,21 @@
 </script>
 
 <Popover bind:open>
-	<Button variant={alternate ? 'secondary' : 'primary'} flat={flat}>
+	<Button variant={alternate ? 'secondary' : 'primary'} {flat}>
 		<span class="dropdown-label">{label}</span>
-		<Icon style="--size-icon: 1.25rem;" class={['dropdown-arrow', shouldAnimate && 'dropdown-arrow-animate', { open }]} />
+		<Icon
+			style="--size-icon: 1.25rem;"
+			class={['dropdown-arrow', shouldAnimate && 'dropdown-arrow-animate', { open }]} />
 	</Button>
 
 	{#snippet popover()}
-		<Panel space="none" class="dropdown-popover-list" flat={flat}>
+		<Panel space="none" class="dropdown-popover-list" {flat}>
 			{#each options as option}
-				<Button variant={alternate ? 'success' : 'secondary'} flat onclick={wrapOnClick(option)} href={option.href}>
+				<Button
+					variant={alternate ? 'success' : 'secondary'}
+					flat
+					onclick={wrapOnClick(option)}
+					href={option.href}>
 					{option.label}
 				</Button>
 			{/each}
diff --git a/src/lib/index.ts b/src/lib/index.ts
index 49856ce060898e7e586db600e46d9483d114085f..011c4828cf64534da8ff14091b382e62c789407b 100644
--- a/src/lib/index.ts
+++ b/src/lib/index.ts
@@ -5,6 +5,7 @@ import CheckerboardPattern from './patterns/CheckerboardPattern.svelte';
 import Popover from './atoms/popover/Popover.svelte';
 import { Anchor } from './atoms/popover/utils.js';
 import Dropdown from './components/modal/Dropdown.svelte';
+import Input from './atoms/Input.svelte';
 
 import type { AnchorName } from './atoms/popover/utils.ts';
 
@@ -12,9 +13,7 @@ import type { AnchorName } from './atoms/popover/utils.ts';
 export { BarbiTheme, CheckerboardPattern, Anchor };
 
 // Atoms
-export {
-	Panel, Button, Popover,
-}
+export { Panel, Button, Popover, Input };
 
 // Components
 export { Dropdown };
diff --git a/src/lib/patterns/CheckerboardPattern.stories.svelte b/src/lib/patterns/CheckerboardPattern.stories.svelte
index 937d657dd5510fa7e6d533e1c38945a4bca80cc7..e8825f0cd3e76f5798d514d3a8bfff8d92aa0131 100644
--- a/src/lib/patterns/CheckerboardPattern.stories.svelte
+++ b/src/lib/patterns/CheckerboardPattern.stories.svelte
@@ -32,8 +32,7 @@
 
 <Story
 	name="Modified Colours"
-	args={{ style: '--pattern-light: #ECA400; --pattern-dark: #27476E;', scale: 2 }}
->
+	args={{ style: '--pattern-light: #ECA400; --pattern-dark: #27476E;', scale: 2 }}>
 	{#snippet children(args)}
 		<BarbiTheme />
 		<CheckerboardPattern {...args} />
diff --git a/src/lib/patterns/CheckerboardPattern.svelte b/src/lib/patterns/CheckerboardPattern.svelte
index 6fb0bfdae6c170f515d6752a1fc077afd446324a..871f864dcca9298f0a594985a0b949b40a6c82e3 100644
--- a/src/lib/patterns/CheckerboardPattern.svelte
+++ b/src/lib/patterns/CheckerboardPattern.svelte
@@ -18,16 +18,14 @@
 	class={className}
 	bind:clientHeight={height}
 	bind:clientWidth={width}
-	{...props}
->
+	{...props}>
 	<defs>
 		<pattern
 			id="checks"
 			patternUnits="userSpaceOnUse"
 			width="16"
 			height="16"
-			class={scrollDirection ? ['scroll', scrollDirection] : []}
-		>
+			class={scrollDirection ? ['scroll', scrollDirection] : []}>
 			<rect width="16" height="16" fill="var(--pattern-light)" />
 			<rect width="8" height="8" x="0" y="0" fill="var(--pattern-dark)" />
 			<rect width="8" height="8" x="8" y="8" fill="var(--pattern-dark)" />
diff --git a/src/lib/patterns/icons/AngleDownIcon.svelte b/src/lib/patterns/icons/AngleDownIcon.svelte
index acd641496db2b7afab6c8335bd78b42d267a0741..2513bc8d6cc57c9ddac16912236aea96811322bc 100644
--- a/src/lib/patterns/icons/AngleDownIcon.svelte
+++ b/src/lib/patterns/icons/AngleDownIcon.svelte
@@ -6,10 +6,8 @@
 	xmlns="http://www.w3.org/2000/svg"
 	class={['icon', className]}
 	viewBox="0 0 448 512"
-	{...props}
->
+	{...props}>
 	<path
 		style="fill: var(--colour-icon)"
-		d="M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z"
-	/>
+		d="M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z" />
 </svg>
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index fb0d6e86a2f6cf2c290b0415cacf6614e2212d80..e6aea9a28e90939238dc9e7e412ebd28de616307 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -13,12 +13,11 @@
 				label: 'First Option',
 				value: '123',
 				onClick() {
-					console.log("FOO")
+					console.log('FOO');
 				}
 			},
 			{ label: 'Second Option', value: '456', href: 'https://example.com' }
-		]}
-	/>
+		]} />
 </div>
 
 <style>