Index: components/Alert.jsx
===================================================================
--- components/Alert.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/Alert.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,85 @@
+import React from 'react'
+
+import { useSelector, useDispatch } from 'react-redux'
+
+import { HiOutlineArrowNarrowRight } from 'react-icons/hi'
+
+import axios from 'axios'
+
+import { setBlackjack, setStyle } from '../redux/reducers/styleSlice'
+import { setGame, setPlayer } from '../redux/reducers/playerSlice'
+
+const Alert = () => {
+    const playerState = useSelector(state => state.player)
+    const styleState = useSelector(state => state.style)
+
+    const dispatch = useDispatch()
+
+    const display = styleState?.style?.alert?.show ? 'flex' : 'none'
+
+    function clicked() {
+        dispatch(setStyle({
+            ...styleState.style,
+            alert: {
+                ...styleState.style.alert,
+                show: false
+            }
+        }))
+
+        if (styleState.style.alert.button.action === 'play_again') {
+            axios.get(`/api/blackjack?action=play_again&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+                if (res.data?.success && res.data?.game) {
+                    dispatch(setGame({
+                        ...playerState.game,
+                        status: res.data.game?.status,
+                        playerCards: res.data.game?.playerCards,
+                        dealerCards: res.data.game?.dealerCards,
+                        sideBetName: res.data.game?.sideBetName,
+                    }))
+
+                    dispatch(setBlackjack({
+                        ...styleState.blackjack,
+                        inputControls: {
+                            ...styleState.blackjack.inputControls,
+                            initialBet: {
+                                ...styleState.blackjack.inputControls.initialBet,
+                                chosenCredits: parseInt(playerState.player.credits/2),
+                            },
+                            sideBet: {
+                                ...styleState.blackjack.inputControls.sideBet,
+                                chosenCredits: parseInt(0),
+                            }
+                        },
+                        displays: {
+                            ...styleState.blackjack.displays,
+                            initialBet: true,
+                            hitStand: false,
+                        }
+                    }))
+                }
+            });
+        }
+        else if (styleState.style.alert.button.action === 'continue_from_side_bet') {
+            dispatch(setBlackjack({
+                ...styleState.blackjack,
+                inputControls: {
+                    ...styleState.blackjack.inputControls,
+                    sideBet: {
+                        ...styleState.blackjack.inputControls.sideBet,
+                        chosenCredits: parseInt(0),
+                    }
+                },
+            }))
+        }
+    }
+
+    return (
+        <div className="alert" style={{display: display}}>
+            <h1>{styleState.style.alert.title}</h1>
+            <h3>{styleState.style.alert.subtitle}</h3>
+            <button className='primaryButton' onClick={() => clicked()}>{styleState.style.alert.button.text} <HiOutlineArrowNarrowRight style={{marginTop: '3px', marginBottom: '-3px'}} /></button>
+        </div>
+    )
+}
+
+export default Alert
Index: components/Card.jsx
===================================================================
--- components/Card.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/Card.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,13 @@
+import React from 'react'
+
+const Card = ( { card, pos, rotateZ } ) => {
+    const src = `/cards/${card}.png`;
+
+    return (
+      <div className="card" style={{backgroundImage: `url("${src}")`, left: `${pos?.left}vw`, top: `${pos?.top}vh`, transform: `translate(-50%, -50%) rotateZ(${rotateZ}deg)`}}>
+        
+      </div>
+    )
+}
+
+export default Card
Index: components/FullwidthText.jsx
===================================================================
--- components/FullwidthText.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/FullwidthText.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,16 @@
+import React from 'react'
+
+import { useSelector } from 'react-redux'
+
+const FullwidthText = ({title, subtitle}) => {
+  const playerState = useSelector(state => state.player);
+
+  return (
+    <div className="fullwidthText">
+      <h1>{title}, {playerState.player.displayName}</h1>
+      <h3>{subtitle}</h3>
+   </div>
+  )
+}
+
+export default FullwidthText
Index: components/GameCircle.jsx
===================================================================
--- components/GameCircle.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/GameCircle.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,47 @@
+import React from 'react'
+
+import { ArcText } from '@arctext/react'
+
+import { useRouter } from 'next/router'
+
+import { useState } from 'react'
+
+import { setInGame } from '../redux/reducers/playerSlice'
+import { useDispatch } from 'react-redux'
+import FullwidthText from './FullwidthText'
+
+const GameCircle = ( { src, text, routeTo, game } ) => {
+  const router = useRouter()
+
+  function clicked() {
+    router.push(routeTo)
+  }
+
+  return (
+    <div className="gameCircle" onClick={() => clicked()}>
+        <div className="circleLarge">
+            <div className="circle" style={{backgroundImage: `url('${src}')`}}>
+
+            </div>
+        </div>
+        <h3>
+            <ArcText
+                text={text}
+                upsideDown
+                width={600}
+                characterWidth={4.8}
+                style={{color: 'white',
+                        position: 'relative',
+                        transform: 'rotateZ(180deg) scaleX(-1)',
+                        marginTop: '30px',
+                        fontSize: '1.6rem',
+                        color: '#FFD700',
+                        fontWeight: 'bold'
+                }}
+            />
+        </h3>
+    </div>
+  )
+}
+
+export default GameCircle
Index: components/Header.jsx
===================================================================
--- components/Header.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/Header.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,150 @@
+import React from 'react'
+
+import Link from 'next/link'
+
+import { useRouter } from 'next/router'
+
+import { useState, useEffect } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
+
+import { setPlayer } from '../redux/reducers/playerSlice'
+import { setStyle } from '../redux/reducers/styleSlice'
+
+import axios from 'axios';
+
+const Header = () => {
+  const dispatch = useDispatch();
+
+  const playerState = useSelector(state => state.player);
+  const styleState = useSelector(state => state.style);
+
+  function register() {
+    dispatch(setStyle({
+      ...styleState.style,
+      displayRegisterScreen: true,
+    }))
+  }
+
+  function login() {
+    dispatch(setStyle({
+      ...styleState.style,
+      displayLoginScreen: true,
+    }))
+  }
+
+  function logout() {
+    axios.get(`/api/postgre?action=logout&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+      if (res.data?.success) {
+        localStorage.removeItem('CAESSINO_SESSION_ID');
+        dispatch(setPlayer({
+          displayName: '',
+          username: '',
+          session_id: '',
+          room_id: '',
+          credits: 0,
+        }))
+      }
+    })
+  }
+
+  function showStats() {
+    axios.get(`/api/postgre?action=get_stats&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+      if (res.data?.success) {
+        dispatch(setStyle({
+            ...styleState.style,
+            displayStatsScreen: true,
+            statsScreenInfo: {
+                money: {
+                    ...styleState.style.statsScreenInfo.money,
+                    earned: res.data.stats.money_earned,
+                },
+                blackjack: {
+                    ...styleState.style.statsScreenInfo.blackjack,
+                    wins: res.data.stats.blackjack_won_games,
+                },
+                roulette: {
+                    ...styleState.style.statsScreenInfo.roulette,
+                    wins: res.data.stats.roulette_won_games,
+                },
+                poker: {
+                    ...styleState.style.statsScreenInfo.poker,
+                    wins: res.data.stats.poker_won_games,
+                }                            
+            }
+        }))
+      }
+    })
+  }
+
+  function manageCredits() {
+    dispatch(setStyle({
+      ...styleState.style,
+      displayManageCreditsScreen: true,
+    }))
+  }
+
+  useEffect(() => {
+    if (playerState.player.displayName === '') {
+      dispatch(setStyle({
+        ...styleState.style,
+        displayLoadingScreen: true
+      }));
+
+      let success = false;
+
+      if (localStorage?.CAESSINO_SESSION_ID && localStorage.CAESSINO_SESSION_ID.length > 0) {
+        axios.get(`/api/postgre?action=check_if_logged_in&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+          if (res.data?.success) {
+            success = true;
+
+            dispatch(setPlayer({
+              ...playerState.player,
+              displayName: res.data?.displayName,
+              sesssion_id: res.data?.session_id,
+              credits: res.data?.credits,
+            }));
+          }
+        });
+      }
+
+      if (!success) {
+        dispatch(setPlayer({
+          ...playerState.player,
+          displayName: 'Guest',
+        }))
+        dispatch(setStyle({
+          ...styleState.style,
+          displayLoadingScreen: false,
+        }))
+      }
+    }
+  }, [dispatch, playerState.player, styleState.style]);
+
+  return (
+    <header className="header">
+      <Link href="/" passHref>
+        <div className="logo">
+          
+        </div>
+      </Link>
+      <nav>
+          <ul>
+            {playerState.player.displayName === '' || playerState.player.displayName === 'Guest' ? (
+              <>
+                <li onClick={() => {register()}}>Register</li>
+                <li onClick={() => {login()}}>Login</li>
+              </>
+            ) : (
+              <>
+                <li onClick={() => {manageCredits()}}>Manage Credits</li>
+                <li onClick={() => {showStats()}}>Stats</li>
+                <li onClick={() => {logout()}}>Logout</li>
+              </>
+            )}
+          </ul>
+      </nav>
+  </header>
+  )
+}
+
+export default Header
Index: components/InGameHeader.jsx
===================================================================
--- components/InGameHeader.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/InGameHeader.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,269 @@
+import React from 'react'
+
+import Link from 'next/link'
+
+import { useRouter } from 'next/router'
+
+import { AiOutlineArrowLeft } from 'react-icons/ai'
+
+import { useState, useEffect } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
+
+import { setGame, setPlayer } from '../redux/reducers/playerSlice'
+import { setBlackjack, setStyle } from '../redux/reducers/styleSlice'
+
+import axios from 'axios';
+
+const InGameHeader = () => {
+    const dispatch = useDispatch();
+
+    const router = useRouter();
+
+    const playerState = useSelector(state => state.player);
+    const styleState = useSelector(state => state.style);
+
+    useEffect(() => {
+        // display loading screen
+        dispatch(setStyle({
+            ...styleState.style,
+            displayLoadingScreen: true,
+        }));
+
+        dispatch(setBlackjack({
+            ...styleState.blackjack,
+            inputControls: {
+                ...styleState.blackjack.inputControls,
+                initialBet: {
+                    ...styleState.blackjack.inputControls.initialBet,
+                    chosenCredits: parseInt(playerState.player.credits/2),
+                }
+            }
+        }));
+
+        axios.get(`/api/postgre?action=get_player_info_on_enter&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(postgreRes => {
+            if (postgreRes.data?.success) {
+                dispatch(setPlayer({
+                    ...playerState.player,
+                    displayName: postgreRes.data?.displayName,
+                    session_id: postgreRes.data?.session_id,
+                    credits: postgreRes.data?.credits,
+                }));
+
+                axios.get(`/api/blackjack?action=get_player_info_on_enter&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+                    if (res.data?.success) {
+                        dispatch(setGame({
+                            ...playerState.game,
+                            status: res.data?.status,
+                            playerCards: res.data?.playerCards,
+                            dealerCards: res.data?.dealerCards,
+                        }))
+
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            displayLoadingScreen: false,
+                        }))
+
+                        if (parseInt(res.data?.status.toString().substr(1, 1)) == 5) {
+                            dispatch(setBlackjack({
+                                ...styleState.blackjack,
+                                inputControls: {
+                                    ...styleState.blackjack.inputControls,
+                                    initialBet: {
+                                        ...styleState.blackjack.inputControls.initialBet,
+                                        chosenCredits: parseInt(res.data?.initialBet),
+                                    },
+                                    sideBet: {
+                                        ...styleState.blackjack.inputControls.sideBet,
+                                        chosenCredits: 0,
+                                    }
+                                },
+                                displays: {
+                                    ...styleState.blackjack.displays,
+                                    initialBet: false,
+                                    hitStand: true,
+                                }
+                            }))
+
+                            if (res.data?.outcome === 'player_busted') {
+                                dispatch(setStyle({
+                                    ...styleState.style,
+                                    alert: {
+                                        show: true,
+                                        title: 'You busted!',
+                                        subtitle: `You lost $${-1*res.data?.earnings}`,
+                                        button: {
+                                            text: 'Play again',
+                                            action: 'play_again',
+                                        }
+                                    }
+                                }))
+                            }
+                            else if (res.data?.outcome === 'dealer_busted') {
+                                dispatch(setStyle({
+                                    ...styleState.style,
+                                    alert: {
+                                        show: true,
+                                        title: 'Dealer busted!',
+                                        subtitle: `You won $${res.data?.earnings}`,
+                                        button: {
+                                            text: 'Play again',
+                                            action: 'play_again',
+                                        }
+                                    }
+                                }))
+                            }
+                            else if (res.data?.outcome === 'player_won') {
+                                dispatch(setStyle({
+                                    ...styleState.style,
+                                    alert: {
+                                        show: true,
+                                        title: 'You won!',
+                                        subtitle: `You won $${res.data?.earnings}`,
+                                        button: {
+                                            text: 'Play again',
+                                            action: 'play_again',
+                                        }
+                                    }
+                                }))
+                            }
+                            else if (res.data?.outcome === 'player_lost') {
+                                dispatch(setStyle({
+                                    ...styleState.style,
+                                    alert: {
+                                        show: true,
+                                        title: 'You lost!',
+                                        subtitle: `You lost $${-1*res.data?.earnings}`,
+                                        button: {
+                                            text: 'Play again',
+                                            action: 'play_again',
+                                        }
+                                    }
+                                }))
+                            }
+                            else if (res.data?.outcome === 'draw') {
+                                dispatch(setStyle({
+                                    ...styleState.style,
+                                    alert: {
+                                        show: true,
+                                        title: 'Draw!',
+                                        subtitle: `You got your $${res.data?.earnings} back`,
+                                        button: {
+                                            text: 'Play again',
+                                            action: 'play_again',
+                                        }
+                                    }
+                                }))
+                            }
+                        }
+
+                        if (parseInt(res.data?.status.toString().substr(1, 1)) == 4) {
+                            dispatch(setBlackjack({
+                                ...styleState.blackjack,
+                                inputControls: {
+                                    ...styleState.blackjack.inputControls,
+                                    initialBet: {
+                                        ...styleState.blackjack.inputControls.initialBet,
+                                        chosenCredits: parseInt(res.data?.initialBet),
+                                    },
+                                    sideBet: {
+                                        ...styleState.blackjack.inputControls.sideBet,
+                                        chosenCredits: 0,
+                                    }
+                                },
+                                displays: {
+                                    ...styleState.blackjack.displays,
+                                    initialBet: false,
+                                    hitStand: true,
+                                }
+                            }))
+                        }
+
+                        if (parseInt(res.data?.status.toString().substr(1, 1)) == 3) {
+                            dispatch(setBlackjack({
+                                ...styleState.blackjack,
+                                inputControls: {
+                                    ...styleState.blackjack.inputControls,
+                                    initialBet: {
+                                        ...styleState.blackjack.inputControls.initialBet,
+                                        chosenCredits: parseInt(res.data?.initialBet),
+                                    },
+                                    sideBet: {
+                                        ...styleState.blackjack.inputControls.sideBet,
+                                        chosenCredits: parseInt(res.data?.sideBet),
+                                    }
+                                },
+                                displays: {
+                                    ...styleState.blackjack.displays,
+                                    initialBet: false,
+                                    hitStand: true,
+                                }
+                            }))
+                        }
+
+                        if (parseInt(res.data?.status.toString().substr(1, 1)) == 2) {
+                            dispatch(setBlackjack({
+                                ...styleState.blackjack,
+                                inputControls: {
+                                    ...styleState.blackjack.inputControls,
+                                    initialBet: {
+                                        ...styleState.blackjack.inputControls.initialBet,
+                                        chosenCredits: parseInt(res.data?.initialBet),
+                                    }
+                                },
+                                displays: {
+                                    ...styleState.blackjack.displays,
+                                    initialBet: false,
+                                    sideBet: true,
+                                }
+                            }))
+                        }
+
+                        if (parseInt(res.data?.status.toString().substr(1, 1)) == 1) {
+                            dispatch(setBlackjack({
+                                ...styleState.blackjack,
+                                inputControls: {
+                                    ...styleState.blackjack.inputControls,
+                                    initialBet: {
+                                        ...styleState.blackjack.inputControls.initialBet,
+                                        chosenCredits: parseInt(postgreRes.data?.credits/2),
+                                    }
+                                },
+                            }))
+                        }
+                    }
+                });
+            }
+            else {
+                dispatch(setStyle({
+                    ...styleState.style,
+                    notification: {
+                        show: true,
+                        text: 'Please login in order to play blackjack.',
+                        status: 'error',
+                    },
+                    displayLoadingScreen: false,
+                }))
+
+                router.push('/');
+            }
+        });
+    }, []);
+
+    return (
+        <header className="header">
+            <Link href="/" passHref>
+                <h2>
+                    <AiOutlineArrowLeft />
+                </h2>
+            </Link>
+            <nav>
+                <ul>
+                    <li>Hi{playerState?.player?.displayName ? `, ${playerState.player.displayName}` : ``}</li>
+                    <li>Balance: ${playerState?.player?.credits}</li>
+                </ul>
+            </nav>
+        </header>
+    )
+}
+
+export default InGameHeader
Index: components/Loading.jsx
===================================================================
--- components/Loading.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/Loading.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,17 @@
+import React from 'react'
+
+import { useSelector } from 'react-redux'
+
+const Loading = () => {
+    const styleState = useSelector(state => state.style);
+    
+    return (
+        <div className="fullscreen fs-centered loadingScreen" style={{display: styleState.style.displayLoadingScreen ? 'block' : 'none', zIndex: 10}}>
+            <div>
+                <h1>Loading...</h1>
+            </div>
+        </div>
+    )
+}
+
+export default Loading
Index: components/LoginScreen.jsx
===================================================================
--- components/LoginScreen.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/LoginScreen.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,134 @@
+import React from 'react'
+
+import { useSelector, useDispatch } from 'react-redux'
+
+import { setPlayer } from '../redux/reducers/playerSlice';
+import { setStyle } from '../redux/reducers/styleSlice';
+
+import axios from 'axios';
+
+const LoginScreen = () => {
+    const dispatch = useDispatch();
+
+    const playerState = useSelector(state => state.player);
+    const styleState = useSelector(state => state.style);
+
+    function onChangeUsername(e) {
+        dispatch(setStyle({
+            ...styleState.style,
+            loginScreenInfo: {
+                ...styleState.style.loginScreenInfo,
+                username: e.target.value,
+            }
+        }))
+    }
+
+    function onChangePassword(e) {
+        dispatch(setStyle({
+            ...styleState.style,
+            loginScreenInfo: {
+                ...styleState.style.loginScreenInfo,
+                password: e.target.value,
+            }
+        }))
+    }
+
+    function closeForm() {
+        dispatch(setStyle({
+            ...styleState.style,
+            displayLoginScreen: false,
+            loginScreenInfo: {
+                username: '',
+                password: '',
+            },
+            inlineAlertText: '',
+        }));
+    }
+
+    function login() {
+        dispatch(setStyle({
+            ...styleState.style,
+            displayLoadingScreen: true,
+        }))
+
+        axios.post(`/api/postgre`, {
+            action: 'login',
+            username: styleState.style.loginScreenInfo.username,
+            password: styleState.style.loginScreenInfo.password,
+        })
+            .then(res => {
+                if (res.data?.success) {
+                    localStorage.CAESSINO_SESSION_ID = res.data?.session?.id;
+                    dispatch(setStyle({
+                        ...styleState.style,
+                        displayLoginScreen: false,
+                    }));
+
+                    dispatch(setPlayer({
+                        ...playerState.player,
+                        username: res.data?.session?.username,
+                        displayName: res.data?.session?.displayName,
+                        credits: res.data?.session.credits,
+                        session_id: res.data?.session?.id,
+                    }));
+
+                    dispatch(setStyle({
+                        ...styleState.style,
+                        displayLoadingScreen: false,
+                        displayLoginScreen: false,
+                        loginScreenInfo: {
+                            username: '',
+                            password: '',
+                        },
+                        notification: {
+                            show: true,
+                            text: 'Successfully logged in.',
+                            status: 'success',
+                        },
+                    }));
+                }
+                else {
+                    dispatch(setStyle({
+                        ...styleState.style,
+                        displayLoginScreen: true,
+                        inlineAlertText: res.data?.message,
+                    }));
+                }
+            })
+    }
+
+    function checkForLink(e) {
+        if (e.target.innerHTML.includes('Register')) {
+            dispatch(setStyle({
+                ...styleState.style,
+                displayRegisterScreen: true,
+                displayLoginScreen: false,
+                loginScreenInfo: {
+                    username: '',
+                    password: '',
+                },
+                inlineAlertText: '',
+            }));
+        }
+    }
+
+    return (
+        <div className="fullscreen fs-centered loginScreen" style={{display: styleState.style.displayLoginScreen ? 'block' : 'none'}}>
+            <div className="fs-inputs-container">
+                {styleState.style.inlineAlertText.length > 0 && <span className="inlineAlert" onClick={(e) => checkForLink(e)}>{styleState.style.inlineAlertText}</span>}
+                <div>
+                    <span>Username:</span>
+                    <input type="text" onChange={(e) => {onChangeUsername(e)}} value={styleState.style.loginScreenInfo.username}/>
+                    <span>Password:</span>
+                    <input type="password" onChange={(e) => {onChangePassword(e)}} value={styleState.style.loginScreenInfo.password}/>
+                    <div style={{width: '100%', display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
+                        <button className="primaryButton" onClick={() => closeForm()}>Close Form</button>
+                        <button className="secondaryButton" onClick={() => login()}>Log In</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    )
+}
+
+export default LoginScreen
Index: components/ManageCredits.jsx
===================================================================
--- components/ManageCredits.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/ManageCredits.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,49 @@
+import React from 'react'
+
+import { useSelector, useDispatch } from 'react-redux'
+import { setStyle } from '../redux/reducers/styleSlice';
+
+import { AiOutlineClose } from 'react-icons/ai';
+import { setPlayer } from '../redux/reducers/playerSlice';
+
+import axios from 'axios';
+
+const ManageCredits = () => {
+    const playerState = useSelector(state => state.player);
+    const styleState = useSelector(state => state.style);
+
+    const dispatch = useDispatch();
+
+    function close() {
+        dispatch(setStyle({
+            ...styleState.style,
+            displayManageCreditsScreen: false,
+        }))
+    }
+
+    function buyCredits() {
+        axios.get(`/api/postgre/?action=add_credits&session_id=${localStorage.CAESSINO_SESSION_ID}&credits=${500}&dont_update_stats=true`).then(res => {
+            if (res.data?.success) {
+                dispatch(setPlayer({
+                    ...playerState.player,
+                    credits: res.data.credits,
+                }))
+            }
+        });
+    }
+
+    return (
+        <div className="fullscreen fs-centered manageCreditsScreen" style={{display: styleState.style.displayManageCreditsScreen ? 'block' : 'none'}}>
+            <AiOutlineClose onClick={() => close()} style={{position: 'absolute', top: '20px', right: '20px'}}/>
+            <div>
+                <h1>Manage Credits:</h1>
+                <p>You currently have: ${playerState.player.credits}</p>
+                <div>
+                    <button className="primaryButton" onClick={() => buyCredits()}>Buy Credits</button>
+                </div>
+            </div>
+        </div>
+    )
+}
+
+export default ManageCredits
Index: components/Notification.jsx
===================================================================
--- components/Notification.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/Notification.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,36 @@
+import React from 'react'
+
+import { AiOutlineClose } from 'react-icons/ai';
+
+import { useDispatch, useSelector } from 'react-redux';
+import { setStyle } from '../redux/reducers/styleSlice';
+
+const Notification = () => {
+    const styleState = useSelector(state => state.style);
+
+    const dispatch = useDispatch();
+
+    const display = styleState.style.notification.show === true ? 'flex' : 'none';
+    const bg = styleState.style.notification.status === 'success' ? 'rgba(0, 200, 255, 0.8)' : 'rgba(255, 0, 0, 0.8)';
+
+    function close() {
+        dispatch(setStyle({
+            ...styleState.style,
+            notification: {
+                ...styleState.style.notification,
+                show: false,
+            }
+        }))
+    }
+
+    return (
+        <div className="notification" style={{display: display, backgroundColor: bg}}>
+            <AiOutlineClose onClick={() => close()}/>
+            <div>
+                {styleState.style.notification.text}
+            </div>
+        </div>
+    )
+}
+
+export default Notification
Index: components/RegisterScreen.jsx
===================================================================
--- components/RegisterScreen.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/RegisterScreen.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,124 @@
+import React from 'react'
+
+import { useSelector, useDispatch } from 'react-redux'
+
+import { setStyle } from '../redux/reducers/styleSlice';
+
+import axios from 'axios';
+
+const RegisterScreen = () => {
+    const dispatch = useDispatch();
+
+    const styleState = useSelector(state => state.style);
+
+    function onChangeUsername(e) {
+        dispatch(setStyle({
+            ...styleState.style,
+            registerScreenInfo: {
+                ...styleState.style.registerScreenInfo,
+                username: e.target.value,
+            }
+        }))
+    }
+
+    function onChangeDisplayName(e) {
+        dispatch(setStyle({
+            ...styleState.style,
+            registerScreenInfo: {
+                ...styleState.style.registerScreenInfo,
+                displayName: e.target.value,
+            }
+        }))
+    }
+
+    function onChangePassword(e) {
+        dispatch(setStyle({
+            ...styleState.style,
+            registerScreenInfo: {
+                ...styleState.style.registerScreenInfo,
+                password: e.target.value,
+            }
+        }))
+    }
+
+    function closeForm() {
+        dispatch(setStyle({
+            ...styleState.style,
+            displayRegisterScreen: false,
+            registerScreenInfo: {
+                username: '',
+                displayName: '',
+                password: '',
+            },
+            inlineAlertText: '',
+        }));
+    }
+
+    function register() {
+        dispatch(setStyle({
+            ...styleState.style,
+            displayLoadingScreen: true,
+        }))
+
+        axios.post('/api/postgre', {
+            action: 'register',
+            username: styleState.style.registerScreenInfo.username,
+            displayName: styleState.style.registerScreenInfo.displayName,
+            password: styleState.style.registerScreenInfo.password,
+        })
+            .then(res => {
+                if (res.data?.success) {
+                    dispatch(setStyle({
+                        ...styleState.style,
+                        displayRegisterScreen: false,
+                    }));
+
+                    dispatch(setStyle({
+                        ...styleState.style,
+                        displayLoadingScreen: false,
+                        displayRegisterScreen: false,
+                        displayLoginScreen: true,
+                        registerScreenInfo: {
+                            username: '',
+                            displayName: '',
+                            password: '',
+                        },
+                        notification: {
+                            show: true,
+                            text: 'Successfully registered! Please Log In now.',
+                            status: 'success',
+                        },
+                    }));
+                }
+                else {
+                    dispatch(setStyle({
+                        ...styleState.style,
+                        displayRegisterScreen: true,
+                        inlineAlertText: res.data?.message,
+                    }));
+                }
+            })
+    }
+
+    return (
+        <div className="fullscreen fs-centered registerScreen" style={{display: styleState.style.displayRegisterScreen ? 'block' : 'none'}}>
+            <div className="fs-inputs-container">
+                {styleState.style.inlineAlertText.length > 0 && <span className="inlineAlert">{styleState.style.inlineAlertText}</span>}
+                <div>
+                    <span>Username:</span>
+                    <input type="text" onChange={(e) => {onChangeUsername(e)}} value={styleState.style.registerScreenInfo.username}/>
+                    <span>Display Name:</span>
+                    <input type="text" onChange={(e) => {onChangeDisplayName(e)}} value={styleState.style.registerScreenInfo.displayName}/>
+                    <span>Password:</span>
+                    <input type="password" onChange={(e) => {onChangePassword(e)}} value={styleState.style.registerScreenInfo.password}/>
+                    <div style={{width: '100%', display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
+                        <button className="primaryButton" onClick={() => closeForm()}>Close Form</button>
+                        <button className="secondaryButton" onClick={() => register()}>Register</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    )
+}
+
+export default RegisterScreen
Index: components/Stats.jsx
===================================================================
--- components/Stats.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/Stats.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,34 @@
+import React from 'react'
+
+import { useSelector, useDispatch } from 'react-redux'
+import { setStyle } from '../redux/reducers/styleSlice';
+
+import { AiOutlineClose } from 'react-icons/ai';
+
+const Stats = () => {
+    const styleState = useSelector(state => state.style);
+
+    const dispatch = useDispatch();
+
+    function close() {
+        dispatch(setStyle({
+            ...styleState.style,
+            displayStatsScreen: false,
+        }))
+    }
+
+    return (
+        <div className="fullscreen fs-centered statsScreen" style={{display: styleState.style.displayStatsScreen ? 'block' : 'none'}}>
+            <AiOutlineClose onClick={() => close()} style={{position: 'absolute', top: '20px', right: '20px'}}/>
+            <div>
+                <h1>Stats:</h1>
+                <p>Total money won: <span>${styleState.style.statsScreenInfo.money.earned}</span></p>
+                <p>Total blackjack games won: <span>{styleState.style.statsScreenInfo.blackjack.wins}</span></p>
+                <p>Total roulette games won: <span>{styleState.style.statsScreenInfo.roulette.wins}</span></p>
+                <p>Total poker games won: <span>{styleState.style.statsScreenInfo.poker.wins}</span></p>
+            </div>
+        </div>
+    )
+}
+
+export default Stats
Index: components/blackjack/Blackjack.jsx
===================================================================
--- components/blackjack/Blackjack.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/blackjack/Blackjack.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,37 @@
+import React from 'react'
+
+import InGameHeader from '../../components/InGameHeader'
+
+import Head from 'next/head'
+import PlayButtons from '../../components/blackjack/PlayButtons'
+import Cards from '../../components/blackjack/Cards'
+import DisplayBet from '../../components/blackjack/DisplayBet'
+import Loading from '../Loading'
+import Alert from '../Alert'
+import Notification from '../Notification'
+
+const Blackjack = () => {
+  return (
+    <div className="app" style={{backgroundImage: 'url("/images/blackjack-bg.png")', backgroundPosition: '0% 30%'}}>
+      <Head>
+        <title>Caessino - Blackjack</title>
+      </Head>
+  
+      <InGameHeader/>
+
+      <PlayButtons/>
+
+      <Cards/>
+
+      <DisplayBet/>
+
+      <Loading/>
+
+      <Alert/>
+
+      <Notification/>
+    </div>
+  )
+}
+
+export default Blackjack
Index: components/blackjack/Cards.jsx
===================================================================
--- components/blackjack/Cards.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/blackjack/Cards.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,41 @@
+import React from 'react'
+
+import { useSelector } from 'react-redux'
+
+import { useState } from 'react'
+
+import Card from '../Card'
+
+const Cards = () => {
+  const playerState = useSelector(state => state.player)
+
+  let initialPos = {
+    left: 70,
+    top: 24,
+  }
+
+  let playerPos = {
+    left: 50,
+    top: 75.5
+  }
+
+  let dealerPos = {
+    left: 50,
+    top: 32,
+  }
+
+  const splitCardsMultiplyByInt = 2;
+
+  return (
+    <div className="blackjackCards">
+      {playerState?.game?.playerCards?.map((card, i) => (
+        <Card key={card} card={card} rotateZ={i*splitCardsMultiplyByInt} pos={{left: playerPos.left+i*splitCardsMultiplyByInt, top: playerPos.top}}/>
+      ))}
+      {playerState?.game?.dealerCards?.map((card, i) => (
+        <Card key={card} card={card} rotateZ={i*splitCardsMultiplyByInt} pos={{left: dealerPos.left+i*splitCardsMultiplyByInt, top: dealerPos.top}}/>
+      ))}
+    </div>
+  )
+}
+
+export default Cards
Index: components/blackjack/DisplayBet.jsx
===================================================================
--- components/blackjack/DisplayBet.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/blackjack/DisplayBet.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,19 @@
+import React from 'react'
+
+import { useSelector } from 'react-redux';
+
+const DisplayBet = () => {
+  const playerState = useSelector(state => state.player);
+  const styleState = useSelector(state => state.style);
+
+  let display = parseInt(playerState.game.status.substr(1, 1)) >= 2 ? 'block' : 'none';
+  let displaySideBet = ( parseInt(playerState.game.status.substr(1, 1)) >= 3 && parseInt(styleState.blackjack.inputControls.sideBet.chosenCredits) > 0 ) ? 'block' : 'none';
+
+  return (
+    <div className="blackjackDisplayBet" style={{display: display}}>
+      <span>${styleState.blackjack.inputControls.initialBet.chosenCredits}{displaySideBet === 'block' ? ` + $${styleState.blackjack.inputControls.sideBet.chosenCredits}` : ''}</span>
+    </div>
+  )
+}
+
+export default DisplayBet
Index: components/blackjack/PlayButtons.jsx
===================================================================
--- components/blackjack/PlayButtons.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
+++ components/blackjack/PlayButtons.jsx	(revision 87614a539b5a6d95f9aee8012bfdef4edeeb2fb5)
@@ -0,0 +1,426 @@
+import React from 'react'
+
+import { GiTwoCoins, GiReturnArrow, GiCardDraw } from 'react-icons/gi'
+import { AiFillCheckCircle } from 'react-icons/ai'
+
+import { setGame, setPlayer } from '../../redux/reducers/playerSlice';
+import { setBlackjack, setStyle } from '../../redux/reducers/styleSlice';
+
+import { useSelector, useDispatch } from 'react-redux'
+import { useState, useEffect } from 'react'
+
+import axios from 'axios';
+
+const PlayButtons = () => {
+    const dispatch = useDispatch();
+
+    const playerState = useSelector(state => state.player);
+    const styleState = useSelector(state => state.style);
+
+    function chooseCoins(e) {
+        dispatch(setBlackjack({
+            ...styleState.blackjack,
+            inputControls: {
+                ...styleState.blackjack.inputControls,
+                initialBet: {
+                    ...styleState.blackjack.inputControls.initialBet,
+                    chosenCredits: parseInt(e.target.value),
+                }
+            }
+        }))
+    }
+
+    function chooseCoinsSideBet(e) {
+        dispatch(setBlackjack({
+            ...styleState.blackjack,
+            inputControls: {
+                ...styleState.blackjack.inputControls,
+                sideBet: {
+                    ...styleState.blackjack.inputControls.sideBet,
+                    chosenCredits: parseInt(e.target.value),
+                }
+            }
+        }));
+    }
+
+    function placeInitialBetClicked() {
+        axios.get(`/api/postgre?action=take_credits&session_id=${localStorage.CAESSINO_SESSION_ID}&credits=${styleState.blackjack.inputControls.initialBet.chosenCredits}`).then(postgreRes => {
+            if (postgreRes.data?.success) {
+                axios.get(`/api/blackjack?action=make_initial_bet&session_id=${localStorage.CAESSINO_SESSION_ID}&bet=${styleState.blackjack.inputControls.initialBet.chosenCredits}`).then(res => {
+                    if (res.data?.success) {
+                        dispatch(setGame({
+                            ...playerState.game,
+                            status: res.data?.status,
+                        }))
+
+                        dispatch(setPlayer({
+                            ...playerState.player,
+                            credits: postgreRes.data?.credits,
+                        }))
+
+                        dispatch(setBlackjack({
+                            ...styleState.blackjack,
+                            displays: {
+                                ...styleState.blackjack.displays,
+                                initialBet: false,
+                                sideBet: true,
+                            }
+                        }))
+                    }
+                });
+            }
+        });
+    }
+
+    function placeSideBetsClicked() {
+        dispatch(setBlackjack({
+            ...styleState.blackjack,
+            displays: {
+                ...styleState.blackjack.displays,
+                sideBetsModal: true,
+                sideBetsChooseCreditsModal: false,
+            },
+            inputControls: {
+                ...styleState.blackjack.inputControls,
+                sideBet: {
+                    ...styleState.blackjack.inputControls.sideBet,
+                    chosenCredits: parseInt(playerState.player.credits/2),
+                }
+            }
+        }))
+    }
+
+    function splitTexts(text) {
+        let chooseCreditsText = ''
+        let paysText = ''
+
+        let allowCopy = true;
+        let copyToPaysText = false;
+        for (let i = 0; i < text.length; i++) {
+            if (text[i] === '<') {
+                allowCopy = false;
+            }
+
+            if (allowCopy) {
+                if (text.length - 1 - i >= 4 && text.substring(i, i + 4) === 'Pays') {
+                    copyToPaysText = true;
+                }
+
+                if (!copyToPaysText) {
+                    chooseCreditsText += text[i];
+                }
+                else {
+                    paysText += text[i];
+                }
+            }
+            
+            if (text[i] === '>') {
+                allowCopy = true;
+            }
+        }
+
+        return {
+            chooseCreditsText,
+            paysText,
+        }
+    }
+
+    function selectedSideBet(e, sideBetName) {
+        const texts = splitTexts(e.target.innerHTML);
+
+        dispatch(setGame({
+            ...playerState.game,
+            sideBetName: sideBetName
+        }))
+
+        dispatch(setBlackjack({
+            ...styleState.blackjack,
+            displays: {
+                ...styleState.blackjack.displays,
+                sideBetsModal: false,
+                sideBetsChooseCreditsModal: true,
+            },
+            texts: {
+                ...styleState.blackjack.texts,
+                sideBetsChooseCreditsText: texts.chooseCreditsText,
+                sideBetsPaysText: texts.paysText,
+            }
+        }))
+    }
+
+    function placeSideBetClicked() {
+        axios.get(`/api/postgre?action=take_credits&session_id=${localStorage.CAESSINO_SESSION_ID}&credits=${styleState.blackjack.inputControls.sideBet.chosenCredits}`).then(postgreRes => {
+            if (postgreRes.data?.success) {
+                axios.get(`/api/blackjack?action=make_side_bet&session_id=${localStorage.CAESSINO_SESSION_ID}&bet=${styleState.blackjack.inputControls.sideBet.chosenCredits}&betName=${playerState.game.sideBetName}`).then(res => {
+                    if (res.data?.success) {
+                        dispatch(setGame({
+                            ...playerState.game,
+                            status: res.data?.status,
+                        }))
+
+                        dispatch(setPlayer({
+                            ...playerState.player,
+                            credits: postgreRes.data?.credits,
+                        }))
+
+                        dispatch(setBlackjack({
+                            ...styleState.blackjack,
+                            displays: {
+                                ...styleState.blackjack.displays,
+                                sideBetsChooseCreditsModal: false,
+                                sideBet: false,
+                                hitStand: true,
+                            }
+                        }))
+
+                        getCards();
+                    }
+                });
+            }
+        });
+    }
+
+    function skipSideBetsClicked() {
+        axios.get(`/api/blackjack?action=make_side_bet&session_id=${localStorage.CAESSINO_SESSION_ID}&bet=0&betName=none&skip=true`).then(res => {
+            if (res.data?.success) {
+                dispatch(setBlackjack({
+                    ...styleState.blackjack,
+                    displays: {
+                        ...styleState.blackjack.displays,
+                        sideBetsModal: false,
+                        sideBetsChooseCreditsModal: false,
+                        sideBet: false,
+                        hitStand: true,
+                    },
+                    inputControls: {
+                        ...styleState.blackjack.inputControls,
+                        sideBet: {
+                            ...styleState.blackjack.inputControls.sideBet,
+                            chosenCredits: 0,
+                        }
+                    },
+                }))
+
+                getCards();
+            }
+        });
+    }
+
+    function getCards() {
+        axios.get(`/api/blackjack?action=get_initial_cards&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+            if (res.data?.success) {
+                dispatch(setGame({
+                    ...playerState.game,
+                    status: res.data?.status,
+                    playerCards: res.data?.playerCards,
+                    dealerCards: res.data?.dealerCards,
+                }))
+
+                if (res.data?.sideBetOutcome !== '') {
+                    if (res.data.sideBetOutcome === 'side_bet_won') {
+                        dispatch(setGame({
+                            ...playerState.game,
+                            credits: res.data?.credits,
+                        }))
+                        
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            alert: {
+                                show: true,
+                                title: 'You won the side bet!',
+                                subtitle: `You won $${res.data?.sideBetEarnings}`,
+                                button: {
+                                    text: 'Continue',
+                                    action: 'continue_from_side_bet',
+                                }
+                            }
+                        }))
+                    }
+                    else if (res.data.sideBetOutcome === 'side_bet_lost') {
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            alert: {
+                                show: true,
+                                title: 'You lost the side bet!',
+                                subtitle: `You lost $${-1*res.data?.sideBetEarnings}`,
+                                button: {
+                                    text: 'Continue',
+                                    action: 'continue_from_side_bet',
+                                }
+                            }
+                        }))
+                    }
+                }
+            }
+        });
+    }
+
+    function hitClicked() {
+        axios.get(`/api/blackjack?action=hit_a_card&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+            if (res.data?.success) {
+                dispatch(setGame({
+                    ...playerState.game,
+                    status: res.data?.status,
+                    playerCards: res.data?.playerCards,
+                }))
+
+                if (res.data?.status === '_5_game_over') {
+                    if (res.data?.outcome === 'player_busted') {
+                        dispatch(setPlayer({
+                            ...playerState.player,
+                            credits: res.data?.credits,
+                        }))
+
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            alert: {
+                                show: true,
+                                title: 'You busted!',
+                                subtitle: `You lost $${-1*res.data?.earnings}`,
+                                button: {
+                                    text: 'Play again',
+                                    action: 'play_again',
+                                }
+                            }
+                        }))
+                    }
+                }
+            }
+        });
+    }
+
+    function standClicked() {
+        axios.get(`/api/blackjack?action=stand&session_id=${localStorage.CAESSINO_SESSION_ID}`).then(res => {
+            if (res.data?.success) {
+                dispatch(setGame({
+                    ...playerState.game,
+                    status: res.data?.status,
+                    playerCards: res.data?.playerCards,
+                    dealerCards: res.data?.dealerCards,
+                }))
+
+                if (res.data?.status.toString().substr(1, 1) === '5') { // game_over
+                    dispatch(setPlayer({
+                        ...playerState.player,
+                        credits: res.data?.credits,
+                    }))
+                    
+                    if (res.data?.outcome === 'dealer_busted') {
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            alert: {
+                                show: true,
+                                title: 'Dealer busted!',
+                                subtitle: `You won $${res.data?.earnings}`,
+                                button: {
+                                    text: 'Play again',
+                                    action: 'play_again',
+                                }
+                            }
+                        }))
+                    }
+                    else if (res.data?.outcome === 'player_won') {
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            alert: {
+                                show: true,
+                                title: 'You won!',
+                                subtitle: `You won $${res.data?.earnings}`,
+                                button: {
+                                    text: 'Play again',
+                                    action: 'play_again',
+                                }
+                            }
+                        }))
+                    }
+                    else if (res.data?.outcome === 'player_lost') {
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            alert: {
+                                show: true,
+                                title: 'You lost!',
+                                subtitle: `You lost $${-1*res.data?.earnings}`,
+                                button: {
+                                    text: 'Play again',
+                                    action: 'play_again',
+                                }
+                            }
+                        }))
+                    }
+                    else if (res.data?.outcome === 'draw') {
+                        dispatch(setStyle({
+                            ...styleState.style,
+                            alert: {
+                                show: true,
+                                title: 'Draw!',
+                                subtitle: `You got your $${res.data?.earnings} back`,
+                                button: {
+                                    text: 'Play again',
+                                    action: 'play_again',
+                                }
+                            }
+                        }))
+                    }
+                }
+            }
+        });
+    }
+
+    return (
+        <div className="blackjackButtons">
+            <div className="blackjackInitialBet" style={{display: styleState.blackjack.displays.initialBet ? 'flex' : 'none'}}>
+                <div>
+                    <input type="range" className="primarySlider" min={0} max={playerState.player.credits} step={1} value={styleState.blackjack.inputControls.initialBet.chosenCredits} onChange={(e) => chooseCoins(e)} />
+                    <div style={{marginTop: '15px', marginBottom: '-30px'}}>
+                        <span>${styleState.blackjack.inputControls.initialBet.chosenCredits}</span>
+                    </div>
+                </div>
+                <button className="primaryButton" onClick={() => placeInitialBetClicked()}>Place Initial Bet <GiTwoCoins style={{marginTop: '3px', marginBottom: '-3px'}} /></button>
+            </div>
+            <div className="blackjackSideBet" style={{display: styleState.blackjack.displays.sideBet ? 'flex' : 'none'}}>
+                <button className="primaryButton" onClick={() => placeSideBetsClicked()}>Place Side Bets <GiTwoCoins style={{marginTop: '3px', marginBottom: '-3px'}} /></button>
+                <button className="primaryButton" onClick={() => skipSideBetsClicked()}>Skip <GiReturnArrow style={{marginTop: '3px', marginBottom: '-3px', transform: 'rotateZ(-15deg)'}} /></button>
+            </div>
+            <div className="blackjackHitStand" style={{display: styleState.blackjack.displays.hitStand ? 'flex' : 'none'}}>
+                <button className="primaryButton" onClick={() => hitClicked()}>Hit <GiCardDraw style={{marginTop: '3px', marginBottom: '-3px'}} /></button>
+                <button className="primaryButton" onClick={() => standClicked()}>Stand <AiFillCheckCircle style={{marginTop: '3px', marginBottom: '-3px'}} /></button>
+            </div>
+
+            <div className="blackjackSideBetsModal" style={{display: styleState.blackjack.displays.sideBetsModal ? 'flex' : 'none'}}>
+                <div className="blackjackSideBetSelect">
+                    <h1>Perfect Pairs</h1>
+                    <div>
+                        <p onClick={(e) => selectedSideBet(e, 'mixed_pair')}>Mixed pair (two of the same value but different suit and colour)<br/><span>Pays 5:1</span></p>
+                        <p onClick={(e) => selectedSideBet(e, 'coloured_pair')}>Coloured pair (two of the same value and the same colour)<br/><span>Pays 12:1</span></p>
+                        <p onClick={(e) => selectedSideBet(e, 'perfect_pair')}>Perfect pair (two of the same card)<br/><span>Pays 25:1</span></p>
+                    </div>
+                </div>
+                <div className="blackjackSideBetSelect">
+                    <h1>21+3</h1>
+                    <div>
+                        <p onClick={(e) => selectedSideBet(e, 'flush')}>Flush (all cards are suited)<br/><span>Pays 5:1</span></p>
+                        <p onClick={(e) => selectedSideBet(e, 'straight')}>Straight (all cards consecutive)<br/><span>Pays 10:1</span></p>
+                        <p onClick={(e) => selectedSideBet(e, 'three_of_a_kind')}>Three of a kind (not the same suit)<br/><span>Pays 30:1</span></p>
+                        <p onClick={(e) => selectedSideBet(e, 'straight_flush')}>Straight flush (consecutive cards same suit)<br/><span>Pays 40:1</span></p>
+                        <p onClick={(e) => selectedSideBet(e, 'suited_triple')}>Suited triple (three of the same card)<br/><span>Pays 100:1</span></p>
+                    </div>
+                </div>
+            </div>
+
+            <div className="blackjackSideBetsChooseCreditsModal" style={{display: styleState.blackjack.displays.sideBetsChooseCreditsModal ? 'flex' : 'none'}}>
+                <p>{styleState.blackjack.texts.sideBetsChooseCreditsText}<br/><span>{styleState.blackjack.texts.sideBetsPaysText}</span></p>
+                <div>
+                    <div>
+                        <input type="range" className="primarySlider" min={0} max={playerState.player.credits} step={1} value={styleState.blackjack.inputControls.sideBet.chosenCredits} onChange={(e) => chooseCoinsSideBet(e)} />
+                        <div style={{marginTop: '15px', marginBottom: '-30px'}}>
+                            <span>${styleState.blackjack.inputControls.sideBet.chosenCredits}</span>
+                        </div>
+                    </div>
+                    <button style={{marginTop: '40px'}} className="primaryButton" onClick={() => placeSideBetClicked()}>Place Side Bet <GiTwoCoins style={{marginTop: '3px', marginBottom: '-3px'}} /></button>
+                </div>
+            </div>
+        </div>
+    )
+}
+
+export default PlayButtons
