cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              // checkboxes to control states and variables
- var n = 1;
  while n < 5
    input(type="radio", name="players", id="players"+n, checked=(n == 1), value=(n++))
- var n = 1;
  while n < 5
    input(type="radio", name="turn", id="turn"+n, checked=(n==1), value=(n++))
- var n = 1;
  while n < 5
    input(type="radio", name="colors", checked=(n == 1), id="colors"+(n++))
input(type="checkbox", id="game-time", class="game-time", name="game-time")
input(type="checkbox", name="show-info", id="show-info")
input(type="checkbox", name="play-fx", id="play-fx")
- var n = 1;
  while n < 6
    input(type="radio", id="show-instructions-"+(n++), class="game-time", name="show-instructions")

// inputs and labels that control the piece position for player 1
each players in [1,2,3,4]
  - var n = 0;
  while n < 107
    input(type="radio", name="cb-player"+players, id="cb-pl"+players+"-"+n, class="cb", checked=(n==0))
    label.dice(for="cb-pl"+players+"-"+(n++))
  
// game settings menu (# of players, colors) 
#options.scrim
  .box
    h1 Game Settings
    div
      h2 Number of players
      div.flex.option-players
        - var n = 1;
        while n < 5
          label(for="players"+n) #{n++}
      h2 Piece colors
      div.option-colors
        - var n = 1;
        while n < 5
          label.flex(for="colors"+(n++))
            span
            span
            span
            span
            span
      h2 Sound options
      label#activate-fx(for="play-fx") FX Sound
      div
        label.option-start(for="show-instructions-1") START GAME
        
// pop-up with information about the game and the author
#info.scrim
  .box
    h1 About
    div
      p Snakes and Ladders is an ancient Indian board game regarded today as a worldwide classic. A number of 'ladders' and 'snakes' are pictured on the board, each connecting two specific board squares. The object of the game is to navigate one's game piece, according to die rolls, from the start (bottom square) to the finish (top square), helped or hindered by ladders and snakes respectively.
        sup
          a(href="https://en.wikipedia.org/wiki/Snakes_and_Ladders", target="_blank") [1]
      p This version was developed by 
        a(href="https://github.com/alvaromontoro", target="_blank") Alvaro Montoro 
        | using HTML and CSS, to practice Pug and Sass, and without any JavaScript line of code.
      p The idea behind this project is that many classic board games are actually Finite-State Machines (FSM), so they can be recreated simulating the states of the automaton with radio buttons, labels, and some CSS styling.
      p
        label#close-button(for="show-info") Close

// animated instructions section
#instructions
  label#go-to-game(for="game-time") SKIP INSTRUCTIONS &rsaquo;
  #step
    div 
      label(for="show-instructions-2")
      label(for="show-instructions-3")
      label(for="show-instructions-4")
      label(for="show-instructions-5")
      label(for="game-time") PLAY &rsaquo;
      
