Vanilla Javascript Trivia Game

Help, Tutorials and Script related to Vanilla Javascript (NO jQuery!)
User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Next the answer user selects is handled by the following handler.

Code: Select all

/* User has made selection */
const clickHandler = (e) => {
    const userAnswer = parseInt(e.target.getAttribute('data-correct'));
    responseAns.id = parseInt(gameData[gameIndex].id); // { id: integer } 
    const checkUrl = "check.php";
    stopTimer();
    checkRequest(checkUrl, checkUISuccess, checkUIError);
    d.querySelector('#headerStyle').setAttribute('data-user', userAnswer);
};
The clickHandler = (e) => function sets the userAnswer and the corresponding id (responseAns.id ) constants, stops the timer and the calls the checkRequest(checkUrl, checkUISuccess, checkUIError) fetch functions in order to retrieve the correct answer from the database table.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Code: Select all

/* Success function utilizing FETCH */
const checkUISuccess = function (parsedData) {
    var correct = parseInt(parsedData.correct);
    var userAnswer = parseInt(d.querySelector('#headerStyle').getAttribute('data-user'));
    scoringFcn(userAnswer, correct);
    calcPercent(answeredRight, total);
    highlightFCN(userAnswer, correct);

    disableListeners();
    next.addEventListener('click', removeQuiz, false);
};
The above function fetches the correct answer from the database base table (var correct = parseInt(parsedData.correct);) along with the userAnswer sends it to the scoringFcn(userAnswer, correct) function and the highlightFCN(userAnswer, correct); function. The answered right and total questions answered so far are sent to the calcPercent(answeredRight, total) function. The disableListeners() listeners are disable, so that the user can't keep click on the answer buttons. The next button is assigned an add event listener (next.addEventListener('click', removeQuiz, false) so the user can go to the next question and answers.

Code: Select all

/* If Database Table fails to load then hard code the correct answers */
const checkUIError = function (error) {

    switch (gameData[gameIndex].id) {
        case 1:
            var correct = gameData[gameIndex].correct;
            break;
        case 55:
            var correct = gameData[gameIndex].correct;
            break;
        case 9:
            var correct = gameData[gameIndex].correct;
    }
    var userAnswer = parseInt(d.querySelector('#headerStyle').getAttribute('data-user'));
    scoringFcn(userAnswer, correct);
    calcPercent(answeredRight, total);
    highlightFCN(userAnswer, correct);

    disableListeners();
    next.addEventListener('click', removeQuiz, false);

};
-----------------------------------------------------------------

Code: Select all

/*
 * Throw error response if something is wrong: 
 */
const handleErrors = (response) => {
    if (!response.ok) {
        throw (response.status + ' : ' + response.statusText);
    }
    return response.json();
};

Code: Select all

/* create FETCH request */
const checkRequest = function (url, succeed, fail) {
        fetch(url, {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(responseAns)

        })
                .then((response) => handleErrors(response))
                .then((data) => succeed(data))
                .catch((error) => fail(error));
};
The const checkRequest = function (url, succeed, fail) uses the POST method instead of the GET method in order to prevent cheating though nothing is 100 percent full proof. The FETCH statement has to setup the POST method and put the data (the question id) in proper JSON format. Other than that it is basically the same as the first FETCH call.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Code: Select all

<?php

require_once '../private/initialize.php';

/* Makes it so we don't have to decode the json coming from JQuery */
header('Content-type: application/json');

/*
 * The below must be used in order for the json to be decoded properly.
 */
$data = json_decode(file_get_contents('php://input'), true);
I just want to ad that the last line of code has to be that way as this is the only way I could get the code to function properly using Fetch. One would think that you would be able to use the normal $_POST statement, but you Can Not.

Code: Select all

/*
 * Database Connection 
 */
