JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

<div id='container'>

<p>Beasts have two pigments, eumelanin and phaeomelanin. Phaeo is the 'ground colour' while eu is the 'pattern colour' used for markings like stripes, spots, etc. Phaeo is naturally yellow/red/brown and eu is naturally black/grey/brown. Various alleles dilute them, or shift the colour, see palettes below.</p>
<p>For some species these pigments appear in natural colours (common bay, buckskin, palomino unicorns). Other species have an Exotic Factor which means one/both pigments instead appear any colour from the rainbow spectrum ('bay' unicorn with pink body and purple points). By breeding or using items, a natural beast can be made exotic-coloured, or vice versa.</p>
<p>All beasts carry 2 hidden values for the exotic colours, even if they don't have the Exotic Factor. You can guess the exotic phaeo colour because it's always a beast's eye colour. It, and the exotic eu colour, may also appear on butterfly wings or other body areas, in a few colourful species. (So there may be up to 4 colours on same beast) (In exotic beasts, maybe the eye colour appears in natural phaeo colour, and any exotic eu areas appear in natural eu colour. Like a reverse of the usual)</p>

<hr>

<div class='title'>Preview test</div>

<div id='preview-container'>
    <div id='beast-preview'><p>Beast profile image will be generated here later. For now, see the pigment colours and layer URLs that will be used.</p></div>
    <div id='preview-dropdowns'></div>
</div>

<hr>

<div class='title'>Eumelanin Palette</div>
<p>Naturally black, at darkest shade. Chocolate gives it a brown colour, Cinnamon makes it reddish. Blue can combine with those to create blue, violet and pink. Steel dilutes to shade 3, Smoky dilutes to shade 2 and Lavender/Ice both dilute to shade 1. Inhibitor allele turns it white.</p>
<div id='palette-eu' class='palette-natural'></div>

<div class='title'>Phaeomelanin Palette</div>
<p>Naturally tan-coloured and shade 3. Mahogany allele makes colour redder....

CSS

div, img, canvas, button, p, select {
    box-sizing: border-box;
}

body {
    font-family: 'Arial', sans-serif;
    font-size: 16px;
    background-color: silver;
}

#container {
    width: 900px;
    margin: 20px auto;
    background-color: #fff;
}
#container .title {
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    margin: 10px auto;
    padding: 10px;
    border-top: 1px solid silver;
    border-bottom: 1px solid silver;
}

.palette-exotic {
    width: 800px;
    margin: 10px auto;
    border: 1px solid black;
}
.palette-exotic .exotic-row {
    display: flex;
    flex-flow: row;
    height: 30px;
}
.palette-exotic .exotic-swatch {
    width: 40px;
    height: 30px;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.3);
}

#palette-eu, #palette-phaeo {
    width: 800px;
    margin: 10px auto;
    display: flex;
    flex-flow: row wrap;
    border: 1px solid black;
}
#palette-eu .four-swatches {
    width: 33.3%;
    /*border: 1px solid silver;*/
    padding: 5px;
    margin-bottom: 10px;
}
#palette-phaeo .four-swatches {
    width: 25%;
    /*border: 1px solid silver;*/
    padding: 5px;
    margin-bottom: 10px;
}

.palette-natural .swatch-title {
    text-align: center;
    font-weight: bold;
    border-bottom: 1px solid silver;
    padding-bottom: 5px;
}
.palette-natural .swatch-container {
    background-color: #eee;
    margin-top: 5px;
    display: flex;
    align-items: center;
}
.palette-natural .swatch {
    width: 40px;
    height: 40px;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
    margin-right: 10px;
}




.allele-list {
    margin: 20px auto;
}
.allele-list .allele-entry {
    margin-bottom: 5px;
    border: 1px solid silver;
    padding: 5px;
    display: flex;
    align-items: center;
}
.allele-list .allele-entry img {
    width: 150px;
    height: 100px;
    margin-right: 10px;
}


#preview-container {
    position: relative;
    height: 400px;
    margin: 20px auto;
}

#beast-preview {
    border: 1px dashed...

JavaScript

const db = {
    // Names, descs, alleles in them.
    loci: [
        {
            name: "BlackColour", symbol: "bc",
            wt: "Black",
            desc: "",
            alleles: [
                {
                    name: "Black",
                    desc: "Wildtype. Enables black eumelanin."
                },{
                    name: "Chocolate",
                    desc: "Recessive."
                },{
                    name: "Cinnamon",
                    desc: "Recessive."
                },{
                    name: "Blueshift",
                    desc: "Homo lethal."
                },{
                    name: "Exotic",
                    desc: "Recessive."
                }
            ]
        },
        {
            name: "BlackShade", symbol: "bs",
            wt: "Wildtype",
            desc: "",
            alleles: [
                {
                    name: "Inhibitor",
                    desc: "Dominant. Switches off eumelanin."
                },{
                    name: "Smoky",
                    desc: "Inc-dominant. Dilutes eumelanin somewhat, then removes completely."
                },{
                    name: "Steel",
                    desc: "Dominant. Dilutes eumelanin slightly."
                },{
                    name: "Wildtype",
                    desc: "No effect."
                },{
                    name: "Ice",
                    desc: "Recessive. Strongly dilutes eumelanin."
                }
            ]
        },
        {
            name: "RedColour", symbol: "rc",
            wt: "Gold",
            desc: "",
            alleles: [
                {
                    name: "Mahogany",
                    desc: "Dominant. Makes phaeomelanin redder."
                },{
                    name: "Gold",
                    desc: "Wildtype allele. Phaeomelanin is tan coloured."
                },{
                    name: "Exotic",
                    desc: "Recessive. Enables...