diff --git a/boot.py b/boot.py
new file mode 100644
index 0000000..5b629bb
--- /dev/null
+++ b/boot.py
@@ -0,0 +1,27 @@
+import network
+from machine import Pin
+from config import *
+
+def do_connect():
+    led = Pin(8, Pin.OUT)
+    sta_if = network.WLAN(network.STA_IF)
+    sta_if.ifconfig((ip, '255.255.255.0', gateway, '1.1.1.1'))
+    if not sta_if.isconnected():
+        print('connecting to network...')
+        sta_if.active(True)
+        sta_if.connect(ssid, password)
+        led.on()
+        while not sta_if.isconnected():
+            pass
+    print('network config:', sta_if.ifconfig())
+    
+do_connect()
+
+ap = network.WLAN(network.AP_IF)
+ap.active(True)
+ap.config(essid="led", password="qwerty1234")
+print(ap.ifconfig())
+
+
+
+
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..6db7767
--- /dev/null
+++ b/index.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>LED Control</title>
+    <script src="main.js" defer></script>
+</head>
+<body>
+    <h1>Control LEDs</h1>
+    <form id="led_form" method="post" action="/num_leds">
+        <label for="num_leds">Number of LEDs:</label>
+        <input type="text" id="num_leds" name="num_leds" value="{num_leds}">
+        <input type="submit" value="Update">
+    </form>
+    <div id="pattern_buttons">
+        <!-- Pattern buttons will be inserted here -->
+    </div>
+    <form id="delay_form" method="post" action="/delay">
+        <label for="delay">Delay:</label>
+        <input type="range" id="delay" name="delay" min="10" max="1000" value="{delay}" step="10">
+    </form>
+    <form id="color_form" method="post" action="/color">
+        <label for="color">Select Color:</label>
+        <input type="color" id="color" name="color" value="{color}">
+    </form>
+    <form id="color2_form" method="post" action="/color2">
+        <label for="color2">Select Color2:</label>
+        <input type="color" id="color2" name="color2" value="{color2}">
+    </form>
+
+</body>
+</html>
diff --git a/main.css b/main.css
new file mode 100644
index 0000000..7b3d403
--- /dev/null
+++ b/main.css
@@ -0,0 +1,40 @@
+body {
+    font-family: Arial, sans-serif;
+    background-color: #f0f0f0;
+    margin: 0;
+    padding: 20px;
+}
+
+h1 {
+    color: #333;
+}
+
+form {
+    margin-bottom: 20px;
+}
+
+label {
+    display: block;
+    margin-bottom: 5px;
+    font-weight: bold;
+}
+
+input[type="text"],
+input[type="range"],
+input[type="color"],
+button {
+    margin-bottom: 10px;
+    padding: 10px;
+    font-size: 16px;
+}
+
+button:disabled {
+    background-color: #ccc;
+}
+
+button {
+    margin-right: 5px;
+    padding: 10px 20px;
+    font-size: 16px;
+    cursor: pointer;
+}
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..e601f25
--- /dev/null
+++ b/main.js
@@ -0,0 +1,95 @@
+let delayTimeout;
+
+async function post(path, value) {
+console.log(path, value);
+    try {
+        const response = await fetch(path, {
+            method: "POST",
+            headers: {
+                'Content-Type': 'application/x-www-form-urlencoded'
+            },
+            body: value 
+        });
+        if (!response.ok) {
+            throw new Error(`HTTP error! Status: ${response.status}`);
+        }
+    } catch (error) {
+        console.error('Error during POST request:', error);
+    }
+}
+
+async function get(path) {
+    try {
+        const response = await fetch(path);
+        if (!response.ok) {
+            throw new Error(`HTTP error! Status: ${response.status}`);
+        }
+        return await response.json(); // Assuming you are expecting JSON response
+    } catch (error) {
+        console.error('Error during GET request:', error);
+    }
+}
+
+async function updateColor(event) {
+    event.preventDefault();
+    const color = document.getElementById('color').value;
+    await post("/color", color);
+}
+
+async function updateColor2(event) {
+    event.preventDefault();
+    const color = document.getElementById('color2').value;
+    await post("/color2", color);
+}
+
+async function updatePattern(pattern) {
+    event.preventDefault();
+    await post("/pattern", pattern);
+}
+
+async function updateDelay(event) {
+    event.preventDefault();
+    clearTimeout(delayTimeout);
+    delayTimeout = setTimeout(async function() {
+        const delay = document.getElementById('delay').value;
+        await post('/delay', delay);
+    }, 500);
+}
+
+async function updateNumLeds(event) {
+    event.preventDefault();
+    const numLeds = document.getElementById('num_leds').value;
+    await post('/num_leds', numLeds);
+}
+
+function createPatternButtons(patterns) {
+    const container = document.getElementById('pattern_buttons');
+    container.innerHTML = ''; // Clear previous buttons
+
+    patterns.forEach(pattern => {
+        const button = document.createElement('button');
+        button.type = 'button'; // Use 'button' instead of 'submit'
+        button.textContent = pattern;
+        button.value = pattern;
+        button.addEventListener('click', async function(event) {
+            event.preventDefault();
+            await updatePattern(pattern);
+        });
+        container.appendChild(button);
+    });
+}
+
+document.addEventListener('DOMContentLoaded', async function() {
+    document.getElementById('color').addEventListener('input', updateColor);
+    document.getElementById('color2').addEventListener('input', updateColor2);
+    document.getElementById('delay').addEventListener('input', updateDelay);
+    document.getElementById('led_form').addEventListener('submit', updateNumLeds);
+
+    try {
+        const patterns = await get("/patterns");
+        console.log('Patterns fetched:', patterns);
+        createPatternButtons(patterns);
+    } catch (error) {
+        console.error('Error fetching patterns:', error);
+    }
+});
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..9e3b4f4
--- /dev/null
+++ b/main.py
@@ -0,0 +1,187 @@
+from machine import Pin
+from patterns import Patterns
+import socket
+import select
+import json
+
+class LEDServer:
+    SETTINGS_FILE = "/settings.json"  # Path should be adjusted for MicroPython's filesystem
+
+    def __init__(self, num_leds=50, pin=4, led_pin=8, brigtness=255):
+        # Initialize NeoPixel Patterns
+        self.num_leds = num_leds
+        self.patterns = Patterns(pin, num_leds)
+        self.selected_pattern = "blink"
+        self.color = (16, 16, 0)
+        self.color2 = (16, 16, 0)
+        self.delay = 100
+        
+        # Initialize single LED
+        self.led = Pin(led_pin, Pin.OUT)
+        
+        # Initialize server
+        self.server_socket = socket.socket()
+        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        self.server_socket.bind(('0.0.0.0', 80))
+        self.server_socket.listen(1)
+        self.server_socket.settimeout(1)  # Adjust timeout as needed
+        
+        self.poll = select.poll()
+        self.poll.register(self.server_socket, select.POLLIN)
+        
+        # Load settings from file
+        self.load_settings()
+        # Read static files
+        color = f'#{self.color[0]:02x}{self.color[1]:02x}{self.color[2]:02x}'
+        color2 = f'#{self.color2[0]:02x}{self.color2[1]:02x}{self.color2[2]:02x}'
+        print(color)
+        self.html = self.read_file("/index.html").format(num_leds=self.num_leds, delay=self.delay, color=color, color2=color2).encode()
+        self.js = self.read_file("/main.js").encode('utf-8')
+        self.css = self.read_file("/main.css").encode('utf-8')
+        self.patterns_json = json.dumps(list(self.patterns.patterns.keys()))
+        
+        
+
+    def read_file(self, file_path):
+        try:
+            with open(file_path, 'r') as file:
+                return file.read()
+        except OSError as e:
+            print(f"Error reading file {file_path}: {e}")
+            return ""
+
+    def save_settings(self):
+        settings = {
+            "num_leds": self.num_leds,
+            "selected_pattern": self.selected_pattern,
+            "color": self.color,
+            "color2": self.color2,
+            "delay": self.delay
+        }
+        print(settings)
+        try:
+            with open(self.SETTINGS_FILE, 'w') as file:
+                json.dump(settings, file)
+        except OSError as e:
+            print(f"Error saving settings: {e}")
+
+    def load_settings(self):
+        if self.file_exists(self.SETTINGS_FILE):
+            try:
+                with open(self.SETTINGS_FILE, 'r') as file:
+                    settings = json.load(file)
+                    self.num_leds = settings.get("num_leds", self.num_leds)
+                    self.selected_pattern = settings.get("selected_pattern", self.selected_pattern)
+                    self.color = tuple(settings.get("color", self.color))
+                    self.color2 = tuple(settings.get("color2", self.color2))
+                    self.delay = settings.get("delay", self.delay)
+                    self.patterns.update_num_leds(4, self.num_leds)
+                    self.patterns.set_delay(self.delay)
+                    self.patterns.selected = self.selected_pattern
+            except (OSError, ValueError) as e:
+                print(f"Error loading settings: {e}")
+
+    def file_exists(self, file_path):
+        try:
+            with open(file_path, 'r'):
+                return True
+        except OSError:
+            return False
+
+    def handle_post(self, path, post_data, client_socket):
+        print(post_data)
+        if path == "/num_leds":
+            try:
+                self.num_leds = int(post_data)
+                self.patterns.update_num_leds(4, self.num_leds)
+                self.save_settings()
+                client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
+            except ValueError:
+                client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
+                
+        elif path == "/pattern":
+            self.selected_pattern = post_data
+            self.patterns.selected = post_data
+            self.save_settings()
+            client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
+
+        elif path == "/delay":
+            try:
+                self.delay = int(post_data)
+                self.patterns.set_delay(self.delay)
+                self.save_settings()
+                client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
+            except ValueError:
+                client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
+
+        elif path == "/color":
+#            try:
+            self.patterns.set_color1(tuple(int(post_data[i:i+2], 16) for i in (1, 3, 5)))  # Convert hex to RGB
+            self.save_settings()
+            client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
+#            except:
+        
+#                client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
+        elif path == "/color2":
+            try:
+                self.patterns.set_color2(tuple(int(post_data[i:i+2], 16) for i in (1, 3, 5)))  # Convert hex to RGB
+                self.save_settings()
+                client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
+            except:
+                client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
+        else:
+            client_socket.send(b'HTTP/1.0 404 Not Found\r\nContent-Type: text/plain\r\n\r\n')
+
+    def handle_get(self, path, client_socket):
+        if path == "/":
+            client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
+            client_socket.send(self.html)
+        elif path == "/main.js":
+            client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: application/javascript\r\n\r\n')
+            client_socket.send(self.js)
+        elif path == "/main.css":
+            client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: text/css\r\n\r\n')
+            client_socket.send(self.css)
+        elif path == "/patterns":
+            client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: application/json\r\n\r\n')
+            client_socket.send(self.patterns_json.encode())
+        else:
+            client_socket.send(b'HTTP/1.0 404 Not Found\r\nContent-Type: text/plain\r\n\r\n')
+
+    def start(self):
+        count = 0
+        try:
+            while True:
+                count += 1
+                events = self.poll.poll(1)
+                for file in events:
+                    if file[0] == self.server_socket:
+                        client_socket, addr = self.server_socket.accept()
+                        request = client_socket.recv(1024).decode()
+                        method, path, _ = request.split('\r\n')[0].split()
+                        print(f"Method: {method}, Path: {path}")            
+                        if method == "POST":
+                            post_data = request.split('\r\n\r\n')[1] if '\r\n\r\n' in request else ''
+                            self.handle_post(path, post_data, client_socket)   
+                        elif method == "GET":
+                            self.handle_get(path, client_socket)
+                        client_socket.close()
+
+                if count > 50:
+                    self.led.off()
+                if count > 100:
+                    self.led.on()
+                    count = 0
+
+                self.patterns.tick()
+               
+        except Exception as e:
+            print("Error:", e)
+        finally:
+            self.server_socket.close()
+            self.save_settings()
+
+# Example of creating and starting the server
+if __name__ == "__main__":
+    server = LEDServer()
+    server.start()
diff --git a/patterns.py b/patterns.py
index bc2c030..7f7d55a 100644
--- a/patterns.py
+++ b/patterns.py
@@ -1,114 +1,220 @@
 from machine import Pin
 from neopixel import NeoPixel