$db_options = array(
    /* important! use actual prepared statements (default: emulate prepared statements) */
    PDO::ATTR_EMULATE_PREPARES => false
    /* throw exceptions on errors (default: stay silent) */
    , PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    /* fetch associative arrays (default: mixed arrays)    */
    , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$pdo = new PDO('mysql:host=' . DATABASE_HOST . ';dbname=' . DATABASE_NAME . ';charset=utf8', DATABASE_USERNAME, DATABASE_PASSWORD, $db_options);
This above code is the PDO connect string in order to properly connect to the database.

Code: Select all

function check($id, $pdo) {
    $query = "SELECT id, correct FROM trivia_questions WHERE id=:id";
    $stmt = $pdo->prepare($query);
    $stmt->execute([':id' => $id]);
    $data = $stmt->fetch(PDO::FETCH_ASSOC);
    return $data;
}
$result = check($data['id'], $pdo);
output($result);
The check function is called using the id that we fetched from the javascript code and the PDO connection string in order to connect to the database. the we retrieve the correct answer and the id once again. The we send it back to the javascript code using the output function.

Code: Select all

function errorOutput($output, $code = 500) {
    http_response_code($code);
    echo json_encode($output);
}
/*
 * After converting data array to JSON send back to javascript using
 * this function.
 */
function output($output) {
    http_response_code(200);
    echo json_encode($output);
}
The errorOutput aabd output functions in order to echo the json encoded data back to the javascript code.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Code: Select all

/* Highlight correct or wrong answers */
const highlightFCN = (userAnswer, correct) => {
    const highlights = d.querySelectorAll('.answerButton');
    highlights.forEach(answer => {
        /*
         * Highlight the Answers Function
         * User answered correctly
         */
        if (userAnswer === correct && userAnswer === parseInt(answer.getAttribute('data-correct'))) {
            answer.style["background-color"] = myGreen;
        }
        /*
         * User answered incorrectly
         */
        if (userAnswer !== correct && userAnswer === parseInt(answer.getAttribute('data-correct'))) {
            answer.style['background-color'] = myRed;
        }
        if (userAnswer !== correct && correct === parseInt(answer.getAttribute('data-correct'))) {
            answer.style['background-color'] = myGreen;
        }
        /*
         * User let timer run out
         */
        if (userAnswer === 5) {
            answer.style['background-color'] = myRed;
        }
    });
};
The highlightFCN function highlights the appropriate answer green and/or red to indicate right and/or wrong answer(s).

Code: Select all

/* Disable Listeners, so users can't click on answer buttons */
const disableListeners = () => {
    const myButtons = d.querySelectorAll('.answerButton');
    myButtons.forEach(answer => {
        answer.removeEventListener('click', clickHandler, false);
    });
};
The disableListeners function disables the answer buttons so the user can not click on them in order to cheat. :D

Code: Select all

/* Calculate Percent */
const calcPercent = (correct, total) => {
    var average = (correct / total) * 100;
    percent.textContent = average.toFixed(0) + "%";
};
The calcPercent function figures out the current percent of right answers.

Code: Select all

/* Figure out Score */
const scoringFcn = (userAnswer, correct) => {
    if (userAnswer === correct) {
        score += points;
        answeredRight++;
        scoreText.textContent = `Score ${score} Points`;
    } else {
        score = score - (points / 2);
        answeredWrong++;
        scoreText.textContent = `Score ${score} Points`;
    }
    total++;
};
The scoringFcn function figures out the current score.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Code: Select all

/*
 * Start and Stop Functions for Countdown Timer For Trivia Game
 */
const startTimer = (dSec) => {
    var seconds = dSec;
    const userAnswer = 5, correct = 1;
    const newClock = d.querySelector('#clock');
    newClock.style['color'] = 'white';
    newClock.textContent = ((seconds < 10) ? `0${seconds}` : seconds);
    const countdown = () => {
        if (seconds === 0) {
            clearTimeout(timer);
            newClock.style['color'] = myRed;
            newClock.textContent = "00";
            scoringFcn(userAnswer, correct);
            highlightFCN(userAnswer, correct);
            calcPercent(answeredRight, total);
            disableListeners();
            next.addEventListener('click', removeQuiz, false);
        } else {
            newClock.textContent = ((seconds < 10) ? `0${seconds}` : seconds);
            seconds--;
        }
    };
    timer = setInterval(countdown, 1000);
};
const stopTimer = () => {
    clearInterval(timer);
};
Timers are really not my speciality, but over the years I have fined tune this timer as best as I can. The player has 20 seconds to answer the question (this can be change to any time limit in the variable initialize section), if the player doesn't answer the question in the allotted time then he/his is charge with an incorrect answer, answer buttons locked and every answer button is highlighted red. The startTimer and stopTimer functions are named what they respectively do.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Code: Select all

/* Remove answers from Screen */
const removeAnswers = () => {
    let element = d.querySelector('#buttonContainer');
    while (element.firstChild) {
        element.removeChild(element.firstChild);
    }
};

Code: Select all

/* Reset the Game */
const resetGame = () => {
    removeAnswers();
    stopTimer();
    score = 0;
    total = 0;
    answeredRight = 0;
    answeredWrong = 0;
    gameIndex = 0;
    gameData = null;
    scoreText.textContent = 'Score 0 Points';
    percent.textContent = '100';
};

Code: Select all

/* Remove Question & Answers */
const removeQuiz = () => {
    removeAnswers(); // Call removeAnswers FCN:
    next.removeEventListener('click', removeQuiz, false);
    gameIndex++;

    if (gameIndex < parseInt(gameData.length)) {
        createQuiz(gameData[gameIndex]); // Recreate the Quiz Display:
    } else {
        question.textContent = 'Game Over';
    }
};
The removeAnswers and removeQuiz functions reinitializes the question and answers display and sets the functionality back properly for the next question. The resetGame function is called when a user selects a different game category.

User avatar
Strider64
Site Admin
Posts: 19
Joined: Thu Apr 02, 2020 9:04 pm

Re: Vanilla Javascript Trivia Game

Post by Strider64 »

Here's the CSS files for the HTML:

reset.css

Code: Select all

/* CSS Document for Screen */
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,300i,700,700i&display=swap');

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, textarea, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

* { box-sizing: border-box; }
game.css

Code: Select all

body {font-family: 'Open Sans', sans-serif; font-size: 16px; font-weight: 300; color: #555;     background: url(../images/img-naturalwhite-01.png) repeat;  padding: 0; margin: 0;}

#page { display: block; max-width: 75em; margin: 0 auto; position: relative; }

/* Text */
h1 { margin: 0 0 1em 0; font-size: 2.0em; font-weight: 700; }
h2 { margin: 0 0 .5em 0; font-size: 1.6em; font-weight: 700; line-height: 1.1em; }
h3 { margin: 0 0 .5em 0; font-size: 1.3em; font-weight: 700; }
h4 { margin: 0 0 1.5em 0; font-size: 1em; font-weight: 700; }

p { margin: 0 0 1em 0 }

a { color: #007eff; }
a:visited { color: #65b1ff; }

a.btn { cursor: pointer; font-size: 1.2em; text-decoration: none; color: #fff; border: 1px solid #fff; padding: 4px 15px; transition: background-color .5s; }
a.btn:hover { background-color: rgba(0, 0, 0, 0.3); }

a.btn3 { clear: both; font-size: 1.2em; text-decoration: none; color: #555; border: 1px solid #555; padding: 4px 15px; transition: background-color .5s; }
a.btn3:hover { background-color: rgba(0, 0, 0, 0.3); }

/* Header */

header {height: 430px; background: #cf0004 url(../images/banner_1200_2.jpg) no-repeat center bottom; position: relative; }

header a.logo {
    z-index: 1;
    position: absolute;
    display: block; width: 160px; height: 160px;
    background: url(../images/logo.svg) no-repeat 0 0; background-size: contain;
    top: 15px; left: 20px;
}

header a.logo span { display: none }

header div.intro { position: absolute; width: 42%; bottom: 50px; left: 5%; z-index: 1; }
header div.intro h1 { line-height: 1em; margin: 0 0 20px 0; color: #fff;  }

/* Section - All */

section { padding: 0 30px; }
section::after { content: ' '; display: block; clear: both; }
/* Section - Main */

section.main { background-color: #fff; margin-top: 20px; margin-bottom: 30px; padding: 20px 0; }
#gameTitle {
    display: block;
    width: 100%;
    max-width: 800px;
    height: auto;
    margin: 0px auto;
}

#gameTitle::after { content: ''; display: block; clear: both; }

h2.gameTitle {
    font-size: 1.8em;
    line-height: 1.5;
}

/* Trivia Game CSS */
#movie, #space { display: none; }

form#gameCat {
    display: block;
    width: 100%;
    max-width: 800px;
    height: auto;
    padding: 20px 0px;
    margin: 5px auto;
}

form#gameCat .select-css  {
    display: block;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 1.0em;
    font-weight: 700;
    text-transform: capitalize;
    color: #4C8FEC;
    line-height: 1.3;
    padding: .6em 1.4em .5em .8em;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    margin: 0.625em 0;
    border: 1px solid #aaa;
    box-shadow: 0 1px 0 1px rgba(0, 0, 0, 0.04);
    border-radius: .5em;
    -moz-appearance: none;
    -webkit-appearance: none;
    appearance: none;
    background-color: #fff;
    background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"), linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
    background-repeat: no-repeat, repeat;
    background-position: right .7em top 50%, 0 0;
    background-size: .65em auto, 100%; 
}

form#gameCat .select-css .select-css::-ms-expand { display: none; }

form#gameCat .select-css .select-css:hover { border-color: #888; }

form#gameCat .select-css .select-css:focus {
    border-color: #aaa;
    box-shadow: 0 0 1px 3px rgba(59, 153, 252, 0.7);
    box-shadow: 0 0 0 3px -moz-mac-focusring;
    color: #222;
    outline: none; 
}

form#gameCat .select-css .select-css option { font-weight: normal; }

.triviaContainer {
    display: block;
    background-color: rgba(0,0,0, 0.5);
    width: 100%;
    max-width: 800px;
    height: 725px;
    min-height: 800px;
    padding: 20px;
    margin: 5px auto;
}

.triviaContainer #categories-form {
    background-color: #f5f2d0;
    padding: 20px;
}

.triviaContainer #categories-form label {
    height: 20px;
    font-family: 'Teko', sans-serif;
    font-size: 1.8em;
    color: rgba(85,85,85,0.6);

}

.triviaContainer #categories-form select {
    clear: both;
    display: block;
    height: 20px;
    border: none;
    outline: none;
    background-color: #4484CE;
    font-family: 'Teko', sans-serif;
    font-size: 1.0em;
    color: #f5f2d0;
    text-transform: uppercase;
    margin-top: 5px;
}

#mainGame::after { content: ' '; display: block; clear: both; }

#mainGame #headerStyle {   
    padding: 10px 20px;
    margin: 0px;
}

#mainGame #headerStyle h2 {
    font-family: 'Teko', sans-serif;
    font-size: 1.2rem;
    line-height: 1.5;
    color: #f5f2d0;
}

