JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/jquery.tmpl.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css">
    <div class="toolbar">
        <div>
            <button data-bind="click: function(){readOnly(false)}, visible: readOnly">Edit</button>

            <button data-bind="click: function(){App.save()}, visible: editable">Save</button>
            <button data-bind="click: function(){readOnly(true)}, visible: editable">Cancel</button>
        </div>
        <div style="float: right;">
            <span data-bind="text: readOnly"></span>
        </div>
    </div>
    <div id="toolbarSpacer">
    </div>

    <div class="partner">
        <h1>
            <span data-bind="text: partner.name"></span>
            (<span data-bind="text: partner.gci"></span>)
        </h1>
        <span class="location" data-bind="text: partner.location"></span>
    </div>
    <h2 data-bind="text: description"></h2>

    <div id="tabs">
        <ul>
            <li><a href="#tabs-1">Details</a></li>
            <li><a href="#tabs-2">People</a></li>
            <li><a href="#tabs-3">More</a></li>
            <li><a href="#tabs-4">JSON</a></li>
        </ul>
        <div id="tabs-1">
        
            <table><tr><td>
            <table class="label">
                <tbody>
                    <tr>
                        <td>Description:</td>
                        <td>
                            <span data-bind="text: description, visible: readOnly"></span>
                            <input type="text" name="description" data-bind="value: description, visible: editable"
                                width="150" />
                       ...

CSS

body {
    font: 62.5% "Trebuchet MS", sans-serif;
    margin: 20px;
    font-size: 0.8em;
}
td {
    vertical-align: top;
}
table.label td:first-child {
    font-weight: bold;
    text-align: right;
}
#products {
    width: 145px;
}
#products select {
    width: 140px;
}
#products span {
    display: inline-block;
}
#products span.remove {
    float: right;
    cursor: pointer;
}
.meta {
    color: gray;
}
div.partner h1 {
    color: #CC3333;
    margin: 0; padding: 0;
}
div.toolbar {
    position: fixed;
    border: 1px solid black;
    left: 0;
    top: 0;
    right: 0;
    background-color: gray;
}
#toolbarSpacer {
    height: 30px;
}

table.contact {
    width: 600px;
    border: 1px solid black;
    border-collapse: collapse;
}
table.contact td, table.contact th {
    border: 1px solid gray;
}

JavaScript

function RefValue(code, label) {
        this.code = code;
        this.label = label;
        this.toString = function() {
            return this.label;
        };
    };
    
    RefValue.comparator = function(a, b){
        if (a == null || b == null) {
            return a == null ? -1 : 1;
        };
        if (a.label < b.label) {
            return -1;
        } else if (a.label > b.label) {
            return 1;
        } else {
            return 0;
        }
    };
    
    function RVList(items) {
        this.items = items;
        
        this.get = function(code) {
            for (i = 0, len = this.items.length; i < len; i++) {
                if (this.items[i].code == code) {
                    return this.items[i];
                }
            }
            return null;
        };
    }

    window.rm = {
        months: ["Jan","Feb","Mar","Apr","Mar","Jun",
                  "Jul","Aug","Sep","Oct","Nov","Dec"],

          padMinutes: function(min) {
            return min < 10 ? ("0" + min) : min; 
        },

        formatDate: function(timestamp) {
            var d = new Date(timestamp);
            return d.getFullYear() + "-" + d.getMonth() + "-" + d.getDate();
        },
        
        formatDateTime: function(timestamp) {
            var d = new Date(timestamp);
            return d.getFullYear() + "-" + this.months[d.getMonth()] + "-" + d.getDate()
                + " " + d.getHours() + ":" + this.padMinutes(d.getMinutes());
        },
        

        oppStatus: new RVList([
            new RefValue("OPEN", "Open"),
            new RefValue("ONHOLD","On Hold"),
            new RefValue("WON", "Won"),
            new RefValue("LOST","Lost"),
            new RefValue("ABAND", "Abandoned")
        ]),

        products: new RVList([ 
                new RefValue("",""), 
                new RefValue("AIR", "Air"),
                new RefValue("OCEAN", "Ocean"),
                new RefValue("INSUR", "Insurance"),
               ...