// 60% layout
// type away !
-
  const row1 = [  ['💀', '', 's2 esc'], ['1', '!'], ['2', '@'], ['3', '#'], ['4', '$'], ['5', '%'], ['6', '^'], ['7', '&'], ['8', '*'], ['9', '('], ['0', ')'], ['-', '_', 'sub'],   ['=', '+', 'add'],   ['😅', '', 's4 back'] ]
  const row2 = [  ['📑', '', 's3 tab'], ['Q'],  ['W'],  ['E'], ['R'], ['T'], ['Y'], ['U'], ['I'], ['O'], ['P'], [ '\[', '\{', 'openbracket' ], [ '\]', '\}', 'closebracket'],  ['\\', '|', 's3 pipe'] ]
  const row3 = [  ['🔓', '', 's4 cap'],  ['A'],  ['S'],  ['D'], ['F', '', 'dotted'], ['G'], ['H'], ['J', '', 'dotted'], ['K'], ['L'], [';', ':', 'semi'], ['\,', '\"', 'comma'], ['😤', '', 's4 enter'] ]
  const row4 = [  ['💪', '', 's5 shift'], ['Z'],  ['X'],  ['C'], ['V'], ['B'], ['N'], ['M'], [',', '<', 'openangular'], ['.', '>', 'closeangular'], ['\/', '?', 'slash'], ['💪', '', 's5 shift up'] ]
  const row5 = [  ['☕', '', 's3 control'], ['🤩', '', 's3 win'],  ['⭐️', '', 's3 alt'], ['', '', 's12 space'],  ['⭐️', '', 's3 alt'], ['🌈', '', 's2 fn left'], ['👨‍💻', '', 's2 fn down'], ['☕', '', 's2 control right'] ]
  const rows = [...row1, ...row2, ...row3, ...row4, ...row5 ]
  
mixin key(k)
  - let size = k[2] ? k[2] : ''
  if k[1] && k[1] != ''
    .key(on-shift=k[1], class=size data-key=k[0])= k[0]
  else
    .key(class=size data-key=k[0])= k[0]

// -----------------------------------------------

.keyboard
  for k in rows
    +key(k)
View Compiled
// don't like lights ? turn it off here 
backlight = true 

// neo colors
light       = #D8DEE8
dark        = #ADBACE
mid         = mix(light, dark)
lightest    = tint(light, 70%)

// responsive sizing
g-size      = (95/50)vw
shadow-size = g-size/6


// neo shadow mixin
neo(light, dark)
  box-shadow: -1*shadow-size  -1*shadow-size  3*shadow-size   light, 
              shadow-size     shadow-size     2*shadow-size   dark
      
neo-press(light, dark)
  hightlight = tint(light, 40%)
  &:hover, &.pressed
    transform     perspective(300px) scale(0.97)
    box-shadow:   inset   -1*shadow-size  -1*shadow-size  3*shadow-size   -0.5*shadow-size tint(light, 30%), 
                  inset   shadow-size     shadow-size     2*shadow-size   dark
    if backlight
      color         white
      text-shadow:  0 0 10px hightlight,  
                    0 0 15px hightlight, 
                    0 0 20px hightlight

                   
// customize shadow for any color      
customize(color)
  background  color
  color       lighten(color, 80%)
  neo-press   lighten(color, 10%)   darken(color, 30%)

  
  
// styles -----------------

.keyboard
  display               grid
  grid-template-columns repeat(30, g-size ) 
  grid-template-rows    repeat(5, g-size*2.5 ) 
  grid-gap              (g-size/2)
  background            mid
  padding               (g-size/1.1)
  border-radius         (g-size/1.5)
  background            light 
  neo                   lightest mid 

  .key
    border-radius   (g-size/2.5)
    grid-column     auto / span 2
    width           100%
    height          100%
    padding         (g-size/4)
    font-size       (g-size)
    display         grid
    align-items     center
    color           shade(dark, 20%)
    justify-content center
    cursor          pointer
    background      light
    neo             lightest mid
    transition      all 100ms cubic-bezier(.09,.32,.34,2)
    user-select     none
    neo-press       lightest mid
    
    &.dotted
      position      relative
      &::before
        content     '_'
        font-weight bold
        color       tint(dark, 10%)
        position    absolute
        top         70%
        left        50%
        transform   translate(-50%, -50%)
      
    &.esc
      customize(#ed4c67)
      
    &.back
      customize(#d63031)
      
    &.shift
      customize(#1e90ff)
      
    &.control
      customize(#be2edd)
   
    &.win
      customize(#f7b731)
      
    &.alt
      customize(#5352ed)
      
    &.fn
      customize(#26de81)
      
    &.cap
      customize(#ee5a24)
      position relative
      &::before
        content ''
        position absolute
        width 0.5vw
        height 0.5vw 
        background tint(#ee5a24, 50%) 
        top 1vw
        right 1vw
        border-radius 50%
      &.on::before
        background tint(#ee5a24, 80%) 
        box-shadow 0 0 0.5vw 0.2vw rgba(white, 0.8)
     
    &.tab
      customize(#12cbc4)
      
    &.enter
      customize(#fdcb6e)


    for i in 2 3 4 5 6 12
      &.s{i}
        font-size   (g-size/1.1)
        grid-column auto / span i

        
    &[on-shift]
      font-size     (g-size/1.3)
      justify-items center 
      
      &::before
        content     attr(on-shift)
        align-items end
        
        
*
  box-sizing border-box
  padding 0
  margin 0
  
body
  font-family: 'Lato', sans-serif;
  min-height  100vh
  overflow    hidden
  display     grid
  place-items center
  background  radial-gradient(circle at top left, light 30%, mid)
  
  
// DESIGNED AND PROGRAMMED BY MANAN TANK 
View Compiled
keyHash = {
  8: ".back",
  9: ".tab",
  13: ".enter",
  16: ".shift",
  17: ".control",
  18: ".alt",
  20: ".cap",
  27: ".esc",
  32: ".space",
  37: ".left",
  38: ".up",
  39: ".right",
  40: ".down",
  186: ".semi",
  187: '.add',
  189: '.sub',
  222: ".comma",
  219: ".openbracket",
  221: ".closebracket",
  220: ".pipe",
  188: ".openangular",
  190: ".closeangular",
  191: ".slash",
  91: '.win'
};



const cap = document.querySelector('.cap');

function checkCaps() {
  if (event.getModifierState("CapsLock")) {
    cap.classList.add('on')
  } else {
    cap.classList.remove('on')
  }
}

const handleKeyDown = (e) => {
  checkCaps()
  let target = keyHash[e.keyCode];
  if (!target) target = `.key[data-key="${String.fromCharCode(e.keyCode)}"]`;
  const key = document.querySelector(target);
  key && key.classList.toggle("pressed");
};

function unPress(e) {
  if (e.propertyName === "transform") this.classList.remove("pressed");
}


window.addEventListener("keydown", handleKeyDown);
const keys = document.querySelectorAll(".key");
keys.forEach((k) => k.addEventListener("transitionend", unPress));

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.