diff --git a/frontend/src/components/AvailabilityPicker.tsx b/frontend/src/components/AvailabilityPicker.tsx
index 0b1554f..86fa02b 100644
--- a/frontend/src/components/AvailabilityPicker.tsx
+++ b/frontend/src/components/AvailabilityPicker.tsx
@@ -1,11 +1,13 @@
-import { Box, Card, Divider, Stack, Typography } from "@mui/material";
+import { Box, Card, Divider, Stack, Theme, Typography, useTheme } from "@mui/material";
 import dayjs, { Dayjs } from "dayjs";
-import { useEffect, useState } from "react";
+import { MouseEvent, ReactNode, useEffect, useState } from "react";
 import * as utc from 'dayjs/plugin/utc';
 import * as timezone from 'dayjs/plugin/timezone';
 import * as localizedFormat from 'dayjs/plugin/localizedFormat';
 import utils from "../utils";
 import { EventTypes } from "../types/Event";
+import "./css/AvailabilityPicker.css";
+// import { alpha } from '@material-ui/core/styles/colorManipulator';
 
 dayjs.extend(utc)
 dayjs.extend(timezone)
@@ -21,6 +23,13 @@ type AvailabilityDay = {
     availableTimes: AvailabilityTime[]
 }
 
+type GhostPreviewProps = {
+    top: number,
+    left: number,
+    width: String,
+    height: String
+}
+
 const HALFHOUR_DISPLAY_HEIGHT: number = 15;
 
 const DAY_DISPLAY_WIDTH: String = "150px";