// the game section: board, dice, snakes, ladders, and all that jazz...
#game
  #player-info.tab
    span Player
  //label#dice.tab
  div#action.tab
    label#turn-changer1(for="turn1")
    label#turn-changer2(for="turn2")
    label#turn-changer3(for="turn3")
    label#turn-changer4(for="turn4")
    div#fx-click-action.fx-sound
      embed(src="https://studiokah.com/tests/click2.mp3")
  label#more-info.tab(for="show-info")
  div#fx-click-more-info.fx-sound
    embed(src="https://studiokah.com/tests/click2.mp3")
  // Board based on the one from codewars: https://www.codewars.com/kata/snakes-and-ladders-1 
  #board
    each val in [100,99,98,97,96,95,94,93,92,91,81,82,83,84,85,86,87,88,89,90,80,79,78,77,76,75,74,73,72,71,61,62,63,64,65,66,67,68,69,70,60,59,58,57,56,55,54,53,52,51,41,42,43,44,45,46,47,48,49,50,40,39,38,37,36,35,34,33,32,31,21,22,23,24,25,26,27,28,29,30,20,19,18,17,16,15,14,13,12,11,1,2,3,4,5,6,7,8,9,10]
      div(class="tile tile"+val, data-index=val)
    svg#snakeladders(viewBox="0 0 600 600", preserveAspectRatio="none")
      g.ladders-big
        path(d="M89,574 140,392 M102,578 153,396 M388,581 385,508 M402,580 399,507 M449,552 554,395 M460,560 565,403 M320,516 333,444 M334,518 347,446 M24,436 74,329 M36,442 87,334 M430,458 210,99 M441,450 222,93 M264,393 214,339 M273,384 224,330 M563,284 391,203 M568,271 396,190 M570,149 559,31 M584,148 573,30 M142,158 155,40 M156,160 169,42 M397,101 379,30 M411,97 392,26")
      g.ladders-small
        path(d="M91,568 104,573 M94,556 105,561 M97,544 108,549 M100,532 111,537 M103,520 114,525 M107,508 118,513 M111,496 122,501 M114,484 125,489 M117,472 128,477 M121,460 132,465 M124,448 135,453 M128,436 139,441 M131,424 142,429 M134,412 145,417 M138,400 149,405 M388,575 401,574 M388,563 401,562 M388,552 401,551 M388,541 401,540 M388,530 400,529 M388,518 400,517 M452,546 464,555 M459,536 470,544 M466,526 476,533 M473,516 482,522 M479,508 490,515 M485,498 496,506 M492,488 502,495 M498,479 509,486 M504,469 515,477 M512,459 522,467 M517,449 528,457 M523,440 534,448 M530,430 541,438 M536,421 548,429 M542,412 554,419 M549,402 560,409 M322,510 335,512 M324,498 337,500 M326,486 339,488 M328,475 341,477 M330,463 343,465 M332,452 345,454 M258,388 268,378 M250,379 260,369 M243,370 252,361 M235,362 245,352 M227,353 236,344 M219,345 229,335 M27,430 40,436 M32,419 45,425 M37,408 49,414 M42,398 54,404 M47,388 59,394 M51,377 64,383 M56,366 69,372 M61,356 75,362 M66,345 79,351 M71,335 84,341 M427,453 438,444 M420,443 432,434 M414,433 426,424 M408,423 420,414 M402,413 413,404 M395,402 407,393 M388,391 400,382 M381,379 393,370 M374,368 386,359 M367,356 378,347 M359,344 371,336 M352,332 364,324 M345,320 357,312 M338,308 350,300 M330,296 342,288 M323,284 335,276 M316,272 328,264 M308,260 320,252 M301,248 313,240 M294,236 305,228 M287,224 298,216 M280,212 291,205 M273,200 284,193 M267,188 277,181 M259,175 269,168 M251,163 261,156 M244,151 254,144 M236,139 246,132 M229,127 239,120 M222,115 232,108 M215,103 225,96 M143,152 157,154 M144,140 158,142 M145,128 159,130 M146,116 160,118 M147,104 161,106 M149,92 163,94 M150,80 164,82 M151,68 165,70 M153,56 167,58 M154,44 168,46 M396,95 409,91 M393,84 406,80 M390,73 403,69 M387,62 400,58 M384,51 397,47 M381,40 394,36 M570,143 583,142 M568,130 582,129 M566,117 580,116 M565,104 577,103 M564,91 576,90 M563,78 575,77 M562,65 574,64 M561,52 573,51 M560,38 572,37 M556,281 562,268 M546,276 552,263 M536,271 542,258 M526,266 532,254 M516,261 522,249 M506,255 512,244 M496,250 502,239 M486,245 492,235 M476,240 482,230 M466,236 472,225 M456,231 462,220 M446,226 451,216 M436,221 441,211 M425,218 431,206 M415,213 421,201 M405,208 411,196 M395,204 401,192")
      path(d="M20,42 28,42 28,35 32,35 32,42 40,42 40,32 45,32 30,20 15,32 20,32 Z M20,578 30,578 30,583 40,570 30,557 30,562 20, 562Z", fill="rgba(0,0,0,0.25)")
      path.snake(d="M 90,226 C 98,257 69,322 128,332 187,342 181,381 120,382 59,383 53,425 54,433 56,450 87,467 87,481 87,495 76,506 76,512 84,505 95,496 96,480 97,464 60,447 64,425 68,403 99,392 134,391 169,390 219,344 131,322 94,313 100,279 101,256 102,233 101,229 100,225 105,223.62 106,214 96,210 86,205 65.75,211 83,223 85.88,225 88,226 90,226 Z", fill="#73880A")
      circle.eye(cx=97, cy=212, r=5)
      path.snake(d="M 22,282 C 35,271 58,266 81,273 104,280 144,278 145,253 146,228 175,208 193,213 204,198 220,210 220,216 220,222 201,229 193,221 182,222 157,229 156,252 155,275 139,297 86,281 33,268 22,283 22,283 Z", fill="#D15600")
      circle.eye(cx=203, cy=210, r=5)
      path.snake(d="M 453,271 C 433,285 396,289 400,261 405,233 394,223 369,223 343,224 319,167 376,161 379,168 401,168 402,156 403,143 376,143 375,152 300,162 333,233 366,233 402,233 388,258 389,266 390,281 414,309 453,272 Z", fill="#6BBA70")
      circle.eye(cx=387, cy=148, r=5)
      path.snake(d="M 457,199 C 429,161 465,134 489,158 512,182 542,159 540,129 538,99 523,98 522,98 528,91 505,75 495,97 503,113 518,105 519,105 519,105 530,110 531,130 532,150 513,169 492,149 471,129 445,143 443,159 442,174 449,194 457,200 Z", fill="#C79810")
      circle.eye(cx=512, cy=90, r=5)
      path.snake(d="M 441,95 C 457,93 479,72 445,52 415,33 434,16 451,16 468,16 489,39 492,40 495,28 521,33 521,43 521,54 496,54 490,48 490,48 466,23 450,25 434,27 439,43 459,51 479,61 473,101 441,96 Z", fill="#356AA0")
      circle.eye(cx=504, cy=35, r=5)
      path.snake(d="M 278,457 C 291,438 262,428 247,444 230,464 193,450 231,420 256,400 300,425 335,395 349,381 334,338 334,338 334,338 348,325 325,324 301,322 306,341 326,340 334,358 346,401 285,401 231,401 205,416 205,446 206,472 244,462 250,452 258,441 281,435 278,458 Z", fill="#3F4C6B")
      circle.eye(cx=327, cy=325, r=5)
      path.snake(d="M 343,584 C 352,567 344,553 320,553 296,553 286,562 279,568 272,573 238,592 238,558 237,524 253,517 253,517 253,517 270,517 270,509 270,498 238,501 247,514 227,537 230,556 230,561 229,567 239,605 281,575 324,544 349,562 343,585 Z", fill="#008C00")
      circle.eye(cx=257, cy=503, r=5)
      path.snake(d="M 572,506 C 555,514 511,516 518,456 526,396 518,380 490,388 457,397 436,346 492,335 507,341 518,334 518,326 518,317 494,313 489,326 422,337 448,410 489,398 525,384 510,449 510,456 510,462 502,547 572,508 Z", fill="#D01F3C")
      circle.eye(cx=503, cy=320, r=5)
      path.snake(d="M 19,138 C 45,154 84,152 63,119 43,87 59,85 79,84 99,83 103,77 94,40 85,46 73,39 72,32 72,25 109,13 102,35 117,69 108,100 79,94 52,88 70,114 73,118 82,127 83,190 18,138 Z", fill="#2096cE")
      circle.eye(cx=89, cy=27, r=5)
      path.snake(d="M 322,152 C 302,168 282,153 285,137 287,120 287,121 275,110 263,99 295,79 291,62 287,45 297,30 318,38 324,51 346,48 346,39 347,30 327,20 320,31 295,18 274,33 280,57 286,82 252,86 262,111 265,118 280,122 275,137 271,148 291,185 322,154 Z", fill="#CC4444")
      circle.eye(cx=330, cy=30, r=5)
    each player in [1,2,3,4]
      svg.piece(id="piece-player-"+player, viewBox="0 0 100 100")
        g
          path(d="M 50,1 C 50,1 80,85 80,85 70,96 60,99 50,99 40,99 30,96 20,85 20,85 50,1 50,1 Z")
          circle(cx=50, cy=21, r=20)
          rect(x=44, y=25, width=12, height=22, stroke="none")

