JSFiddle - React, Tailwind, and code Playground

HTML

<script type="text/javascript" src="http://cdn.icecomm.io/icecomm.js"></script>
<body>
  <div class="colorful box">
    <div class="panel">
    <div class="header">TIC TAC TOE ULTIMATE</div>
    <div class="board">
      <div class="row1">
        <button data-value="0"></button>
        <button data-value="1"></button>
        <button data-value="2"></button>
      </div>
      <div class="row2">
        <button data-value="3"></button>
        <button data-value="4"></button>
        <button data-value="5"></button>
      </div>
      <div class="row3">
        <button data-value="6"></button>
        <button data-value="7"></button>
        <button data-value="8"></button>
      </div>
    </div>
    <div class="status"></div>
    </div>
  </div>
</body>

CSS

@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,700,800);
@font-face {
  font-family: 'BrandonGrotesque';
  src: url("./Brandon_bld.otf");
  font-weight: regular;
  font-style: normal; }

body {
  width: 100%;
  height: auto;
  bottom: 0px;
  top: 0px;
  left: 0;
  position: absolute;
  margin: 0px;
}

.board {
  position: relative;
  width: 330px;
  height: 330px;
}

.header {
  width: 300px;
  padding: 20px 10px;
  font-family: 'Open Sans', sans-serif;
  font-size: 40px;
  color: #333;
  text-align: center;
  color: #776E65;
  font-weight: 800;
  font-family: BrandonGrotesque-Bold;
  color: #EECAFC;
  /*line-height: 101px;*/
}

button {
  height: 90px;
  width: 90px;
  font-size: 48px;
  display: block;
  float: left;
  border: none;
  border-radius: 4px;
  margin: 8px;
  font-family: 'Open Sans', sans-serif;
  background: #50E3C2;
  color: #FFF;
}

button:focus {outline:0;}

.row1, .row2, .row3 {
  position: absolute;
}

.row2 {
  top: 33%;
}

.row3 {
  top: 66%;
}

.panel {
  margin: 0 auto;
  width: 320px;
}

.status {
  padding: 20px;
  font-family: 'Open Sans', sans-serif;
  font-size: 20px;
  color: #fff;
}

.box {
  position: relative;
  height: 100%;
  width: 100%;
  padding: 20px;
  
}

.colorful {
  background: -webkit-radial-gradient(0% 100%, rgba(118, 72, 160, 0.701961) 0px, rgba(118, 72, 160, 0) 60%), -webkit-radial-gradient(90% 100%, rgb(82, 63, 140) 0px, rgba(82, 63, 140, 0) 40%), -webkit-radial-gradient(50% 0%, rgba(84, 90, 182, 0.6) 0px, rgba(84, 90, 182, 0) 75%), -webkit-radial-gradient(100% 0%, rgb(121, 74, 162) 0px, rgba(121, 74, 162, 0) 57%);
  background-color: #3b2f63; 
}

JavaScript

var comm = new Icecomm('ZlhtYUKhl679gI2AmeOXuMQVCKRESIhITIglAlniHWHzA7ikW');

var mediaOptions = {
  stream: false,
  limit: 2
}
var board = [[],[],[]],
    host = false,
    mySign, theirSign, isMyTurn, started;

comm.connect('another room', mediaOptions);

comm.on('data', function(options) {
  if (options.data === 'won') {
    alert('YOU LOST');
  }
  if (mySign) {
    $('button[data-value="' + options.data + '"]').text(theirSign);
    isMyTurn = true;
  }
  if (!mySign && options.data.started) {
    mySign = options.data.theirSign;
    assignSigns(mySign);
  }
});

comm.on('connected', function(options) {
  if (comm.isHost()) {
    mySign = confirm("A player joined. Would you like to start as X?") ? 'X' : 'O';
    assignSigns(mySign);
    var obj = {
      started: true,
      theirSign: theirSign
    };
    comm.send(obj)
  }
});

$('.status').html('Waiting for other player...');

$('button').click(function(event) {
  if (!$(this).text() && isMyTurn) {
    $(this).text(mySign);
    board[Math.floor($(this).data('value')/3)][$(this).data('value')%3] = 1;
    if (hasWon()) {
      alert('YOU WON');
      comm.send('won');
    }
    else {
      comm.send($(this).data('value'));
      isMyTurn = false;
    }
  }
});

function assignSigns(me) {
  theirSign = me === 'X' ? 'O' : 'X';
  isMyTurn = mySign === 'X';
  started = true;
  $('.status').html('Ready to play');
}

function hasWon() {
  if ((board[0][0] === 1 && board[0][1] === 1 && board[0][2] === 1) ||
      (board[1][0] === 1 && board[1][1] === 1 && board[1][2] === 1) ||
      (board[2][0] === 1 && board[2][1] === 1 && board[2][2] === 1) ||
      (board[0][0] === 1 && board[1][0] === 1 && board[2][0] === 1) ||
      (board[0][1] === 1 && board[1][1] === 1 && board[2][1] === 1) ||
      (board[0][2] === 1 && board[1][2] === 1 && board[2][2] === 1) ||
      (board[0][0] === 1 && board[1][1] === 1 && board[2][2] === 1) ||
      (board[0][2] === 1 && board[1][1] === 1 && board[2][0] === 1)) {
    return true;
 ...