-import _thread
-import time, math
-import sys
+import utime
+import random
 
-class LedPatterns:
-    def __init__(self, pin, num_leds):
+class Patterns:
+    def __init__(self, pin, num_leds, color1=(0,0,0), color2=(0,0,0), brightness=127, selected="rainbow_cycle", delay=100):
+        self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds)
         self.num_leds = num_leds
-        self.np = NeoPixel(Pin(pin), num_leds)
-        self.run = True
+        self.pattern_step = 0
+        self.last_update = utime.ticks_ms()
+        self.delay = delay
+        self.brightness = brightness
+        self.patterns = {
+            "color_wipe": self.color_wipe_step,
+            "rainbow_cycle": self.rainbow_cycle_step,
+            "theater_chase": self.theater_chase_step,
+            "blink": self.blink_step,
+            "random_color_wipe": self.random_color_wipe_step,
+            "random_rainbow_cycle": self.random_rainbow_cycle_step,
+            "random_theater_chase": self.random_theater_chase_step,
+            "random_blink": self.random_blink_step,
+            "color_transition": self.color_transition_step  # Added color transition pattern
+        }
+        self.selected = selected
+        self.color1 = color1
+        self.color2 = color2
+        self.transition_duration = 5000  # Duration of color transition in milliseconds
+        self.transition_step = 0
     