#snake-popup.scrim 
  div.box
    h1 Snake!!!
    div Oh no! The snake bit you! You'll have to move your piece to the snake's tail.
      div
        each players in [1,2,3,4]
          each val, index in {16:6, 46:25, 49:11, 62:19, 64:60, 74:53, 89:68, 92:88, 95:75, 99:80}
            label(id="snake-pl"+players+"-"+index, for="cb-pl"+players+"-"+val) Move Down
    svg(viewBox="0 0 100 100")
      path(d="M1,32 4,32 M6,34 4,32 M4,32 10,20", stroke="black", stroke-with="1")
      path(d="M 30,70 C 49,56 60,84 33,92 -17,103 0,50 24,45 32,44 37,41 29,27 26,33 5,35 3,24 4,13 26,3 37,16 49,30 49,52 28,55 8,59 0,94 33,82 56,72 35,66 30,71 Z", fill="#73B80A", stroke-width="0")
      circle(cx=18, cy=15, r=5, fill="black", stroke="white", stroke-width=6)
      
    
#ladder-popup.scrim
  div.box
    h1 Ladder!
    div Yay! You found a ladder! You can climb up now.
      div
        each players in [1,2,3,4]
          each val, index in {2:38, 7:14, 8:31, 15:26, 21:42, 28:84, 36:44, 51:67, 71:91, 78:98, 87:94}
            label(id="ladder-pl"+players+"-"+index, for="cb-pl"+players+"-"+val) Move Up
    svg(viewBox="0 0 100 100")
      path(d="M5,85 20,10", stroke="#8B4513", stroke-width="10", "stroke-linecap"="round")
      path(d="M10,67 30,71 M15,45 35,49 M20,23 40,27", stroke="#aB6533", stroke-width="5", "stroke-linecap"="round")
      path(d="M30,90 45,15", stroke="#8B4513", stroke-width="10", "stroke-linecap"="round")
      
#home-popup.scrim
  div.box
    h1 Home
    div You made it home, but you didn't do it in an exact jump so you will bounce back the remaining tiles.
      div
        each players in [1,2,3,4]
          each val, index in {101:99, 102:98, 103:97, 104:96, 105:95, 106:94}
            label(id="home-pl"+players+"-"+index, for="cb-pl"+players+"-"+val) Bounce back
    svg(viewBox="0 0 100 100")
      path(d="M12,85 12,40 5,40 30,5 55,40 48,40 48,85 35,85 35,60 25,60 25,85 Z", fill="#8Ba5f3")
      path(d="M30,65 C 30,60 25,55 20,55 15,55 10,60 10,65 10,70 15,75 20,75 20,75 20,75 50,75 M40,65 50,75 40,85", stroke="#eeee60", stroke-width=6, fill="none")
      
#congratulations.scrim
  div.box
    h1 Congratulations!
    div You made it home safely! You won!
    div Reload the page to play again.
    svg(viewBox="0 0 100 100")
      path(d="M5,10 C 5,10 65,10 65,10 65,10 65,40 65,40 65,50 55,70 35,70 15,70 5,50 5,40 Z", fill="#fede60")
      path(d="M35,40 35,85 M20,85 50,85", stroke="#fede60", stroke-width=12, fill="none", stroke-linecap="round")
    
div#fx-dice.fx-sound
  embed(src="https://studiokah.com/tests/dice.mp3")
div#fx-click.fx-sound
  // Click sound by Sebastian. Source: http://soundbible.com/1705-Click2.html
  embed(src="https://studiokah.com/tests/click2.mp3")
            
          
!
            
              // variables
$border-radius: 3px;
$color-blue: #48c;
$color-red: #f55;
$color-green: #4a5;
$color-yellow: #dd5;
$animation-time: 0.6s;
$ladders: (2, 7, 8, 15, 21, 28, 36, 51, 71, 78, 87);
$snakes: (16, 46, 49, 62, 64, 74, 89, 92, 95, 99);

/***** dice animation */
@keyframes changeOrder {
  from { z-index: 6;}
  to { z-index: 1; }
}

@-webkit-keyframes changeOrder {
  from { z-index: 6; }
  to { z-index: 1; }
}

// coment for testing 
input { display: none; }

.fx-sound { 
  display: none; 
  position: absolute;
  top: -1000px;
  left: -1000px;
  heigth: 0px;
  width: 0px;
  overflow: hidden;
}
#play-fx:checked ~ {
  label.dice:active ~ #fx-dice { display: block; }
  #game label:active ~ .fx-sound { display: block; }
}


