JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

Virtual griffin stable, for OotG fansite.<br>Create, rename or delete griffins from list. Make eggs grow, and inspect genomes in detail. Choose two parents to breed and create new eggs.
<br>
<span class='result'></span>
<br>
<button class='tab_button active_tab' data-tab='create'>Create Griffins</button> 
<button class='tab_button' data-tab='breed'>Breeding</button> 
<button class='tab_button' data-tab='inspect'>Inspection</button>
<button id='reset_stable'>Clear Stable</button>

<span id='testing'></span>

<div class='tab_content tab_create' style='display: visible;'>
    <div class='select_holder'>
        <div class='select_div'>
            Name: <input type='text' id='create_name' value='Unnamed'>
        </div>
        <div class='select_div'>
            Sex: <select id='create_sex'>
            <option value='1'>Male</option>
            <option value='2'>Female</option>
            </select>
        </div>
        <div class='select_div'>
            Red: <select id='create_r1'>
                <option value='R'>R</option>
                <option value='r' selected>r</option>
            </select>
            <select id='create_r2'>
            <option value='R'>R</option>
            <option value='r' selected>r</option>
            </select>
        </div>
        <div class='select_div'>
            Green: <select id='create_g1'>
            <option value='G'>G</option>
            <option value='g' selected>g</option>
            </select>
            <select id='create_g2'>
            <option value='G'>G</option>
            <option value='g' selected>g</option>
            </select> 
        </div>
        <div class='select_div'>
            Cream: <select id='create_cr1'>
            <option value='Cr'>Cr</option>
            <option value='cr' selected>cr</option>
            </select>
            <select id='create_cr2'>
            <option value='Cr'>Cr</option>
            <option value='cr' selected>cr</option>
            </select> 
      ...

CSS

* {box-sizing: border-box;}
.select_holder {
    display: flex;
    flex-flow: row wrap;
}
.select_holder .select_div {
    width: 50%;
    padding: 2px;
}

.stack {
    width: 150px;
    display: inline-block;
    background-color: white;
    border: 1px solid grey;
    border-radius: 5px;
    padding: 5px;
    margin: 5px;
    text-align: center;
}

.tab_content {
    display: none;
    padding: 10px;
    border: 1px solid grey;
}


.active_tab {
    border: 1px solid blue;
}

#griffin_list {
    padding: 10px;
    border: 1px solid grey;
    background-color: silver;
    border-radius: 5px;
}

/* These buttons, divs appear only when 2 valid parents are loaded. */
#try_breeding, #baby_image, #baby_genes, #confirm_breeding {
    display: none;
}

.hidden {
    display: none;
}

/* Editable, contains each griffin's name. */
.name_input {
    border: 0;
    max-width: 100%;
    text-align: center;
    font-weight: bold;
    padding: 5px;
}

#error_holder {
    display: none;
    max-width: 40%;
    max-height: 40%;
    background-color: white;
    padding: 10px;
    border: 1px solid grey;
}

JavaScript

// JS for Virtual Griffin Stable by Gwyn Milcote.
// This is part of a fan-site for Order of the Griffin.
// Griffin designs and genetic system belong to Jennifer Hoffman.

const path = "http://mythstable.epizy.com/ootg/images/";

// Alleles in every locus, in order of dominance.
// Used when making random griffins, and ordering genotype.
const genome = {
    r: ["R", "r"],
    g: ["G", "g"],
    k: ["K", "k"],
    w: ["W", "w"],
    e: ["E", "e"],
    cr: ["Cr", "cr"],
    // Below, genes I had to guess.
    // Fade: inc-dominant?
    f: ["F", "f"],
    // Limiter: tiger, leopard. Co-dom.
    lm: ["Lm^t", "Lm^l", "lm"],
    // Agelaius (dusky): dominant?
    ag: ["Ag", "ag"],
    // Mask: recessive? Activated by heating egg?
    m: ["M", "m"],
    // Paint: boots, dip (inc-dom), splash.
    p: ["P^b", "P^d", "P^s", "p"],
    // Sunny: dominant?
    s: ["S", "s"],
    // Fairbelly: dominant?
    fb: ["Fb", "fb"],
    // Nivicolous (snowy): dominant? Activated by cooling egg?
    nv: ["Nv", "nv"]
};

// Names, useful for looping through genos.
const loci = ["r", "g", "k", "w", "e", "cr", "f", "lm", "ag", "m", "p", "s", "fb", "nv"];

// Used when generating babies and random adults.
const names = ["Magic","Storm","Star","Beaky","Fluffy","Screech","Crystal","Blaze","Misty","Soar","Charm","Scratch","Glider","Shine","Beast","Sky","Glade","Mighty","Echo","Breeze","Lightning","Moon","Lucky","Jewel","Talon","Whisper","Dream","Eclipse","Marvel","Phoenix","Cloud","Chimera","Myth"];

const sexNames = ["???", "Male", "Female"];
const stageNames = ["???", "Egg", "Chick", "Cub", "Teen", "Adult"];

// For handling the Virtual Stable minigame.
class Stable {

    constructor(){
        this.loadGriffins();
        // Hold temporary griffs for breeding/scrying.
        this.male = 0;
        this.female = 0;
        this.inspecting = 0;
        this.baby = {id: 0};
        // ID must be unique, higher for each new griff.
        this.lastID = 1;
        if(this.griffins.length >...