#mainGame #triviaSection {
    margin: 0px;
}

#mainGame #triviaSection #questionBox {
    display: block;
    width: 100%;
    height: 400px;
    padding: 10px;
    background-color: #f5f2d0;
}

#mainGame #triviaSection #questionBox h2 {
    font-family: 'Teko', sans-serif;
    font-size: 1.6em;
    line-height: 1.5;
    color: rgba(85,85,85,0.8);
    vertical-align: middle;
}

#mainGame #triviaSection #buttonContainer .answerButton {
    display: block;
    width: 100%;
    height: 50px;
    outline: none;
    border: none;
    cursor: pointer;
    border-top: 2px solid #7f7f7f;
    background-color: rgba(85,85,85, 0.9);
    font-family: 'Teko', sans-serif;
    font-size: 1.4em;
    color: #f5f2d0;;
    text-align: left;
    padding-left: 10px;
    margin: 0;
}

#mainGame #playerStats {
    position: relative;
    display: block;
    width: 100%;
    height: 40px;
    border-top: 2px solid #7f7f7f;
}

#mainGame #playerStats #score {
    position: absolute;
    top: 10px;
    left: 10px;
    font-family: 'Teko', sans-serif;
    font-size: 1.2em;
    color: #f5f2d0;
    line-height: 15px;
}