// presentation
@import url('https://fonts.googleapis.com/css?family=Dosis|Roboto');

body {
  font-size: 16px;
  font-family: Dosis, Roboto, Arial, Verdana, sans-serif;
  padding: 0;
  margin: 0;
  border: 0;
  background: rgba(128,200,255,0.8) /*rgba(128,200,255,0.8)*/;
}

.scrim {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.75);
  z-index: 999;
  .box {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    background: white;
    border-radius: $border-radius;
    box-shadow: 0 1.5em 0.5em -1em rgba(0, 0, 0, 0.25);
    width: 70%;
    max-width: 375px;
    > div {
      padding:1rem;
    }
    h1 {
      margin-top: 0;
      margin-bottom: 0;
      font-size: 1.75rem;
      text-align: center;
      height: 2.5rem;
      line-height: 2.35rem;
      background: $color-blue;
      color: white;
      border-radius: $border-radius $border-radius 0px 0px;
    }
    h2 {
      margin-top: 1rem;
      margin-bottom: 0.15rem;
      font-size: 1.3rem;
      &:first-child {
        margin-top: 0;
      }
    }
    p:first-child {
      margin-top: 0;
    }
    p:last-child {
      margin-bottom: 0;
    }
  }
}

.flex {
  display: flex;
  > label, > div {
    flex: 1;
    margin-left: 0.3rem;
    &:first-child {
      margin-left: 0;
    }
  }
}

/** start screen: configuration **/
#options {
  background: rgba(0,0,0,0);
  .option-players label, label.option-start {
    display: block;
    margin-top: 0.5rem;
    color: white;
    background: rgba(0,150,48,0.6);
    text-align: center;
    padding: 6px;
    transition: background 0.5s, color 0.5s;
    box-sizing: border-box;
    border: 2px solid transparent;
    border-radius: $border-radius;
    cursor: pointer;
    &:hover {
      background: rgba(220,220,0,0.7);
      color: black;
    }
    &:active {
      border: 2px solid rgba(0,0,0,0.1);
    }
    &.option-start {
      background: $color-blue;
      color: white;
      margin-top: 2rem;
      &:hover {
        background: darken($color-blue, 5%);
      }
    }
  }
  .option-colors label {
    opacity: 0.6;
    margin-bottom: 0.3rem;
    cursor: pointer;
    //transition: opacity 0.5s; // commented as it creates weird jump
    &:hover {
      opacity: 0.8;
    }
    span {
      flex: 1;
      margin-left: 0.3rem;
      border-radius: $border-radius;
      display: inline-block;
      padding: 3px;
      font-size: 0.7rem;
      border: 2px solid transparent;
      &:first-child {
        flex: 0;
        margin-left: 0;
        background: none;
        font-size: 1rem;
        &::before {
          content: "\2610";
        }
      }
    }
    &:nth-child(1) span {
      &:nth-child(2) { background: $color-green; }
      &:nth-child(3) { background: $color-blue; }
      &:nth-child(4) { background: $color-red; }
      &:nth-child(5) { background: $color-yellow; }
    }
    &:nth-child(2) span {
      &:nth-child(2) { background: $color-blue; }
      &:nth-child(3) { background: $color-red; }
      &:nth-child(4) { background: $color-yellow; }
      &:nth-child(5) { background: $color-green; }
    }
    &:nth-child(3) span {
      &:nth-child(2) { background: $color-red; }
      &:nth-child(3) { background: $color-yellow; }
      &:nth-child(4) { background: $color-green; }
      &:nth-child(5) { background: $color-blue; }
    }
    &:nth-child(4) span {
      &:nth-child(2) { background: $color-yellow; }
      &:nth-child(3) { background: $color-green; }
      &:nth-child(4) { background: $color-blue; }
      &:nth-child(5) { background: $color-red; }
    }
  }
  #activate-fx {
    cursor: pointer;
    &::before {
      content: "\2610\00a0";
    }
  }
}

// hide the game settings when Start is pressed
#game-time:checked ~ #options,
[name=show-instructions]:checked ~ #options { display: none; }
#play-fx:checked ~ #options #activate-fx::before { content: "\2612\00a0" }

// control active # of players and colors
@for $i from 1 to 5 {
  #players#{$i}:checked {
    ~ #options {
      label[for=players#{$i}] {
        background: rgba(0,150,48,1);
        border: 2px solid rgba(0,0,0,0.1);
        color: white;
      }
      @for $j from $i+1 to 5 {
        label[for^=colors] span:nth-child(#{$j+1}){
          display: none;
        }
      }
    }
  }
  #colors#{$i}:checked {
    ~ #options {
      label[for=colors#{$i}] {
        opacity: 1;
        border: 0;
        span {
          border: 2px solid rgba(0,0,0,0.1);
          &:first-child {
            border: 2px solid transparent;
            &::before {
              content:"\2612";
            }
          }
        }
      }
    }
  }
}

