<form class="calc">
  <div class="calc__logo">
    <span class="calc__j">J</span>K
  </div>
  <div class="calc__memory"></div>
  <div class="calc__error"></div>
  <input class="calc__screen" type="text" name="output" maxlength="10" value="0" readonly>
  <div class="calc__btns">
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="%" title="Percent" aria-label="Percent" ontouchstart="">
      <span tabindex="-1">%</span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="sqrt" title="Square Root" aria-label="Square Root" ontouchstart="">
      <span tabindex="-1"><small>&radic;</small></span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="+-" title="Negate Value" aria-label="Negate Value" ontouchstart="">
      <span tabindex="-1"><small>+/-</small></span>
    </button>
    <button class="calc__btn calc__btn--primary" type="button" data-fn="C" title="Clear" aria-label="Clear" ontouchstart="">
      <span tabindex="-1">C</span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="mrc" title="Recall/Clear Memory" aria-label="Recall/Clear Memory" ontouchstart="">
      <span tabindex="-1"><small>MRC</small></span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="m-" title="Subtract From Memory" aria-label="Subtract From Memory" ontouchstart="">
      <span tabindex="-1"><small>M-</small></span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="m+" title="Add To Memory" aria-label="Add To Memory" ontouchstart="">
      <span tabindex="-1"><small>M+</small></span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="/" title="Divided By" aria-label="Divided By" ontouchstart="">
      <span tabindex="-1">&divide;</span>
    </button>
    <button class="calc__btn" type="button" data-fn="7" ontouchstart="">
      <span tabindex="-1">7</span>
    </button>
    <button class="calc__btn" type="button" data-fn="8" ontouchstart="">
      <span tabindex="-1">8</span>
    </button>
    <button class="calc__btn" type="button" data-fn="9" ontouchstart="">
      <span tabindex="-1">9</span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="*" title="Times" aria-label="Times" ontouchstart="">
      <span tabindex="-1">&times;</span>
    </button>
    <button class="calc__btn" type="button" data-fn="4" ontouchstart="">
      <span tabindex="-1">4</span>
    </button>
    <button class="calc__btn" type="button" data-fn="5" ontouchstart="">
      <span tabindex="-1">5</span>
    </button>
    <button class="calc__btn" type="button" data-fn="6" ontouchstart="">
      <span tabindex="-1">6</span>
    </button>
    <button class="calc__btn calc__btn--secondary" type="button" data-fn="-" title="Minus" aria-label="Minus" ontouchstart="">
      <span tabindex="-1">-</span>
    </button>
    <button class="calc__btn" type="button" data-fn="1" ontouchstart="">
      <span tabindex="-1">1</span>
    </button>
    <button class="calc__btn" type="button" data-fn="2" ontouchstart="">
      <span tabindex="-1">2</span>
    </button>
    <button class="calc__btn" type="button" data-fn="3" ontouchstart="">
      <span tabindex="-1">3</span>
    </button>
    <button class="calc__btn calc__btn--secondary calc__btn--tall" type="button" data-fn="+" title="Plus" aria-label="Plus" ontouchstart="">
      <span tabindex="-1">+</span>
    </button>
    <button class="calc__btn" type="button" data-fn="0" ontouchstart="">
      <span tabindex="-1">0</span>
    </button>
    <button class="calc__btn" type="button" data-fn="." aria-label="Point" ontouchstart="">
      <span tabindex="-1">.</span>
    </button>
    <button class="calc__btn" type="button" data-fn="=" title="Equals" aria-label="Equals" ontouchstart="">
      <span tabindex="-1">=</span>
    </button>
  </div>