#mainGame #playerStats #percent {
    position: absolute;
    top: 10px;
    right: 10px;
    font-family: 'Teko', sans-serif;
    font-size: 1.2em;
    color: #f5f2d0;
    line-height: 15px;
}

#mainGame #nextStyle {
    position: relative;
    display: block;
    width: 100%;
    height: 50px;
}

#mainGame #nextStyle #next {
    position: absolute;
    top: 3px;
    right: 10px;
    border: none;
    outline: none;
    display: block;
    width: 100%;
    max-width: 150px;
    height: 40px;
    cursor: pointer;
    background-color: #555;
    font-family: 'Teko', sans-serif;
    font-size: 1.4em;
    color: #fff;
    text-transform: capitalize;
}

#mainGame #nextStyle #next:hover {
    background-color: rgba(85,85,85, 0.7);
    color: #fff;
}

/* Navigation */
nav {
    background-color: rgba(0,0,0,0.65);
    position: absolute;
    top: 0px; left: 0px;
    padding: 15px 0 0 0; 
    width: 100%;
}

nav::after { content: ''; display: block; clear: both; }

nav ul { list-style: none; margin: 0; padding: 0px; }

nav ul li:hover { background-color: #2b0306; }

nav ul li:hover > ul { display: block; }

nav ul li a { 
    display: inline-block;
    color: #fff;
    padding: 10px 20px;
    text-decoration: none;
    width: 125px;
    position: relative;
}

nav ul li a:visited { color: #fff; }

nav ul li a:hover { background-color: #6d0911; }

nav ul ul { position: absolute; top: 100%; background-color: #2b0306; display: none; }

nav ul ul li { position: relative; }

nav ul ul ul { left: 100%; top: 0px; }

/* Top Level */
nav > ul { padding-left: 200px; }
nav > ul > li { float: left; }
nav > ul > li > a { width: auto; padding: 10px 20px 15px 20px;  }


nav a[aria-haspopup='true']::after {
    content: '';
    display: block; width: 0px; height: 0px;
    position: absolute;
    top: 10px; right: 15px;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 4px solid #fff;
}

nav > ul > li > a[aria-haspopup='true']::after {
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 4px solid #fff;
    left: 20px; right: auto;
    bottom: 6px; top: auto;
} 

/* Footer */
footer { font-size: .8em; margin: 40px; color: #999;}
footer .content { display: inline; }
footer a { margin-left: 30px; color: #777; }
footer a:visited { color: #777; }
footer a:hover { color: #000; }

/* Media Queries */
@media screen and (max-width: 1000px) {

    h1 { font-size: 1.6em; }

    /* Header */
    header div.intro { left: 65%; }
    header div.intro h1 { margin-bottom: 12px; }

}


@media screen and (max-width: 825px) {

    .shade {
        display: none;
    }
    h1 { font-size: 1.2em; }

    header { height: 300px; background-image: url(../images/banner_825.jpg)}
    header div.intro { top: 120px; left: 48%; }

    section.main {  display: block; width: 90%; height: auto; margin: 0 auto; padding: 0; }
    section.main aside { width: 100%; float: left; }


    .triviaContainer {

        background-color: rgba(0,0,0, 0.5);
        height: 850px;
        min-height: 700px;
        padding: 5px;
        margin: 0;
    }

    .triviaContainer #categories-form {

        background-color: #555;
        padding: 20px;
    }

    .triviaContainer #categories-form label {


        height: 20px;
        font-family: 'Teko', sans-serif;
        font-size: 1.4em;
        color: #fff;

    }

    .triviaContainer #categories-form select {
        clear: both;
        display: block;
        height: 20px;
        border: none;
        outline: none;
        background-color: #4b0a0c;
        font-family: 'Teko', sans-serif;
        font-size: 1.0em;
        color: #fff;
        text-transform: uppercase;
        margin-top: 5px;
    }

    #gameTitle {
        display: block;
        width: 100%;
        max-width: 800px;
        height: auto;
        text-align: center;
        margin: 0px auto;
    }

    #gameTitle::after { content: ''; display: block; clear: both; }

    h2.gameTitle {
        color: rgba(0,0,0, 0.5);
        font-size: 1.8em;
        line-height: 1.5;
    }


    #mainGame {
        display: none;
        width: 100%;
        height: 700px;
        margin: 0px auto;
    }

    #mainGame #headerStyle {
        font-size: 0.8em;
        padding: 2px 5px;
        margin: 0px 10px;
    }

    #mainGame #triviaSection #questionBox {
        display: block;
        width: 100%;
        height: 400px; 
        padding: 10px;
        background-color: #f5f2d0;
    }

    #mainGame #triviaSection #questionBox h2 {
        font-size: 1.2em;
    }

    #mainGame #triviaSection #buttonContainer .answerButton {
        display: block;
        width: 100%;
        height: 40px;
        outline: none;
        border: none;
        cursor: pointer;
        border-top: 2px solid #7f7f7f;
        background-color: rgba(85,85,85, 0.9);
        font-family: 'Teko', sans-serif;
        font-size: 1.0em;
        color: #f5f2d0;;
        text-align: left;
        padding-left: 10px;
        margin: 0;
    }

    #mainGame #nextStyle #next {
        position: absolute;
        top: 3px;
        right: 10px;
        border: none;
        outline: none;
        display: block;
        width: 100%;
        max-width: 150px;
        height: 40px;
        cursor: pointer;
        background-color: #555;
        font-family: 'Teko', sans-serif;
        font-size: 1.4em;
        color: #fff;
        text-transform: capitalize;
    }

}