@@ -31,9 +40,10 @@ export default function AvailabilityPicker(props: {
     eventType: String,
     availabilityDurationInMinutes: number
 }) {
+    const theme: Theme = useTheme();
+
     const [days, setDays] = useState<AvailabilityDay[]>([]);
-    const [selectingAvailabilityForDay, setAvailabilityDayBeingSelectedFor] = useState<AvailabilityDay | null>(null);
-    const [currentAvailabilityTime, setAvailabilityTime] = useState<AvailabilityTime | null>(null);
+    const [ghostPreviewProps, setGhostPreviewProps] = useState<GhostPreviewProps | null>();
 
     useEffect(() => {
         let localTimezone = dayjs.tz.guess();
@@ -61,10 +71,6 @@ export default function AvailabilityPicker(props: {
         }
     }, [props]);
 
-    useEffect(() => {
-        console.log(days)
-    }, [days])
-
     function createAvailabilitiesBasedOnUnspecifiedInitialDate(numberOfDays: number, tz: string) {
         createAvailabilitiesBasedOnInitialDate(dayjs.tz("1970-01-05 00:00:00", tz), numberOfDays);
     }
@@ -84,131 +90,117 @@ export default function AvailabilityPicker(props: {
         setDays(availabilities);
     }
 
-    function clearAvailabilityTimeSelection() {
-        setAvailabilityDayBeingSelectedFor(null);
-        setAvailabilityTime(null);
+    function displayGhostPeriod(e: React.MouseEvent<HTMLDivElement, MouseEvent>, time: Dayjs) {
+        let timeInMinutes = (time.hour() * 60) + time.minute();
+        let timeLeftInDayLessThanDuration = (timeInMinutes + props.availabilityDurationInMinutes) > 24 * 60;
+
+        if (timeLeftInDayLessThanDuration) {
+            return;
+        }
+
+        let scrollTop = document.getElementById('availability-picker')?.scrollTop ?? 0;
+        let scrollLeft = document.getElementById('availability-picker')?.scrollLeft ?? 0;
+
+        const element = e.target.getBoundingClientRect();
+
+        setGhostPreviewProps({
+            top: e.target?.offsetTop - scrollTop,
+            left: e.target?.offsetLeft - scrollLeft,
+            width: element.width,
+            height: `${(props.availabilityDurationInMinutes/60) * 2 * HALFHOUR_DISPLAY_HEIGHT}px`
+        })
     }
 
-    function beginAvailabilityTimeSelection(e: React.MouseEvent<HTMLDivElement, MouseEvent>, day: AvailabilityDay, startTime: Dayjs) {
-        setAvailabilityDayBeingSelectedFor(day);
-        setAvailabilityTime({
-            fromTime: startTime,
-            toTime: startTime
+    function createAvailability(day: AvailabilityDay, time: Dayjs) {
+        let fromTime = time;
+        let toTime = time.add(props.availabilityDurationInMinutes, "minutes");
+
+        let existingTimeContainingFrom = day.availableTimes.findIndex(t => (t.fromTime.isBefore(fromTime) || t.fromTime.isSame(fromTime)) && (t.toTime.isAfter(fromTime) || t.toTime.isSame(fromTime)));
+        let existingTimeContainingTo = day.availableTimes.findIndex(t => (t.fromTime.isBefore(toTime) || t.fromTime.isSame(toTime)) && (t.toTime.isAfter(toTime) || t.toTime.isSame(toTime)));
+
+        // the newly created availability crosses another single one. Both have the same from and to. Do nothing.
+        if (existingTimeContainingFrom >= 0 && existingTimeContainingTo >= 0 && existingTimeContainingFrom === existingTimeContainingTo) {
+            return;
+        }
+
+        // the newly created availability crosses 2 existing ones. Combine all of them into a single one.
+        if (existingTimeContainingFrom >= 0 && existingTimeContainingTo >= 0 && existingTimeContainingFrom !== existingTimeContainingTo) {
+            let newFrom = day.availableTimes[existingTimeContainingFrom].fromTime;
+            let newTo = day.availableTimes[existingTimeContainingFrom].toTime;
+
+            day.availableTimes.splice(existingTimeContainingFrom);
+            day.availableTimes.splice(existingTimeContainingTo);
+
+            day.availableTimes.push({
+                fromTime: newFrom,
+                toTime: newTo
+            });
+
+            return;
+        }
+
+        // The newly created availability from is within an existing one. Combine the 2 into one.
+        if (existingTimeContainingFrom >= 0 && existingTimeContainingTo < 0) {
+            let newFrom = day.availableTimes[existingTimeContainingFrom].fromTime;
+
+            day.availableTimes.splice(existingTimeContainingFrom);
+
+            day.availableTimes.push({
+                fromTime: newFrom,
+                toTime: toTime
+            });
+
+            return;
+        }
+
+        // The newly created availability to is within an existing one. Combine the 2 into one.
+        if (existingTimeContainingFrom >= 0 && existingTimeContainingTo < 0) {
+            let newTo = day.availableTimes[existingTimeContainingFrom].toTime;
+
+            day.availableTimes.splice(existingTimeContainingFrom);
+
+            day.availableTimes.push({
+                fromTime: fromTime,
+                toTime: newTo
+            });
+
+            return;
+        }
+
+        day.availableTimes.push({
+            fromTime: fromTime,
+            toTime: toTime
         });
-    }
 
-    function finishAvailabilityTimeSelection(e: React.MouseEvent<HTMLDivElement, MouseEvent>, day: AvailabilityDay) {
-        if (currentAvailabilityTime === null) {
-            return;
-        }
-
-        day.availableTimes.push(currentAvailabilityTime);
         setDays([...days])
-
-        clearAvailabilityTimeSelection();
     }
 
-    function addTimeToAvailabilityTimeSelection(e: React.MouseEvent<HTMLDivElement, MouseEvent>, day: AvailabilityDay, time: Dayjs) {
-        if (e.buttons !== 1) {
-            return;
-        }
-
-        if (currentAvailabilityTime === null) {
-            return;
-        }
-
-        if (currentAvailabilityTime !== null && selectingAvailabilityForDay !== null && Math.abs(selectingAvailabilityForDay.forDate.diff(time, "day")) >= 1) {
-            clearAvailabilityTimeSelection();
-            return;
-        }
-
-        let currentFrom = currentAvailabilityTime.fromTime;
-        let currentTo = currentAvailabilityTime.toTime;
-
-        if (time.isBefore(currentFrom)) {
-            setAvailabilityTime({
-                fromTime: time,
-                toTime: currentTo
-            })
-
-            return;
-        }
-
-        if (time.isAfter(currentTo)) {
-            setAvailabilityTime({
-                fromTime: currentFrom,
-                toTime: time
-            })
-
-            return;
-        }
-    }
-
-    function currentAvailabilityTimeSelectionIncludes(time: Dayjs): boolean {
-        if (currentAvailabilityTime === null) {
-            return false;
-        }
-
-        if ((time.isAfter(currentAvailabilityTime.fromTime) && time.isBefore(currentAvailabilityTime.toTime)) || (time.isSame(currentAvailabilityTime.toTime) || time.isSame(currentAvailabilityTime.fromTime))) {
-            return true;
-        }
-
-        return false;
-    }
-
-    function isTimeIncludedInAnyAvailabilityPeriod(day: AvailabilityDay, time: Dayjs): boolean {
-        return day.availableTimes.some(t => t.fromTime.isBefore(time) && t.toTime.isAfter(time));
-    }
-
-    function isTimeBeginningOfAnyAvailabilityPeriod(day: AvailabilityDay, time: Dayjs): boolean {
-        return day.availableTimes.some(t => t.fromTime.isSame(time));
-    }
-
-    function isTimeEndingOfAnyAvailabilityPeriod(day: AvailabilityDay, time: Dayjs): boolean {
-        return day.availableTimes.some(t => t.toTime.isSame(time));
+    function isSelectedAvailability(day: AvailabilityDay, time: Dayjs): boolean {
+        return day.availableTimes.some(t => (t.fromTime.isBefore(time) || t.fromTime.isSame(time)) && (t.toTime.isAfter(time) || t.toTime.isSame(time)));
     }
 
     function generateDay(day: AvailabilityDay) {
 
-        const HOVER_COLOR: String = "#004455";
-        const HOUR_LIGHT_COLOR: String = "#002233";
-        const HOUR_DARK_COLOR: String = "#003344";
-        const HOUR_BORDER_COLOR: String = "#777";
-        const ACTIVE_COLOR: String = "#223300";
-        const CURRENTLY_SELECTED_COLOR: String = "#112200";
         const HOUR_TEXT_COLOR: String = "#ddd";
-        const HALFHOUR_BORDER_COLOR: String = "#333";
 
-        let hours = [...Array<String>(24)].map((_, i) => {
+        let hours = [];
+
+        for (var i = 0; i < 24; i++) {
             let time = day.forDate.set("hour", i).set("minute", 0).set("second", 0);
 
-            return (
+            hours.push(
                 <Box 
                     key={`${i}`} 
-                    sx={{ 
-                        width: "100%",                             
-                        borderBottom: 1,
-                        borderColor: HOUR_BORDER_COLOR,
-                        bgcolor: (i % 2 == 0) ? HOUR_LIGHT_COLOR : HOUR_DARK_COLOR,
-                        ":hover": {
-                            bgcolor: HOVER_COLOR
-                        }
-                    }}
+                    className={(i % 2 == 0) ? "hour-light" : "hour-dark"}
                 >
                     <Box
-                        sx={{
-                            width: "100%",
-                            height: HALFHOUR_DISPLAY_HEIGHT,
-                            borderBottom: 1,
-                            borderColor: HALFHOUR_BORDER_COLOR,
-                            ":active": {
-                                bgcolor: ACTIVE_COLOR
-                            },
-                            bgcolor: currentAvailabilityTimeSelectionIncludes(time) ? CURRENTLY_SELECTED_COLOR : "inherit"
-                        }}
-                        onMouseDown={(e) => beginAvailabilityTimeSelection(e, day, time)}
-                        onMouseUp={(e) => finishAvailabilityTimeSelection(e, day)}
-                        onMouseOver={(e) => addTimeToAvailabilityTimeSelection(e, day, time)}
+                        className={[ 
+                            "full-hour",
+                            isSelectedAvailability(day, time) && "selected-availability"
+                        ]}
+                        height={HALFHOUR_DISPLAY_HEIGHT}
+                        onMouseEnter={(e: MouseEvent<HTMLDivElement, MouseEvent>) => displayGhostPeriod(e, time)}
+                        onClick={(e) => createAvailability(day, time)}
                     >
                         <Typography
                             className={"noselect"}
@@ -220,23 +212,18 @@ export default function AvailabilityPicker(props: {
                         </Typography>
                     </Box>
                     <Box
-                        sx={{
-                            width: "100%",
-                            height: HALFHOUR_DISPLAY_HEIGHT,
-                            ":active": {
-                                bgcolor: ACTIVE_COLOR
-                            },
-                            bgcolor: currentAvailabilityTimeSelectionIncludes(time.set("minute", 30)) ? CURRENTLY_SELECTED_COLOR : "inherit"
-                        }}
-                        onMouseDown={(e) => beginAvailabilityTimeSelection(e, day, time.set("minute", 30))}
-                        onMouseUp={(e) => finishAvailabilityTimeSelection(e, day)}
-                        onMouseOver={(e) => addTimeToAvailabilityTimeSelection(e, day, time.set("minute", 30))}
+                        className={[ 
+                            "half-hour",
+                            isSelectedAvailability(day, time) && "selected-availability"
+                        ]}
+                        height={HALFHOUR_DISPLAY_HEIGHT}
+                        onMouseEnter={(e: MouseEvent<HTMLDivElement, MouseEvent>) => displayGhostPeriod(e, time.add(30, "minutes"))}
+                        onClick={(e) => createAvailability(day, time.add(30, "minutes"))}
                     >
                     </Box>
                 </Box>
-                
             );
-        })
+        }
 
         return (
             <Stack 
@@ -255,7 +242,6 @@ export default function AvailabilityPicker(props: {
                         overflow: "visible" 
                     }}
                     variant="outlined"
-                    onMouseLeave={(e) => clearAvailabilityTimeSelection()}
                 >
                     <Box
                         sx={{ width: "100%" }}
@@ -281,6 +267,7 @@ export default function AvailabilityPicker(props: {
                         }
                     </Box>
                     <Divider></Divider>
+
                     {hours}
                 </Card>
             </Stack>
@@ -288,21 +275,51 @@ export default function AvailabilityPicker(props: {
     }
 
     return (
-        <Stack 
-            direction="row" 
-            spacing={1} 
-            justifyContent={"safe center"} 
+        <Box
             sx={{ 
+                position: "relative",
                 width: "100%", 
-                height: "auto", 
-                maxHeight: "500px",  
-                overflowY: "scroll", 
-                overflowX: "scroll" 
-            }} 
+                height: "auto",
+                overflow: "hidden"
+            }}
         >
+            <Stack
+                id="availability-picker" 
+                direction="row" 
+                spacing={1} 
+                justifyContent={"safe center"} 
+                sx={{ 
+                    width: "100%", 
+                    height: "500px", 
+                    overflowY: "scroll",
+                    overflowX: "scroll"
+                }}
+                onScroll={(e) => setGhostPreviewProps(null)}
+            >
+                {
+                    days.map(a => generateDay(a))
+                }
+            </Stack>
             {
-                days.map(a => generateDay(a))
+                (ghostPreviewProps !== null) &&
+                <Box
+                    sx={{
+                        position: "absolute",
+                        top: ghostPreviewProps?.top,
+                        left: ghostPreviewProps?.left,
+                        width: ghostPreviewProps?.width,
+                        height: ghostPreviewProps?.height,
+                        bgcolor: "rgba(0, 255, 0, 0.1)",
+                        border: 1,
+                        borderColor: "#272",
+                        borderRadius: 1,
+                        m: 0,
+                        p: 0,
+                        pointerEvents: "none"
+                    }}
+                >
+                </Box>
             }
-        </Stack>
+        </Box>
     );
 }
\ No newline at end of file
diff --git a/frontend/src/components/css/AvailabilityPicker.css b/frontend/src/components/css/AvailabilityPicker.css
new file mode 100644
index 0000000..f011ea4
--- /dev/null
+++ b/frontend/src/components/css/AvailabilityPicker.css
@@ -0,0 +1,46 @@
+:root {
+    --hover-color: #004455;
+    --hour-light-color: #003344;
+    --hour-dark-color: #002233;
+    --hour-border-bolor: #777;
+    --hour-text-color: #ddd;
+    --active-color: #223300;
+    --currently-selected-color: #112200;
+    --halfhour-border-color: #333;
+}
+
+div.hour-light {
+    width: 100%;
+    border-bottom: solid 1px;
+    border-color: var(--hour-border-bolor);
+    background-color: var(--hour-light-color);
+}
+
+div.hour-dark {
+    width: 100%;
+    border-bottom: solid 1px;
+    border-color: var(--hour-border-bolor);
+    background-color: var(--hour-dark-color);
+}
+
+div.full-hour {
+    width: 100%;
+    border-bottom: dashed 1px;
+    border-color: var(--halfhour-border-color)
+}
+
+div.half-hour {
+    width: 100%;
+}
+
+div.selected-availability {
+    background-color: var(--currently-selected-color);
+}
+
+div.full-hour:hover, div.half-hour:hover {
+    background-color: var(--hover-color);
+}
+
+div.full-hour:active, div.half-hour:active {
+    background-color: var(--active-color);
+}
\ No newline at end of file