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">A</div>
        <div class="guess bordered float" id="guess-2">No</div>
        <div class="guess bordered float" id="guess-3">Bet</div>
    </div>
</div>
<pre id="info" class="float">Info...</pre>

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 speakStructure = {};

function renderData() {
    console.log(speakStructure);
    var speakStructureStr = JSON.stringify(speakStructure, null, 4);
    $('#info').html('Speak Structure: ' + speakStructureStr);
}

function learn(message, brain) {
    if (message.length == 0) return {}; // or do something else
    var ch = message[0]; // get the first character
    if (!brain[ch]) { // create new node when not exists
        brain[ch] = {
            value: ch,
            count: 1,
            followables: {}
        };
    } else { // increment count when exist
        brain[ch].count += 1;
    }
    var substr = message.substring(1); // remove first character
    if (substr) { // do it for the remaining substring
        brain[ch].followables = learn(substr, brain[ch].followables);
    } else {
        renderData();
    }
    return brain;
}

function guess(progress, brain) {
    console.log("Guessing based on: " + progress);
    var guesses = {
        0: "",
        1: "",
        2: ""
    }
    var firstChar = progress[0]; 
    if (brain[firstChar]) {
        var step = brain[firstChar];
        for (var i = 0; i < progress.length; i++) {
            var char = progress[i];
            if (step.followables[char]) {
                step = step.followables[char];
                if (i == progress.length) {
                    var guesses = nextStrings(step.followables);
                    renderGuesses(guesses);
                }
            } else {
                renderGuesses(guesses);
            }
        }
    } else {
        renderGuesses(guesses);
    }
}

function renderGuesses(guesses) {
    console.log(guesses);
    $('#guess-1').text(guesses[0]);
    $('#guess-2').text(guesses[1]);
    $('#guess-3').text(guesses[2]);
}

function nextStrings(followables) {
    console.log('Searching for next string...');
    var results;
    if (followables.length > 0) {
        results = chooseRoutes(followables);
    } else {
        results = {
           ...