@media screen and (max-width: 760px) {

    h1 { font-size: 1.5em; }
    h2 { font-size: 1.2em; }
    h3 { font-size: 1.0em; }

    a.btn { font-size: 1em; }

    /* Header */

    header a.logo { width: 60px; height: 60px; }
    header div.intro { top: 180px; left: 60%; }

    section.main { margin-top: 10px; margin-bottom: 10px; }
    /* Navigation */
    nav { padding-top: 80px; }
    nav > ul { padding-left: 10px; }

}

@media screen and (max-width: 625px) {
    h1 { font-size: 1em; }
    h3 { margin-bottom: 0px; }
    a.btn { font-size: .9em; }

    header { height: 160px; background-image: url(../images/banner_625.jpg); background-position: left top; }
    header a.logo {
        width: 100%; height: 60px;
        left: 0px; top: 0px;
        background-color: rgba(0,0,0,.65);
        background-size: 46px 46px;
        background-position: 20px center;
    }

    header div.intro { width: 300px; top: 85px; left: 40px; }
    header div.intro h1 { margin-bottom: 10px; } 

    /* Navigation */
    nav { position: static; width: auto; padding: 20px 15px; background-color: #4b0a0c;  }
    nav ul, 
    nav ul ul,
    nav ul ul ul { display: block; position: static; }

    nav > ul { padding: 0; }
    nav > ul > li { float: none; margin-top: 25px; }

    nav ul li:hover { background: none; }

    nav ul li a {
        width: auto;
        display: block;
        margin: 8px 10px;
        padding: 8px 15px;
        border: 1px solid rgba(255, 255, 255, .25);
    }

    nav ul li a:hover { background-color: rgba(255,255,255,.24); }

    nav ul ul { background: none;}

    nav ul ul li a { margin-left: 30px; }
    nav ul ul ul li a { margin-left: 60px; }

    nav a[aria-haspopup="true"]::after { display: none; }

    /* footer */

    footer div.content { display: block; margin-top: 15px; }

    footer div.content a { margin: 0 20px 0 0; }

}

Locked