// assign colors to the game pieces according to the color scheme selected
// TODO: this probably can be reduced with SASS as well as the code above
#colors1:checked ~ #game #piece-player-1 g { fill: $color-green; }
#colors1:checked ~ #game #piece-player-2 g { fill: $color-blue; }
#colors1:checked ~ #game #piece-player-3 g { fill: $color-red; }
#colors1:checked ~ #game #piece-player-4 g { fill: $color-yellow; }
#colors2:checked ~ #game #piece-player-1 g { fill: $color-blue; }
#colors2:checked ~ #game #piece-player-2 g { fill: $color-red; }
#colors2:checked ~ #game #piece-player-3 g { fill: $color-yellow; }
#colors2:checked ~ #game #piece-player-4 g { fill: $color-green; }
#colors3:checked ~ #game #piece-player-1 g { fill: $color-red; }
#colors3:checked ~ #game #piece-player-2 g { fill: $color-yellow; }
#colors3:checked ~ #game #piece-player-3 g { fill: $color-green; }
#colors3:checked ~ #game #piece-player-4 g { fill: $color-blue; }
#colors4:checked ~ #game #piece-player-1 g { fill: $color-yellow; }
#colors4:checked ~ #game #piece-player-2 g { fill: $color-green; }
#colors4:checked ~ #game #piece-player-3 g { fill: $color-blue; }
#colors4:checked ~ #game #piece-player-4 g { fill: $color-red; }

/** info pop-up **/
#info { 
  display: none;
  .box {
    width: 75%;
    max-width: none;
    p:last-child {
      text-align: right;
    }
    #close-button {
      display: inline-block;
      background: $color-green;
      border-radius: $border-radius;
      color: white;
      padding: 6px 1rem;
      cursor: pointer;
      transition: background 0.5s;
      &:hover {
        background: darken($color-green, 5%);
      }
    }
  }
}
#show-info:checked {
  ~ #info { display: block; }
}


/** Instructions **/
#instructions {
  position: fixed;
  z-index: 9999;
  background-color: rgba(0,0,0,0.01);
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: none;
  #go-to-game {
    position: absolute;
    bottom: 1rem;
    right: 1rem;
    font-size: 1rem;
    z-index: 3;
    color: white;
    cursor: pointer;
  }
  #step {
    display: none;
    position: absolute;
    box-shadow: 0 0 50px calc(200vmax) rgba(0,0,0,0.85), inset 0 0 4px 0 rgba(0,0,0,1);
    transform: translate(-1rem, -1rem);
    border-radius: 100%;
    z-index: 1;
    top: 0;
    left: 1rem;
    width: calc(100px + 2rem);
    height: calc(6rem);
    transition: all 0.75s;
    div {
      position: absolute;
      bottom: -0.5rem;
      line-height: 1.1rem;
      font-size: 1rem;
      color: rgba(255,255,255,0.8);
      left: 1rem;
      width: 80vmin;
      transform: translate(0, 100%);
      -webkit-transform: translate(0, 100%);
      label {
        display: none;
        font-weight: bold;
        cursor: pointer;
        text-decoration: underline;
        &:hover {
          text-decoration: none;
        }
        &:not([for=game-time])::before {
          content: "Next \203A"
        }
      }
    }
  }
}

[name=show-instructions] {
  &:checked ~ {
    #instructions, #game, #action, #instructions #step {
      display: block;
    }
  }
}

@for $i from 1 to 5 {
  #show-instructions-#{$i}:checked ~ #instructions label[for=show-instructions-#{$i+1}] {
    display: inline-block;
  }
}
#show-instructions-5:checked ~ #instructions label[for=game-time] {
  display: inline-block;
}

#show-instructions-1:checked ~ #instructions #step {
  top: 0;
  left: 1rem;
  width: calc(100px + 2rem);
  height: calc(6rem);
  div::before {
    content: "This area indicates whose turn it is at any given moment.";
  }
}
#show-instructions-2:checked ~ #instructions #step {
  top:6rem;
  left: 1rem;
  width: 5rem;
  height: 5rem;
  div::before {
    content: "The active player clicks here to roll the dice.";
  }
}
#show-instructions-3:checked ~ #instructions #step {
  top: 50%;
  left: 50%;
  width: 30vw;
  height: 30vw;
  max-width: 500px;
  max-height: 500px;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  div {
    transform: translate(-20vmin, 100%);
    -webkit-transform: translate(-20vmin, 100%);
    left: 0;
    &::before {
      content: "The player's piece will advance on the board once the dice is rolled. If the piece falls on a tile with a snake's head, it will fall down to the snake's tail. If it falls on a ladder's bottom, it will go up to the top.";
    }
  }
}
#show-instructions-4:checked ~ #instructions #step {
  top: 0;
  left: calc(100px + 2rem);
  width: calc(100px + 2rem);
  height: calc(6rem);
  div::before {
    content: "After that, click on the button to go to the next player's turn.";
  }
}
#show-instructions-5:checked ~ #instructions #step {
  top: 0;
  left: calc(100vw - 100px - 1rem);
  width: calc(100px + 2rem);
  height: calc(6rem);
  div {
    left: auto;
    right: 0rem;
    &::before {
      content: "If you want more information during the game, click on this button."
    }
  }
}

#game-time:checked ~ #instructions {
  display: none;
}

/** game screen: board, dice, messages **/
.dice {
  position: absolute;
  display: none;
  visibility: visible;
  top: 6rem;
  left: 1rem;
  width: 3rem;
  height: 3rem;
  background: white;
  border-radius: $border-radius;
  box-shadow: 0 1.5em 0.5em -1em rgba(0, 0, 0, 0.042);
  z-index:1;
  &::before {
    content: "Roll the Dice";
    display: block; 
    height: 100%; 
    width: 100%;
    font-size: 0.8rem;
    box-sizing: border-box;
    cursor: pointer;
    padding-top: 0.5rem;
  }
}