-    def color_chase(self, color, wait):
-        self.run = True
+    def tick(self):
+        self.patterns[self.selected]()
+        
+    def update_num_leds(self, pin, num_leds):
+        self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds)
+        self.num_leds = num_leds
+        self.pattern_step = 0
+
+    def set_delay(self, delay):
+        self.delay = delay
+
+    def set_brightness(self, brightness):
+        self.brightness = brightness
+        
+    def set_color1(self, color):
+        print(color)
+        self.color1 = self.apply_brightness(color)
+        
+    def set_color2(self, color):
+        self.color2 = self.apply_brightness(color)
+    
+    def apply_brightness(self, color):
+        return tuple(int(c * self.brightness / 255) for c in color)
+    
+    def fill(self):
         for i in range(self.num_leds):
-            self.np[i] = color
-            self.np.write()
-            if not run:
-                break
-            time.sleep(wait)
-    
-    def wheel(self, pos):
-        if pos < 0 or pos > 255:
-            return (0, 0, 0)
-        if pos < 85:
-            return (255 - pos * 3, pos * 3, 0)
-        if pos < 170:
-            pos -= 85
-            return (0, 255 - pos * 3, pos * 3)
-        pos -= 170
-        return (pos * 3, 0, 255 - pos * 3)
-    
-    def rainbow_cycle(self, wait):
-        run = True
-        for j in range(255):
+            self.n[i] = self.color1
+        self.n.write()
+
+    def color_wipe_step(self):
+        color = self.apply_brightness(self.color1)
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            if self.pattern_step < self.num_leds:
+                for i in range(self.num_leds):
+                    self.n[i] = (0, 0, 0)
+                self.n[self.pattern_step] = color
+                self.n.write()
+                self.pattern_step += 1
+            else:
+                self.pattern_step = 0
+            self.last_update = current_time
+
+    def rainbow_cycle_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            def wheel(pos):
+                if pos < 85:
+                    return (pos * 3, 255 - pos * 3, 0)
+                elif pos < 170:
+                    pos -= 85
+                    return (255 - pos * 3, 0, pos * 3)
+                else:
+                    pos -= 170
+                    return (0, pos * 3, 255 - pos * 3)
+
             for i in range(self.num_leds):
