JSFiddle - React, Tailwind, and code Playground

HTML

<div id="messenger" class="bordered float">
    <div id="messages-container">
        <div id="messages" class="shadowed">
            <div class="message from bordered">Hey</div>
            <div class="message to bordered">Sup</div>
            <div class="message from bordered">How are ya?</div>
        </div>
    </div>
    <div class="divider bordered"></div>
    <input type="text" id="input" class="float bordered" placeholder="Message"></input>
    <div id="send" class="bordered float">Send</div>
    <div id="guesses">
        <div class="guess bordered float" id="guess-1"></div>
        <div class="guess bordered float" id="guess-2"></div>
        <div class="guess bordered float" id="guess-3"></div>
    </div>
</div>
<div id="info" class="float">Info...</div>

CSS

div, input, pre {
    box-sizing:border-box !important;
    padding:0;
    margin:0;
}
:focus {
    outline-color:transparent;
    outline-style:none
}
::selection {
    background:#00a9ff
}
body {
    padding:0;
    margin:0;
    background-color:#0090d8;
}
.float {
    float:left
}
.bordered {
    border-style:solid;
    border-width:1px
}
.shadowed {
    box-shadow:rgba(0, 0, 0, .1) 0 0 30px -10px inset, rgba(0, 0, 0, .5) 0 0 8px -5px inset
}
#info {
    width:40vw;
    height:100vh;
    overflow:scroll;
    font-family:"Courier New", Courier, monospace;
    padding:30px;
    color:white;
}
#messenger {
    width:50vw;
    height:100vh;
    background-color:#dbdbdb;
    font-family:Arial;
    border-width:0 10px;
    border-color:#26c8ff;
    margin-left:5vw;
    box-shadow:rgba(38, 200, 255, 0.8) 0 0 300px -50px, rgba(38, 200, 255, 0.8) 0 0 10px -2px
}
#messages-container {
    display:table;
    width:100%;
}
#messages {
    color:#dbdbdb;
    width:100%;
    height:70vh;
    background-color:#fff;
    padding:10px;
    display: table-cell;
    vertical-align: bottom;
    box-shadow:rgba(0, 0, 0, 0.2) 0px 0px 15px -3px inset, rgba(0, 0, 0, 0.3) 0px 0px 3px 0px inset;
}
.divider {
    width:100%;
    height:10px;
    color:#efefef;
}
#guesses {
    width:100%;
    float:left;
    height:40px;
    box-shadow:rgba(0, 0, 0, 0.2) 0px 5px 30px -5px, rgba(0, 0, 0, 0.2) 0px 0px 2px 0px;
}
.guess {
    color:#efefef;
    font-size:24px;
    width:33.3333333%;
    height:40px;
    box-shadow:rgba(255, 255, 255, .2) 0 0 50px 10px inset;
    text-align:center;
    padding-top:5px;
    transition:box-shadow .3s, color .2s
}
.guess:hover {
    box-shadow:rgba(255, 255, 255, 1) 0 0 120px -20px inset;
    color:#fff;
    cursor:pointer
}
#input {
    width:80%;
    height:30px;
    text-align:center;
    cursor:pointer;
    font-size:17px;
    border-color:#000;
    transition: border-color 1s;
}
#input:focus, #input:hover {
    border-color:#0090d8;
}
#send {
   ...

JavaScript

var app = {
    /* So far, these words have been entered:
    hi
    hi
    hi
    hi
    hi
    hey
    hello
    hella
    */
    history: [{
        letter: "h",
        count: 8,
        followables: [{
            letter: "e",
            count: 3,
            followables: [{
                letter: "y",
                count: 1,
                followables: []
            }, {
                letter: "l",
                count: 2,
                followables: [{
                    letter: "l",
                    count: 2,
                    followables: [{
                        letter: "o",
                        count: 1,
                        followables: []
                    }, {
                        letter: "a",
                        count: 1,
                        followables: []
                    }]
                }]
            }]
        }, {
            letter: "i",
            count: 5,
            followables: []
        }]
    }],
    init: function () {
        $('#input').on('keyup', app.guess);
    },
    findChildren: function (node, depth) {
        /* Traverse history for current word, there is only one path */
        for (k in node) {
            if (node[k].letter == app.progress[depth]) {
                if (depth + 1 == app.progress.length) {
                    /* Found it, hope it has followables */
                    return node[k].followables;
                } else {
                    /* Must go deeper... */
                    return app.findChildren(node[k].followables, depth + 1);
                };
            };
        };
        /* No results */
        return false;
    },
    guesses: [{
        element: $('#guess-1'),
        word: ''
    }, {
        element: $('#guess-2'),
        word: ''
    }, {
        element: $('#guess-3'),
        word: ''
    }],
    totalInNode: 0,
    countWordsFromNode: function (node) {
        for (i in node) {
            if (node[i].followables.length) {
         ...