@for $i from 1 to 5 {
  #turn#{$i}:checked ~ .game-time:checked ~ [name=cb-player#{$i}]:checked + label + input + label,
  #turn#{$i}:checked ~ .game-time:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label, 
  #turn#{$i}:checked ~ .game-time:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label,
  #turn#{$i}:checked ~ .game-time:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label,
  #turn#{$i}:checked ~ .game-time:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label + input + label,
  #turn#{$i}:checked ~ .game-time:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label + input + label + input + label {
    display: block;
    left: 1rem;
    text-align: center;
    animation: changeOrder $animation-time infinite;
    -webkit-animation: changeOrder $animation-time infinite;
  }
}

@for $i from 1 to 5 {
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label { animation-delay: 0s !important; }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label { animation-delay: -$animation-time/6 !important; }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label { animation-delay: -2*$animation-time/6 !important; }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label { animation-delay: -3*$animation-time/6 !important; }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label + input + label { animation-delay: -4*$animation-time/6 !important; }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label + input + label + input + label { animation-delay: -5*$animation-time/6 !important; }
}

@for $i from 1 to 5 {
  /*
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label::before { background-image: 
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='50' cy='50' r='8' /></svg>");
       }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label::before { background-image: 
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='23' cy='77' r='8' /><circle cx='77' cy='23' r='8' /></svg>"); }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label::before { background-image: 
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='23' cy='77' r='8' /><circle cx='77' cy='23' r='8' /><circle cx='50' cy='50' r='8' /></svg>"); }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label::before { background-image: 
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='23' cy='23' r='8' /><circle cx='77' cy='23' r='8' /><circle cx='77' cy='77' r='8' /><circle cx='23' cy='77' r='8' /></svg>"); }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label + input + label::before { background-image: 
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='23' cy='23' r='8' /><circle cx='77' cy='23' r='8' /><circle cx='77' cy='77' r='8' /><circle cx='23' cy='77' r='8' /><circle cx='50' cy='50' r='8' /></svg>"); }
  #turn#{$i}:checked ~ [name=cb-player#{$i}]:checked + label + input + label + input + label + input + label + input + label + input + label + input + label::before { background-image: 
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><circle cx='23' cy='23' r='8' /><circle cx='77' cy='23' r='8' /><circle cx='77' cy='77' r='8' /><circle cx='23' cy='77' r='8' /><circle cx='23' cy='50' r='8' /><circle cx='77' cy='50' r='8' /></svg>"); }
  */
}


// label:active adapted from solution by Temani Afif. Ref: https://stackoverflow.com/a/51451218/3695983 
label.dice:active {
  position:static !important; 
  margin-left: 50px !important;
  background: none !important;
  font-size: 0;
  &::before {
    content:"";
    position:absolute;
    top:0;
    right:-50px;
    left:0;
    bottom:0;
    z-index:200;
  }
}
  