-                self.np[i] = self.wheel((i * 256 // self.num_leds) + j)
-            self.np.write()
-            if not run:
-                break
-            time.sleep(wait)
-    
-    def breathing(self, color, duration):
-        steps = 256
-        for _ in range(steps):
-            brightness = int(255 * abs(steps / 2 - _) / (steps / 2))
-            self.np.fill((brightness * color[0] // 255, brightness * color[1] // 255, brightness * color[2] // 255))
-            self.np.write()
-            time.sleep(duration / steps)
-    
-    def color_transition(self, start_color, end_color, duration):
-        steps = 256
-        for step in range(steps):
-            color = (
-                int(start_color[0] + (end_color[0] - start_color[0]) * step / steps),
-                int(start_color[1] + (end_color[1] - start_color[1]) * step / steps),
-                int(start_color[2] + (end_color[2] - start_color[2]) * step / steps),
-            )
-            self.np.fill(color)
-            self.np.write()
-            if not self.running():
-                return
-            time.sleep(duration / steps)
+                rc_index = (i * 256 // self.num_leds) + self.pattern_step
+                self.n[i] = self.apply_brightness(wheel(rc_index & 255))
+            self.n.write()
+            self.pattern_step = (self.pattern_step + 1) % 256
+            self.last_update = current_time
+
+    def theater_chase_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            for i in range(self.num_leds):
+                if (i + self.pattern_step) % 3 == 0:
+                    self.n[i] = self.color1
+                else:
+                    self.n[i] = (0, 0, 0)
+            self.n.write()
+            self.pattern_step = (self.pattern_step + 1) % 3
+            self.last_update = current_time
+
+    def blink_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            if self.pattern_step % 2 == 0:
+                for i in range(self.num_leds):
+                    self.n[i] = self.color1
+            else:
+                for i in range(self.num_leds):
+                    self.n[i] = (0, 0, 0)
+            self.n.write()
+            self.pattern_step = (self.pattern_step + 1) % 2
+            self.last_update = current_time
+
+    def random_color_wipe_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
+            if self.pattern_step < self.num_leds:
+                for i in range(self.num_leds):
+                    self.n[i] = (0, 0, 0)
+                self.n[self.pattern_step] = self.apply_brightness(color)
+                self.n.write()
+                self.pattern_step += 1
+            else:
+                self.pattern_step = 0
+            self.last_update = current_time
+
+    def random_rainbow_cycle_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            def wheel(pos):
+                if pos < 85:
+                    return (pos * 3, 255 - pos * 3, 0)
+                elif pos < 170:
+                    pos -= 85
+                    return (255 - pos * 3, 0, pos * 3)
+                else:
+                    pos -= 170
+                    return (0, pos * 3, 255 - pos * 3)
+
+            random_offset = random.randint(0, 255)
+            for i in range(self.num_leds):
+                rc_index = (i * 256 // self.num_leds) + self.pattern_step + random_offset
+                self.n[i] = self.apply_brightness(wheel(rc_index & 255))
+            self.n.write()
+            self.pattern_step = (self.pattern_step + 1) % 256
+            self.last_update = current_time
+
+    def random_theater_chase_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
+            for i in range(self.num_leds):
+                if (i + self.pattern_step) % 3 == 0:
+                    self.n[i] = self.apply_brightness(color)
+                else:
+                    self.n[i] = (0, 0, 0)
+            self.n.write()
+            self.pattern_step = (self.pattern_step + 1) % 3
+            self.last_update = current_time
+
+    def random_blink_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
+            if self.pattern_step % 2 == 0:
+                for i in range(self.num_leds):
+                    self.n[i] = self.apply_brightness(color)
+            else:
+                for i in range(self.num_leds):
+                    self.n[i] = (0, 0, 0)
+            self.n.write()
+            self.pattern_step = (self.pattern_step + 1) % 2
+            self.last_update = current_time
+
+    def color_transition_step(self):
+        current_time = utime.ticks_ms()
+        if utime.ticks_diff(current_time, self.last_update) >= self.delay:
+            # Calculate transition factor based on elapsed time
+            transition_factor = (self.pattern_step * 100) / self.transition_duration
+            if transition_factor > 100:
+                transition_factor = 100
+            color = self.interpolate_color(self.color1, self.color2, transition_factor / 100)
             
-    def scanner(self, color, speed):
-        position = 0
-        direction = 1
-
-        while True:
-            self.np.fill((0, 0, 0))
-            self.np[position] = color
-            self.np.write()
-            time.sleep(speed)
-            position += direction
-            if position == self.num_leds - 1 or position == 0:
-                direction *= -1
-    
-    def bidirectional_scanner(self, color_left, color_right=None, speed=0.1):
-        color_right = color_right or color_left
-        position_left = 0
-        position_right = self.num_leds - 1
-        direction_left = 1
-        direction_right = -1
-        while True:
-            self.np.fill((0, 0, 0))
-            self.np[position_left] = color_left
-            self.np[position_right] = color_right
-            self.np.write()
-            time.sleep(speed)
-
-            position_left += direction_left
-            position_right += direction_right
-
-            if position_left == self.num_leds - 1 or position_left == 0:
-                direction_left *= -1
-            if position_right == self.num_leds - 1 or position_right == 0:
-                direction_right *= -1
-    
-    def sine_wave_propagation(self, color, speed):
-        frequency = 10
-        phase = 0
-        while True:
-            self.np.fill((0, 0, 0)) 
+            # Apply the interpolated color to all LEDs
             for i in range(self.num_leds):
-                brightness = int(127.5 * (math.sin(frequency * i + phase) + 1))
-                self.np[i] = (brightness * color[0] // 255, brightness * color[1] // 255, brightness * color[2] // 255)
-            self.np.write()
-            time.sleep(speed)
-            phase += 0.1
+                self.n[i] = self.apply_brightness(color)
+            self.n.write()
 
-    def fill(self,color):
-        for i in range(self.num_leds):
-            self.np[i] = color
-            self.np.write()
+            self.pattern_step += self.delay
+            if self.pattern_step > self.transition_duration:
+                self.pattern_step = 0
+
+            self.last_update = current_time
+
+    def interpolate_color(self, color1, color2, factor):
+        return (
+            int(color1[0] + (color2[0] - color1[0]) * factor),
+            int(color1[1] + (color2[1] - color1[1]) * factor),
+            int(color1[2] + (color2[2] - color1[2]) * factor)
+        )
+
+if __name__ == "__main__":
+    p = Patterns(4, 180)
+    p.set_color1((255,0,0))
+    p.set_color2((0,255,0))
+    try:
+        while True:
+            for key in p.patterns:
+                print(key)
+                for _ in range(1000):
+                    p.tick()
+                    utime.sleep_ms(1)
+    except KeyboardInterrupt:
+        p.fill((0, 0, 0))
diff --git a/scripts.js b/scripts.js
new file mode 100644
index 0000000..87a7e8e
--- /dev/null
+++ b/scripts.js
@@ -0,0 +1,61 @@
+let delayTimeout;
+
+function post(path, value) {
+    fetch(path, {
+        method: "POST",
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+        body: encodeURIComponent(value)
+    });
+}
+
+function get(path, value) {
+    fetch(path, {
+        method: "GET",
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+function updateColor() {
+    const color = document.getElementById('color').value;
+    post("POST", "/color", color);
+}
+
+function updatePattern(pattern) {
+    const patternButtons = document.querySelectorAll('button[name="pattern"]');
+    //patternButtons.forEach(button => button.disabled = true);
+    post("/pattern", pattern);
+}
+
+function updateDelay() {
+    clearTimeout(delayTimeout);
+    delayTimeout = setTimeout(function() {
+        const delay = document.getElementById('delay').value;
+        post('/delay', delay);
+    }, 500);
+}
+
+function updateNumLeds(event) {
+    event.preventDefault();
+    const numLeds = document.getElementById('num_leds').value;
+    post('/num_leds', numLeds);
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+    document.getElementById('color').addEventListener('input', updateColor);
+    document.getElementById('delay').addEventListener('input', updateDelay);
+    document.getElementById('led_form').addEventListener('submit', updateNumLeds);
+
+    const patternButtons = document.querySelectorAll('button[name="pattern"]');
+    patternButtons.forEach(function(button) {
+        button.addEventListener('click', function(event) {
+            event.preventDefault();
+            const pattern = this.value;
+            updatePattern(pattern);
+        });
+    });
+});
+
diff --git a/styles.css b/styles.css
new file mode 100644
index 0000000..418247e
--- /dev/null
+++ b/styles.css
@@ -0,0 +1,79 @@
+body {
+    font-family: Arial, sans-serif;
+    padding: 20px;
+}
+
+h1, h2 {
+    color: #333;
+}
+
+form {
+    margin-bottom: 20px;
+}
+
+input[type="number"], input[type="color"], input[type="range"] {
+    margin-right: 10px;
+}
+
+button {
+    padding: 5px 10px;
+    background-color: #007bff;
+    color: white;
+    border: none;
+    border-radius: 5px;
+    cursor: pointer;
+}
+
+button:hover {
+    background-color: #0056b3;
+}
+
+#delay_value {
+    display: inline-block;
+    width: 80px;
+}
+
+#patterns_radio_buttons label {
+    display: block;
+}
+body {
+    font-family: Arial, sans-serif;
+    background-color: #f0f0f0;
+    margin: 0;
+    padding: 20px;
+}
+
+h1 {
+    color: #333;
+}
+
+form {
+    margin-bottom: 20px;
+}
+
+label {
+    display: block;
+    margin-bottom: 5px;
+    font-weight: bold;
+}
+
+input[type="text"],
+input[type="range"],
+input[type="color"],
+button {
+    margin-bottom: 10px;
+    padding: 10px;
+    font-size: 16px;
+}
+
+button:disabled {
+    background-color: #ccc;
+}
+
+button {
+    margin-right: 5px;
+    padding: 10px 20px;
+    font-size: 16px;
+    cursor: pointer;
+}
+