</form>
* {
  border: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
:root {
  --bg: #c7cad1;
  --fg: #17181c;
  --calcBg: #e3e4e8;
  --fg: #17181c;
  --logoBlue: #255ff4;
  --transDur: 0.05s;
  --buttonTiming: linear;
  font-size: calc(20px + (30 - 20) * (100vw - 320px) / (1280 - 320));
}
body, button, input {
  color: var(--fg);
  font: 1em/1.5 "Hind", sans-serif;
}
body {
  background-color: var(--bg);
  display: grid;
  padding: 1.5em 0;
  place-items: center;
  height: 100vh;
}
.calc {
  background-color: var(--calcBg);
  background-image:
    linear-gradient(180deg,#0000,#0001),
    radial-gradient(0.25em 0.25em at 0.5em 0.25em,#fff7 25%,#fff0 50%),
    radial-gradient(95% 0.25em at 50% 0.25em,#fff7 25%,#fff0 50%);
  border-radius: 0.75em;
  box-shadow:
    0 0.5em 0.5em #fff4 inset,
    0 -0.125em 0.25em 0.125em #0007 inset,
    0 0.25em 0.75em #0007;
  padding: 0.25em 1em;
  position: relative;
  width: 12em;
  height: 19.5em;
}
.calc__btns {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-template-rows: repeat(6,1.5em);
  grid-gap: 0.5em 0.75em;
}
.calc__btn:focus, .calc__btn span:focus, .calc__screen:focus {
  outline: transparent;
}
.calc__btn, .calc__screen {
  -webkit-appearance: none;
  appearance: none;
}
.calc__btn, .calc__btn.calc__btn--primary, .calc__btn.calc__btn--secondary {
  color: #fff;
}
.calc__btn {
  background-color: #2e3138;
  background-image:
    linear-gradient(180deg,#0000,#0002),
    radial-gradient(90% 0.125em at 50% 0.125em,#fff7 25%,#fff0 50%);
  border: 0;
  border-radius: 0.25em;
  box-shadow:
    0.125em 0.125em 0.25em #0007,
    0 -0.05em 0 0.05em #0004,
    0 0.05em 0 0.05em #fff4,
    -0.125em 0 0.125em #22252a inset,
    0 0.125em 0.125em #fff4 inset,
    0.125em 0 0.125em #fff4 inset,
    0 -0.125em 0.125em #22252a inset;
  cursor: pointer;
  text-shadow: 0 0 0.125em #fff7;
  transition: box-shadow var(--transDur) var(--buttonTiming);
  -webkit-tap-highlight-color: #0000;
}
.calc__btn:active, .calc__btn.calc__btn--active {
  box-shadow:
    0 0 0 #0007,
    0 -0.05em 0 0.05em #0004,
    0 0.05em 0 0.05em #fff4,
    -0.125em 0 0.125em #0b0c0e inset,
    0 0.125em 0.125em #0004 inset,
    0.125em 0 0.125em #0004 inset,
    0 -0.125em 0.125em #0b0c0e inset;
}
.calc__btn:active span, .calc__btn.calc__btn--active span {
  transform: scale(0.95);
}
.calc__btn:focus {
  color: #86a6f9;
  text-shadow: 0 0 0.25em #86a6f977;
}
.calc__btn small, .calc__btn span {
  pointer-events: none;
}
.calc__btn span {
  display: block;
  transition: transform var(--transDur) var(--buttonTiming);
}
.calc__btn.calc__btn--primary {
  background-color: #255ff4;
  box-shadow:
    0.125em 0.125em 0.25em #0007,
    0 -0.05em 0 0.05em #0004,
    0 0.05em 0 0.05em #fff4,
    -0.125em 0 0.125em #0936aa inset,
    0 0.125em 0.125em #fff4 inset,
    0.125em 0 0.125em #fff4 inset,
    0 -0.125em 0.125em #0936aa inset;
}
.calc__btn.calc__btn--primary:active, .calc__btn.calc__btn--primary.calc__btn--active {
  box-shadow:
    0 0 0 #0007,
    0 -0.05em 0 0.05em #0004,
    0 0.05em 0 0.05em #fff4,
    -0.125em 0 0.125em #062779 inset,
    0 0.125em 0.125em #0004 inset,
    0.125em 0 0.125em #0004 inset,
    0 -0.125em 0.125em #062779 inset;
}
.calc__btn.calc__btn--secondary {
  background-color: #5c6270;
  box-shadow:
    0.125em 0.125em 0.25em #0007,
    0 -0.05em 0 0.05em #0004,
    0 0.05em 0 0.05em #fff4,
    -0.125em 0 0.125em #454954 inset,
    0 0.125em 0.125em #fff4 inset,
    0.125em 0 0.125em #fff4 inset,
    0 -0.125em 0.125em #454954 inset;
}
.calc__btn.calc__btn--secondary:active, .calc__btn.calc__btn--secondary.calc__btn--active {
  box-shadow:
    0 0 0 #0007,
    0 -0.05em 0 0.05em #0004,
    0 0.05em 0 0.05em #fff4,
    -0.125em 0 0.125em #2e3138 inset,
    0 0.125em 0.125em #0004 inset,
    0.125em 0 0.125em #0004 inset,
    0 -0.125em 0.125em #2e3138 inset;
}
.calc__btn--tall {
  grid-column: 4 / 5;
  grid-row: 5 / 7;
}
.calc__error, .calc__memory, .calc__screen {
  color: #17181c;
}
.calc__error, .calc__memory {
  font-weight: bold;
  position: absolute;
  left: 1.5em;
  text-shadow: 0.1em 0.1em 0.1em #0004;
}
.calc__error {
  top: 4.3em;
}
.calc__memory {
  top: 3.4em;
}
.calc__j {
  color: var(--logoBlue);
  text-shadow: 0 0 0.25em #255ff444;
}
.calc__logo {
  font-size: 2em;
  text-align: center;
  text-shadow: 0 0 0.25em #0004;
  height: 3rem;
}
.calc__screen {
  background-image: linear-gradient(180deg,#9aa38f,#8d9781);
  border-top: 0.25rem solid #abafba;
  border-right: 0.25rem solid #abafba;
  border-bottom: 0.25rem solid #fff;
  border-left: 0.25rem solid #c7cad1;
  border-radius: 0.25rem;
  box-shadow:
    0 0.25rem 0.25rem #0007 inset;
  display: block;
  font: 2em/1 "VT323", monospace;
  margin: 0 auto 1rem auto;
  padding: 0 0.25rem;
  text-align: right;
  text-shadow: 0.1rem 0.1rem 0.1rem #0004;
  text-transform: uppercase;
  width: 100%;
}
.calc__screen--fade-in {
  animation: valueBlink 0.05s linear;
}
/* Dark theme */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #454954;
    --fg: #e3e4e8;
    --calcBg: #17181c;
    --logoBlue: #5583f6;
  }
  .calc__btn {
    background-color: #e3e4e8;
    background-image:
      linear-gradient(180deg,#0000,#0002),
      radial-gradient(90% 0.125em at 50% 0.125em,#fff7 25%,#fff0 50%);
    box-shadow:
      0.125em 0.125em 0.25em #0007,
      0 -0.05em 0 0.05em #0004,
      0 0.05em 0 0.05em #fff1,
      -0.125em 0 0.125em #737a8c inset,
      0 0.125em 0.125em #fff4 inset,
      0.125em 0 0.125em #fff4 inset,
      0 -0.125em 0.125em #737a8c inset;
    color: #17181c;
    text-shadow: 0 0 0.125em #fff7;
  }
  .calc__btn:active, .calc__btn.calc__btn--active {
    box-shadow:
      0 0 0 #0007,
      0 -0.05em 0 0.05em #0004,
      0 0.05em 0 0.05em #fff1,
      -0.125em 0 0.125em #5c6270 inset,
      0 0.125em 0.125em #0004 inset,
      0.125em 0 0.125em #0004 inset,
      0 -0.125em 0.125em #5c6270 inset;
  }
  .calc__btn.calc__btn--primary {
    box-shadow:
      0.125em 0.125em 0.25em #0007,
      0 -0.05em 0 0.05em #0004,
      0 0.05em 0 0.05em #fff1,
      -0.125em 0 0.125em #0936aa inset,
      0 0.125em 0.125em #fff4 inset,
      0.125em 0 0.125em #fff4 inset,
      0 -0.125em 0.125em #0936aa inset;
  }
  .calc__btn.calc__btn--primary:active, .calc__btn.calc__btn--primary.calc__btn--active {
    box-shadow:
      0 0 0 #0007,
      0 -0.05em 0 0.05em #0004,
      0 0.05em 0 0.05em #fff1,
      -0.125em 0 0.125em #062779 inset,
      0 0.125em 0.125em #0004 inset,
      0.125em 0 0.125em #0004 inset,
      0 -0.125em 0.125em #062779 inset;
  }
  .calc__btn.calc__btn--secondary {
    box-shadow:
      0.125em 0.125em 0.25em #0007,
      0 -0.05em 0 0.05em #0004,
      0 0.05em 0 0.05em #fff1,
      -0.125em 0 0.125em #454954 inset,
      0 0.125em 0.125em #fff4 inset,
      0.125em 0 0.125em #fff4 inset,
      0 -0.125em 0.125em #454954 inset;
  }
  .calc__btn.calc__btn--secondary:active, .calc__btn.calc__btn--secondary.calc__btn--active {
    box-shadow:
      0 0 0 #0007,
      0 -0.05em 0 0.05em #0004,
      0 0.05em 0 0.05em #fff1,
      -0.125em 0 0.125em #2e3138 inset,
      0 0.125em 0.125em #0004 inset,
      0.125em 0 0.125em #0004 inset,
      0 -0.125em 0.125em #2e3138 inset;
  }
  .calc__logo {
    text-shadow: 0 0 0.25em #fff4;
  }
  .calc__screen {
    border-top: 0.25rem solid #2e3138;
    border-right: 0.25rem solid #2e3138;
    border-bottom: 0.25rem solid #454954;
    border-left: 0.25rem solid #454954;
  }
}
/* Animation */
@keyframes valueBlink {
  from {
    color: #17181c00;
    text-shadow: 0.1rem 0.1rem 0.1rem #0000;
  }
  to {
    color: #17181c;
    text-shadow: 0.1rem 0.1rem 0.1rem #0004;
  }
}
document.addEventListener("DOMContentLoaded",app);

function app() {
  let calc = document.forms[0],
    isCalcing = false,
    error = "",
    val = 0,
    m = 0,
    op = "",
    exp = [],
    lastPart = "",
    lastOperand = 0,
    signs = /[\/\*\-\+]/,
    debug = false,
    action = e => {
      let tar = e.target || e,
        fn = fnByKey(e.keyCode,e.shiftKey,e.altKey,e.metaKey),
        output = calc.output;
      // prevent a click right after equals if a button is in focus
      if (e.keyCode == 13)
        e.preventDefault();
      // pressing button on screen
      else if (!fn && !e.keyCode)
        fn = tar.getAttribute("data-fn");

      if (fn && output) {
        let maxLen = +output.maxLength,
          maxVal = 10 ** maxLen,
          fnIsNum = !isNaN(fn),
          fnIsDec = fn == ".",
          fnIsPct = fn == "%",
          fnIsSqrt = fn == "sqrt",
          fnIsSign = fn == "+-",
          recallOrClearM = fn == "mrc",
          subFromM = fn == "m-",
          addToM = fn == "m+",
          fnIsOp = "/*-+".indexOf(fn) > -1,
          fnIsEquals = fn == "=",
          fnIsClear = fn == "C";

        if (!error) {
          if (exp.length)
            lastPart = exp[exp.length - 1];

          if (fnIsNum || fnIsDec || fnIsPct || fnIsSqrt || fnIsSign || fnIsOp) {
            // start a new expression if `=` was previously pressed
            if (!isCalcing) {
              isCalcing = true;
              if (fnIsNum || fnIsDec) {
                op = "";
                exp = ["0"];
                lastPart = exp[0];
                lastOperand = 0;
              }
            }
            if (!exp.length)
              exp.push("0");
          }
          // number
          if (fnIsNum) {
            if (isNaN(lastPart)) {
              exp.push(fn);
            } else if (lastPart.length < maxLen) {
              let numToAdd = lastPart + fn;
              // prevent whole numbers beginning with 0
              if (numToAdd[0] == "0" && numToAdd[1] != ".")
                numToAdd = numToAdd.substr(1);

              exp[exp.length - 1] = numToAdd;
            }
          // decimal point
          } else if (fnIsDec) {
            if (lastPart.indexOf(".") == -1) {
              if (isNaN(lastPart))
                exp.push("0.");
              else if (lastPart.length < maxLen - 1)
                exp[exp.length - 1] += fn;
            }
          // percent
          } else if (fnIsPct) {
            if (exp.length) {
              if (!isNaN(lastPart)) {
                if (op && exp.indexOf(op) > -1) {
                  exp[exp.length - 1] = nearestLastDecPt(exp[0] * exp[exp.length - 1] / 100);
                } else {
                  exp[exp.length - 1] = nearestLastDecPt(exp[exp.length - 1] / 100);
                  isCalcing = false;
                }
              } else {
                exp.push(`${exp[0] * (exp[0] / 100)}`);
                exp[exp.length - 1] = nearestLastDecPt(exp[exp.length - 1]);
              }
            }
            blink();
          // square root
          } else if (fnIsSqrt) {
            if (exp.length) {
              if  (!isNaN(lastPart))
                exp[exp.length - 1] = String(Math.sqrt(exp[exp.length - 1]));
              else
                exp.push(String(Math.sqrt(exp[0])));
            }
            blink();
          // toggle sign
          } else if (fnIsSign) {
            if (exp.length) {
              if  (!isNaN(lastPart))
                exp[exp.length - 1] = String(-exp[exp.length - 1]);
              else
                exp[0] = String(-exp[0]);
            }
          // memory
          } else if (recallOrClearM) {
            if (m != 0 && m == val) {
              if (exp.length <= 1) {
                isCalcing = false;
                m = 0;
                displayM(false);
              }

            } else {
              if (!isCalcing)
                isCalcing = true;

              if (isNaN(lastPart) || !exp.length)
                exp.push(String(m));
              else
                exp[exp.length - 1] = String(m);

              lastPart = exp[exp.length - 1];
              lastOperand = lastPart;
              
              displayM(m != 0);
            }
          // operation
          } else if (fnIsOp) {
            op = fn;
            // switch operator
            if (isNaN(lastPart)) {
              exp[exp.length - 1] = op;
            // calculate the current expression before using the operator
            } else {
              let curExp = exp.join(" ");
              if (signs.test(curExp)) {
                exp = [`${solve(exp[0],exp[1],exp[2])}`];
                exp[0] = nearestLastDecPt(exp[0]);
                lastPart = exp[0];
                val = lastPart;
              }
              exp.push(op);
            }
            blink();
          // equals, m-. or m+
          } else {
            let memAction = subFromM || addToM;
            if (fnIsEquals || memAction) {
              isCalcing = false;

              if (op && exp.indexOf(op) > -1)
                lastOperand = lastPart;
              
              let compoundEquals = lastOperand && exp.indexOf(op) == -1,
                normalEquals = !isNaN(lastOperand);
            
              if (compoundEquals) {
                if (!memAction)
                  exp = [`${solve(val,op,lastOperand)}`];

              } else if (normalEquals) {
                exp = [`${solve(exp[0],op,lastOperand)}`];
              // equals without a second operand
              } else {
                lastOperand = exp[0];
                exp = [`${solve(val,op,val)}`];
              }
              
              exp[0] = nearestLastDecPt(exp[0]);

              // decrement/increment memory value by screen value
              if (memAction) {
                if (subFromM)
                  m -= +exp[0];
                if (addToM)
                  m += +exp[0];

                displayM(m != 0);
                if (debug)
                  console.log(`M: ${m}`);
              }
              blink();
            }
          }
          if (fn != "C") {
            lastPart = exp[exp.length - 1];
            if (!isNaN(lastPart) || lastPart == "NaN")
              val = lastPart;
            // deal with infinity, 0 / 0, square root of a negative number, or integer overflow
            if (Math.abs(val) == Infinity || val == "NaN") {
              error = "0";

            } else if (val <= -maxVal / 10) {
              let cutNeg = maxLen - 3;
              if (cutNeg < 0)
                cutNeg = 0;
              error = (val / maxVal).toFixed(cutNeg);

            } else if (val >= maxVal) {
              let cutPos = maxLen - 2;
              if (cutPos < 0)
                cutPos = 0;
              error = (val / maxVal).toFixed(cutPos);
            }
            // update the display
            let outputVal = error || String(val);
            if (!error) {
              // fit the value into the screen without ending with a decimal point
              if ((val >= -1e8 && val < -1e7) || (val >= 1e8 && val < 1e9))
                outputVal = outputVal.substr(0,maxLen - 1);
              else
                outputVal = outputVal.substr(0,maxLen);

            } else {
              displayE();
            }
            output.value = outputVal;
          }
        }
        // clear
        if (fnIsClear) {
          if (debug)
            console.clear();
          isCalcing = false;
          error = "";
          val = 0;
          // prevent storage of infinity or non-numbers
          if (Math.abs(m) == Infinity || isNaN(m)) {
            m = 0;
            displayM(false);
          }
          op = "";
          exp = [];
          lastPart = "";
          lastOperand = 0;
          output.value = val;
          blink();
          displayE(false);
        }
        if (debug)
          console.log(exp);
      }
    },
    blink = () => {
      let output = calc.output;
      if (output) {
        let fadeInClass = "calc__screen--fade-in",
          screenCL = output.classList;

        screenCL.remove(fadeInClass);
        void output.offsetWidth;
        setTimeout(() => {
          screenCL.add(fadeInClass);
        },0);
      }
    },
    displayE = (show = true) => {
      let ce = calc.querySelector(".calc__error");
      ce.textContent = show ? "E" : "";
    },
    displayM = (show = true) => {
      let cm = calc.querySelector(".calc__memory");
      cm.textContent = show ? "M" : "";
    },
    fnByKey = (keycode,isShift,isAlt,isCmd) => {
      let fn = "";
      switch (keycode) {
        case 12:
        case 27:
        case 67:
          if (!isCmd)
            fn = "C";
          break;
        case 13:
          fn = "=";
          break;
        case 48:
        case 96:
          fn = "0";
          break;
        case 49:
        case 97:
          fn = "1";
          break;
        case 50:
        case 98:
          fn = "2";
          break;
        case 51:
        case 99:
          fn = "3";
          break;
        case 52:
        case 100:
          fn = "4";
          break;
        case 53:
        case 101:
          fn = isShift ? "%" : "5";
          break;
        case 54:
        case 102:
          fn = "6";
          break;
        case 55:
        case 103:
          fn = "7";
          break;
        case 56:
          fn = isShift ? "*" : "8";
          break;
        case 104:
          fn = "8";
          break;
        case 57:
        case 105:
          fn = "9";
          break;
        case 77:
          fn = "mrc";
          break;
        case 83:
          fn = "sqrt";
          break;
        case 106:
          fn = "*";
          break;
        case 107:
          fn = "+";
          break;
        case 187:
          fn = isShift ? "+" : "=";
          break;
        case 188:
          fn = isShift ? "m-" : "";
          break;
        case 109:
        case 189:
          fn = isAlt ? "+-" : "-";
          break;
        case 110:
          fn = ".";
          break;
        case 190:
          fn = isShift ? "m+" : ".";
          break;
        case 111:
        case 191:
          fn = "/";
          break;
        default:
          fn = "";
          break;
      }
      return fn;
    },
    kbdButtonPress = (e,state = "down") => {
      let tar = e.target || e,
        fn = fnByKey(e.keyCode,e.shiftKey,e.altKey,e.metaKey),
        key = calc.querySelector(`[data-fn="${fn}"]`);

      if (key) {
        let activeClass = "calc__btn--active",
          keyCL = key.classList;

        if (state == "down" && !keyCL.contains(activeClass))
          keyCL.add(activeClass);
        else if (state == "up" && keyCL.contains(activeClass))
          keyCL.remove(activeClass);
      }
    },
    nearestLastDecPt = (n,places = 9) => {
      let power = 10 ** -places,
        r = Math.round(n / power) * power;
      return String(+r.toFixed(places));
    },
    solve = (A,op,B) => {
      let r = 0,
        a = !isNaN(A) ? +A : r,
        b = !isNaN(B) ? +B : a;

      switch (op) {
        case "/":
          r = a / b;
          break;
        case "*":
          r = a * b;
          break;
        case "-":
          r = a - b;
          break;
        case "+":
          r = a + b;
          break;
        default:
          r = a;
          break;
      }
      return r;
    };

  calc.addEventListener("click",action);
  document.addEventListener("keydown",action);
  document.addEventListener("keydown",kbdButtonPress);
  document.addEventListener("keyup",e => kbdButtonPress(e,"up"));
}

External CSS

  1. https://fonts.googleapis.com/css2?family=Hind:wght@400;700&amp;display=swap
  2. https://fonts.googleapis.com/css2?family=VT323&amp;display=swap

External JavaScript

This Pen doesn't use any external JavaScript resources.