#game {
  display: none;
  .tab {
    position: absolute;
    top: 0;
    background: white;
    border-radius: 0 0 3px 3px;
    box-shadow: 0 1.5em 0.5em -1em rgba(0, 0, 0, 0.25);
    z-index: 9;
    float:left;
    margin-left: 1rem;
    &::before {
      text-align: center;
      display: block;
      padding: 6px 16px;
      color: white;
      background: $color-blue;
      height: 0.7rem;
      line-height: 0.7rem;
      font-size: 0.75rem;
      font-weight: bold;
      white-space: nowrap;
      text-transform: uppercase;
      font-size: 0.95rem; 
    }
    &::after, &#player-info span {
      display: block;
      text-align: center;
      padding: 6px 16px;
      height: 2rem;
      line-height: 1.9rem;
      white-space: nowrap;
    }
    &#player-info {
      min-width: 100px;
      &::before { content: "Turn"; }
      span { 
        font-weight: bolder;
        &::before {
          content: "\25CF\00A0";
        }
        &::after {
          content: " 1"; 
          font-weight: bolder; 
        }
      }
    }
    &#dice {
      cursor: pointer;
      &::before { content: "Dice"; }
      &::after { 
        content: "Roll"; 
      }
    }
    &#more-info {
      cursor: pointer;
      left: auto;
      right: 1rem;
      width: 100px;
      z-index: 1;
      &::before { content: "About"; }
      &::after { content: "More info" }
    }
    &#action {
      cursor: pointer;
      left: calc(100px + 1rem);
      width: 100px;
      &::before { content: "Action"; }
      &::after { content: "Next player" }
      label {
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        cursor: pointer;
      }
    }
  }
  #board {
    width: 70%;
    max-width: 500px;
    border: 3px solid $color-blue;
    border-radius: $border-radius * 2;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    background: white;
    margin-top: 2.5rem;
    box-shadow: 0 1.5em 0.5em -1em rgba(0, 0, 0, 0.25);
    .tile {
      float: left;
      width: 10%;
      position: relative;
      height: 0;
      padding-top: 10%;
      box-sizing: border-box;
      border-left: 1px solid rgba(0,0,0,0.1);
      border-right: 1px solid rgba(0,0,0,0.1);
      border-top: 1px solid rgba(0,0,0,1);
      border-bottom: 1px solid rgba(0,0,0,1);
      background: lighten(#9ad0ac,15%);
      &::before {
        content: attr(data-index);
        position: absolute;
        top: 0rem;
        left: 0.15rem;
        font-size: 0.66rem;
      }
      &.tile6, &.tile12, &.tile18, &.tile22, &.tile23, &.tile28, &.tile30, &.tile34, &.tile36, &.tile39, &.tile55, &.tile79 {
        &::before {
          left: auto;
          right: 0.15rem;
        }
      }
      &.tile52::before {
        top:auto;
        bottom:0rem;
      }
      &.tile76::before {
        left: 0.6rem;
      }
    }
    @for $i from 1 to 11 {
      .tile#{$i} { border-bottom: 1px solid transparent; }
      .tile#{$i+90} { border-top: 1px solid transparent; }
      .tile#{$i*10} { border-top: 1px solid rgba(0,0,0,0.1); }
      .tile#{$i*10+1} { border-bottom: 1px solid rgba(0,0,0,0.1); }
    }
    .tile1, .tile15, .tile24, .tile38, .tile49, .tile55, .tile65, .tile76, .tile86, .tile94 {
      background: lighten(#f198b4, 15%);
    }

    .tile2, .tile16, .tile23, .tile35, .tile42, .tile56, .tile64, .tile79, .tile87, .tile93 {
      background: lighten(#C3D9FF, 8%);
    }

    .tile3, .tile18, .tile26, .tile33, .tile41, .tile58, .tile68, .tile78, .tile81, .tile96 {
      background: lighten(#f89448, 30%);
    }

    .tile4, .tile11, .tile29, .tile40, .tile47, .tile51, .tile61, .tile77, .tile88, .tile99 {
      background: lighten(#c297c5, 23%);
    }

    .tile5, .tile19, .tile27, .tile32, .tile44, .tile59, .tile69, .tile80, .tile89, .tile97 {
      background: lighten(#68caef, 18%);
    }

    .tile6, .tile20, .tile28, .tile31, .tile45, .tile60, .tile70, .tile75, .tile85, .tile98 {
      background: lighten(#fef471, 21%);
    }

    .tile7, .tile13, .tile21, .tile36, .tile50, .tile53, .tile63, .tile74, .tile84, .tile91 {
      background: lighten(#b9e6fd, 5%);
    }

    .tile8, .tile12, .tile30, .tile39, .tile46, .tile52, .tile62, .tile73, .tile90, .tile100 {
      background: lighten(#e5b75f,19%);
    }

    .tile9, .tile14, .tile22, .tile37, .tile48, .tile54, .tile66, .tile72, .tile83, .tile96 {
      background: lighten(#f37859,20%);
    }
  }
}

#action label { display: none; }
#players1:checked ~ #turn1:checked ~ #game-time:checked ~ #game #action { display:none; }
#players1:checked ~ #turn1:checked ~ #game #turn-changer1 { display: block; }
#players2:checked ~ #turn1:checked ~ #game #turn-changer2 { display: block; }
#players3:checked ~ #turn1:checked ~ #game #turn-changer2 { display: block; }
#players4:checked ~ #turn1:checked ~ #game #turn-changer2 { display: block; }
#players2:checked ~ #turn2:checked ~ #game #turn-changer1 { display: block; }
#players3:checked ~ #turn2:checked ~ #game #turn-changer3 { display: block; }
#players4:checked ~ #turn2:checked ~ #game #turn-changer3 { display: block; }
#players3:checked ~ #turn3:checked ~ #game #turn-changer1 { display: block; }
#players4:checked ~ #turn3:checked ~ #game #turn-changer4 { display: block; }
#players4:checked ~ #turn4:checked ~ #game #turn-changer1 { display: block; }

// assign colors to the game pieces according to the color scheme selected
// TODO: this probably can be reduced with SASS as well as the code above for piece colors
#turn1:checked ~ #colors1:checked ~ #game #player-info span::before { color: $color-green; }
#turn2:checked ~ #colors1:checked ~ #game #player-info span::before { color: $color-blue; }
#turn3:checked ~ #colors1:checked ~ #game #player-info span::before { color: $color-red; }
#turn4:checked ~ #colors1:checked ~ #game #player-info span::before { color: $color-yellow; }
#turn1:checked ~ #colors2:checked ~ #game #player-info span::before { color: $color-blue; }
#turn2:checked ~ #colors2:checked ~ #game #player-info span::before { color: $color-red; }
#turn3:checked ~ #colors2:checked ~ #game #player-info span::before { color: $color-yellow; }
#turn4:checked ~ #colors2:checked ~ #game #player-info span::before { color: $color-green; }
#turn1:checked ~ #colors3:checked ~ #game #player-info span::before { color: $color-red; }
#turn2:checked ~ #colors3:checked ~ #game #player-info span::before { color: $color-yellow; }
#turn3:checked ~ #colors3:checked ~ #game #player-info span::before { color: $color-green; }
#turn4:checked ~ #colors3:checked ~ #game #player-info span::before { color: $color-blue; }
#turn1:checked ~ #colors4:checked ~ #game #player-info span::before { color: $color-yellow; }
#turn2:checked ~ #colors4:checked ~ #game #player-info span::before { color: $color-green; }
#turn3:checked ~ #colors4:checked ~ #game #player-info span::before { color: $color-blue; }
#turn4:checked ~ #colors4:checked ~ #game #player-info span::before { color: $color-red; }

@for $i from 1 to 5 {
  #turn#{$i}:checked ~ #game .tab#player-info span::after{
    content: " #{$i}";
  }
}

// show the game board when Start is pressed
#game-time:checked ~ #game {
  display: block;
}

svg {
  &#snakeladders{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    g {
      &.ladders-big {
        stroke: #8B4513;
        stroke-width: 4;
        stroke-linecap: round;
      }
      &.ladders-small {
        stroke: #8B4513;
        stroke-width: 2.5;
        stroke-linecap: round;
      }
    }
  }
  .snake {
    stroke: none;
  }
  .eye {
    fill: black;
    stroke: white;
    stroke-width: 6;
  }
  &.piece {
    position: absolute;
    width: 8%;
    bottom: 0;
    left: 0;
    transform: translate(-2%, -2%);
    -webkit-transform: translate(-2%, -2%);
    transition: bottom 0.5s, left 0.5s;
    g {
      fill: $color-red;
      stroke-width: 4;
      stroke: rgba(0,0,0,0.3);
    }
    &#piece-player-1 {
      transform: translate(-5%, -3%);
      -webkit-transform: translate(-5%, -3%);
      z-index:44;
      g {
        fill: $color-red;
      }
    }
    &#piece-player-2 {
      transform: translate(40%, -40%);
      -webkit-transform: translate(40%, -40%);
      z-index: 41;
      g {
        fill: $color-blue;
      }
    }
    &#piece-player-3 {
      transform: translate(42%, -7%);
      -webkit-transform: translate(42%, -7%);
      z-index: 43;
      g {
        fill: $color-green;
      }
    }
    &#piece-player-4 {
      transform: translate(-3%, -41%);
      -webkit-transform: translate(-3%, -41%);
      z-index: 42;
      g {
        fill: $color-yellow;
      }
    }
  }
}

// generate the different positions on each tile
$positions: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0;
@for $i from 1 through 4 {
  #cb-pl#{$i+"-0"}:checked ~ #game #piece-player-#{$i} {
    left: -10%;
    bottom: 0;
  }
  @for $j from 1 to 101 {
    #cb-pl#{$i}-#{$j}:checked {
      ~ #game #piece-player-#{$i} { 
        left: nth($positions, (($j - 1) % 20) + 1) * 1%; 
        bottom: nth($positions, floor(($j - 1) / 10) + 1) * 1%; 
      }  
    }
  }
  @for $j from 101 to 107 {
    #cb-pl#{$i}-#{$j}:checked {
      ~ #game #piece-player-#{$i} { 
        left: 0;
        bottom: 90%;
      }
    }
  }
}

// hide the players that are not active
@for $i from 1 to 5 {
  @for $j from $i+1 to 5 {
    #players#{$i}:checked ~ #game #piece-player-#{$j} { 
      display: none !important; 
    }
  }
}


// all these popups have a similar code below that could be reduced with a mixin (TODO)
#snake-popup, #ladder-popup, #home-popup, #congratulations {
  opacity: 0;
  z-index: -1;
  transition: opacity 0s;
  label {
    display: none;
  }
  svg {
    height:100%;
    position:absolute;
    right:0;
    top:0;
    transform:translate(80%, 0);
  }
}

// when we fall in a ladder, show the ladder popup
@each $l in $ladders {
  .cb[id$='-#{$l}'] {
    &:checked {
      ~ .dice { 
        display: none !important; 
      }
      ~ #ladder-popup {
        opacity: 1;
        z-index: 99999;
        transition: opacity 0.15s;
        transition-delay: 0.5s;
        -webkit-transition-delay: 0.5s;
        label {
          background: $color-green;
          border-radius: $border-radius;
          color: white;
          padding: 6px 1rem;
          cursor: pointer;
          transition: background 0.5s;
          margin-top: 1rem;
          &:hover {
            background: darken($color-green, 5%);
          }
        }
      }
    }
  }
}

// when we fall in a ladder, show the ladder popup
@each $s in $snakes {
  .cb[id$='-#{$s}'] {
    &:checked {
      ~ .dice { 
        display: none !important; 
      }
      ~ #snake-popup {
        opacity: 1;
        z-index: 99999;
        transition: opacity 0.15s;
        transition-delay: 0.5s;
        -webkit-transition-delay: 0.5s;
        label {
          background: $color-green;
          border-radius: $border-radius;
          color: white;
          padding: 6px 1rem;
          cursor: pointer;
          transition: background 0.5s;
          margin-top: 1rem;
          &:hover {
            background: darken($color-green, 5%);
          }
        }
      }
    }
  }
}

// when we fall in a ladder, show the ladder popup
@for $s from 101 to 107 {
  .cb[id$='-#{$s}'] {
    &:checked {
      ~ .dice { 
        display: none !important; 
      }
      ~ #home-popup {
        opacity: 1;
        z-index: 99999;
        transition: opacity 0.15s;
        transition-delay: 0.5s;
        -webkit-transition-delay: 0.5s;
        label {
          background: $color-green;
          border-radius: $border-radius;
          color: white;
          padding: 6px 1rem;
          cursor: pointer;
          transition: background 0.5s;
          margin-top: 1rem;
          &:hover {
            background: darken($color-green, 5%);
          }
        }
      }
    }
  }
}

// show the right button in the ladder/snake popup
@for $i from 1 to 5 {
  @each $l in $ladders {
    #cb-pl#{$i}-#{$l}:checked ~ #ladder-popup #ladder-pl#{$i}-#{$l} { display: inline-block; }
  }
  @each $s in $snakes {
    #cb-pl#{$i}-#{$s}:checked ~ #snake-popup #snake-pl#{$i}-#{$s} { display: inline-block; }
  }
  @for $j from 101 to 107 {
    #cb-pl#{$i}-#{$j}:checked ~ #home-popup #home-pl#{$i}-#{$j} { display: inline-block; }
  }
}

.cb[id$='-100']:checked {
  ~ #congratulations {
    opacity: 1;
    z-index: 99999;
    transition: opacity 0.15s;
    transition-delay: 0.5s;
    -webkit-transition-delay: 0.5s;
  }
}

@media (max-width: 400px) {
  #game {
    #board .tile::before {
      font-size: 0.4rem;
    }
    .tab {
      &::before {
        font-size: 0.65rem;
      }
      &::after, &#player-info span {
        font-size: 0.9rem;
        height: 1.5rem;
        line-height: 1.4rem;
      }
    }
  }
}

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console